diff options
author | Bertrand Marc <beberking@gmail.com> | 2013-08-03 13:07:32 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2013-08-03 13:07:32 +0200 |
commit | 1ae32bc989973c2e8909c3b085d34b2454f92d1e (patch) | |
tree | dfde89b41437def7ce23af24db53a11a9b5f1075 /src/transport | |
parent | 740b30688bd745a527f96f9116c19acb3480971a (diff) |
Imported Upstream version 0.9.5a
Diffstat (limited to 'src/transport')
154 files changed, 12927 insertions, 6161 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index b040874..5f65dff 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -4,29 +4,42 @@ plugindir = $(libdir)/gnunet pkgcfgdir= $(pkgdatadir)/config.d/ +libexecdir= $(pkglibdir)/libexec/ + pkgcfg_DATA = \ transport.conf if HAVE_MHD GN_LIBMHD = -lmicrohttpd - HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la + HTTP_SERVER_PLUGIN_LA = libgnunet_plugin_transport_http_server.la + HTTPS_SERVER_PLUGIN_LA = libgnunet_plugin_transport_https_server.la + HTTP_SERVER_PLUGIN_TEST = test_plugin_http_server + HTTPS_SERVER_PLUGIN_TEST = test_plugin_https_server +endif + +if HAVE_LIBCURL + HTTP_CLIENT_PLUGIN_TEST = test_plugin_http_client + HTTPS_CLIENT_PLUGIN_TEST = test_plugin_https_client + HTTP_CLIENT_PLUGIN_LA = libgnunet_plugin_transport_http_client.la + HTTPS_CLIENT_PLUGIN_LA = libgnunet_plugin_transport_https_client.la +endif + +if HAVE_MHD +if HAVE_LIBCURL HTTP_API_TEST = test_transport_api_http - HTTP_NAT_API_TEST = test_transport_api_http_nat + HTTP_REVERSE_API_TEST = test_transport_api_http_reverse HTTP_API_TIMEOUT_TEST = test_transport_api_timeout_http HTTP_REL_TEST = test_transport_api_reliability_http - HTTP_NAT_REL_TEST = test_transport_api_reliability_http_nat HTTP_QUOTA_TEST = test_quota_compliance_http \ test_quota_compliance_http_asymmetric - HTTPS_PLUGIN_LA = libgnunet_plugin_transport_https.la HTTPS_API_TEST = test_transport_api_https - HTTPS_NAT_API_TEST = test_transport_api_https_nat HTTPS_API_TIMEOUT_TEST = test_transport_api_timeout_https HTTPS_REL_TEST = test_transport_api_reliability_https - HTTPS_NAT_REL_TEST = test_transport_api_reliability_https_nat HTTPS_QUOTA_TEST = test_quota_compliance_https \ - test_quota_compliance_https_asymmetric + test_quota_compliance_https_asymmetric endif +endif if USE_COVERAGE AM_CFLAGS = --coverage -O0 @@ -36,17 +49,20 @@ if LINUX WLAN_BIN = gnunet-helper-transport-wlan WLAN_BIN_DUMMY = gnunet-helper-transport-wlan-dummy WLAN_BIN_SENDER = gnunet-transport-wlan-sender + WLAN_BIN_RECEIVER = gnunet-transport-wlan-receiver WLAN_PLUGIN_LA = libgnunet_plugin_transport_wlan.la + WLAN_PLUGIN_TEST = test_plugin_wlan WLAN_API_TEST = test_transport_api_wlan WLAN_REL_TEST = test_transport_api_reliability_wlan WLAN_UREL_TEST = test_transport_api_unreliability_wlan + WLAN_QUOTA_TEST = test_quota_compliance_wlan \ + test_quota_compliance_wlan_asymmetric endif if LINUX install-exec-hook: - $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-transport-wlan || true - $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-transport-wlan || true + $(top_srcdir)/src/transport/install-wlan-helper.sh $(libexecdir) $(SUDO_BINARY) || true else install-exec-hook: endif @@ -54,6 +70,7 @@ endif if !MINGW UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la UNIX_PLUGIN_TEST = test_transport_api_unix +UNIX_TEST = test_plugin_unix UNIX_PLUGIN_TIMEOUT_TEST = test_transport_api_timeout_unix UNIX_REL_TEST = test_transport_api_unreliability_unix UNIX_QUOTA_TEST = test_quota_compliance_unix \ @@ -61,8 +78,8 @@ UNIX_QUOTA_TEST = test_quota_compliance_unix \ endif noinst_PROGRAMS = \ - $(WLAN_BIN_SENDER) -# gnunet-transport-connect-running-peers + $(WLAN_BIN_SENDER) \ + $(WLAN_BIN_RECEIVER) lib_LTLIBRARIES = \ libgnunettransport.la \ @@ -74,6 +91,7 @@ libgnunettransporttesting_la_LIBADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(GN_LIBINTL) libgnunettransporttesting_la_DEPENDENCIES = \ libgnunettransport.la @@ -91,13 +109,15 @@ libgnunettransport_la_LIBADD = \ $(GN_LIBINTL) libgnunettransport_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:0 + -version-info 3:0:1 -bin_PROGRAMS = \ - gnunet-transport \ +libexec_PROGRAMS = \ $(WLAN_BIN) \ $(WLAN_BIN_DUMMY) \ - gnunet-service-transport \ + gnunet-service-transport + +bin_PROGRAMS = \ + gnunet-transport \ gnunet-transport-certificate-creation #bin_SCRIPTS = \ @@ -121,6 +141,11 @@ gnunet_transport_wlan_sender_SOURCES = \ gnunet_transport_wlan_sender_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +gnunet_transport_wlan_receiver_SOURCES = \ + gnunet-transport-wlan-receiver.c +gnunet_transport_wlan_receiver_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + gnunet_transport_SOURCES = \ gnunet-transport.c gnunet_transport_LDADD = \ @@ -139,7 +164,8 @@ gnunet_service_transport_SOURCES = \ gnunet-service-transport_hello.h gnunet-service-transport_hello.c \ gnunet-service-transport_neighbours.h gnunet-service-transport_neighbours.c \ gnunet-service-transport_plugins.h gnunet-service-transport_plugins.c \ - gnunet-service-transport_validation.h gnunet-service-transport_validation.c + gnunet-service-transport_validation.h gnunet-service-transport_validation.c \ + gnunet-service-transport_manipulation.h gnunet-service-transport_manipulation.c gnunet_service_transport_LDADD = \ $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/hello/libgnunethello.la \ @@ -148,13 +174,18 @@ gnunet_service_transport_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_GLPK) \ $(GN_LIBINTL) +gnunet_service_transport_CFLAGS = \ + $(CFLAGS) +# -DANALYZE plugin_LTLIBRARIES = \ libgnunet_plugin_transport_tcp.la \ libgnunet_plugin_transport_udp.la \ $(UNIX_PLUGIN_LA) \ - $(HTTP_PLUGIN_LA) \ - $(HTTPS_PLUGIN_LA) \ + $(HTTP_CLIENT_PLUGIN_LA) \ + $(HTTPS_CLIENT_PLUGIN_LA) \ + $(HTTP_SERVER_PLUGIN_LA) \ + $(HTTPS_SERVER_PLUGIN_LA) \ $(WLAN_PLUGIN_LA) \ libgnunet_plugin_transport_template.la @@ -165,14 +196,16 @@ libgnunet_plugin_transport_tcp_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_tcp_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_transport_template_la_SOURCES = \ plugin_transport_template.c libgnunet_plugin_transport_template_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_template_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -196,7 +229,8 @@ libgnunet_plugin_transport_udp_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_udp_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -206,50 +240,88 @@ libgnunet_plugin_transport_unix_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_unix_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_http_la_SOURCES = \ - plugin_transport_http.c plugin_transport_http.h \ - plugin_transport_http_client.c plugin_transport_http_server.c -libgnunet_plugin_transport_http_la_LIBADD = \ + +libgnunet_plugin_transport_http_client_la_SOURCES = \ + plugin_transport_http_client.c plugin_transport_http_common.c plugin_transport_http_common.h +libgnunet_plugin_transport_http_client_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ @LIBCURL@ \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_transport_http_la_LDFLAGS = \ - $(GN_LIBMHD) \ +libgnunet_plugin_transport_http_client_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_http_la_CFLAGS = \ +libgnunet_plugin_transport_http_client_la_CFLAGS = \ $(CFLAGS) -libgnunet_plugin_transport_http_la_CPPFLAGS = \ +libgnunet_plugin_transport_http_client_la_CPPFLAGS = \ @LIBCURL_CPPFLAGS@ -libgnunet_plugin_transport_https_la_SOURCES = \ - plugin_transport_http.c plugin_transport_http.h \ - plugin_transport_http_client.c plugin_transport_http_server.c -libgnunet_plugin_transport_https_la_LIBADD = \ + +libgnunet_plugin_transport_http_server_la_SOURCES = \ + plugin_transport_http_server.c plugin_transport_http_common.c +libgnunet_plugin_transport_http_server_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ - @LIBCURL@ \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_transport_https_la_LDFLAGS = \ +libgnunet_plugin_transport_http_server_la_LDFLAGS = \ $(GN_LIBMHD) \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_https_la_CFLAGS = \ +libgnunet_plugin_transport_http_server_la_CFLAGS = \ + $(CFLAGS) + +libgnunet_plugin_transport_https_client_la_SOURCES = \ + plugin_transport_http_client.c plugin_transport_http_common.c +libgnunet_plugin_transport_https_client_la_LIBADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + @LIBCURL@ \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_transport_https_client_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_transport_https_client_la_CFLAGS = \ $(CFLAGS) -DBUILD_HTTPS -libgnunet_plugin_transport_https_la_CPPFLAGS = \ +libgnunet_plugin_transport_https_client_la_CPPFLAGS = \ @LIBCURL_CPPFLAGS@ +libgnunet_plugin_transport_https_server_la_SOURCES = \ + plugin_transport_http_server.c plugin_transport_http_common.c +libgnunet_plugin_transport_https_server_la_LIBADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunet_plugin_transport_https_server_la_LDFLAGS = \ + $(GN_LIBMHD) \ + $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_transport_https_server_la_CFLAGS = \ + $(CFLAGS) -DBUILD_HTTPS + check_PROGRAMS = \ + test_transport_testing_startstop \ + test_transport_testing_restart \ test_transport_testing \ test_transport_startonly \ + test_plugin_tcp \ + test_plugin_udp \ + $(UNIX_TEST) \ + $(WLAN_PLUGIN_TEST) \ + test_http_common \ + $(HTTP_CLIENT_PLUGIN_TEST) \ + $(HTTPS_CLIENT_PLUGIN_TEST) \ + $(HTTP_SERVER_PLUGIN_TEST) \ + $(HTTPS_SERVER_PLUGIN_TEST) \ test_transport_api_blacklisting \ test_transport_api_disconnect_tcp \ test_transport_api_bidirectional_connect \ @@ -265,35 +337,41 @@ check_PROGRAMS = \ $(UNIX_PLUGIN_TIMEOUT_TEST) \ test_transport_api_udp_nat \ $(HTTP_API_TEST) \ - $(HTTP_NAT_API_TEST) \ + $(HTTP_REVERSE_API_TEST) \ $(HTTP_API_TIMEOUT_TEST) \ $(HTTPS_API_TEST) \ - $(HTTPS_NAT_API_TEST) \ $(HTTPS_API_TIMEOUT_TEST) \ + $(WLAN_API_TEST) \ test_transport_api_multi \ + test_transport_api_manipulation_send_tcp \ + test_transport_api_manipulation_recv_tcp \ test_transport_api_reliability_tcp \ test_transport_api_reliability_tcp_nat \ test_transport_api_unreliability_udp \ test_transport_api_unreliability_constant_udp \ $(UNIX_REL_TEST) \ $(HTTP_REL_TEST) \ - $(HTTP_NAT_REL_TEST) \ $(HTTPS_REL_TEST) \ - $(HTTPS_NAT_REL_TEST) \ + $(WLAN_REL_TEST) \ + $(WLAN_UREL_TEST) \ test_quota_compliance_tcp \ test_quota_compliance_tcp_asymmetric \ test_quota_compliance_udp \ $(UNIX_QUOTA_TEST) \ $(HTTP_QUOTA_TEST) \ $(HTTPS_QUOTA_TEST) \ - $(WLAN_API_TEST) \ - $(WLAN_REL_TEST) \ - $(WLAN_UREL_TEST) + $(WLAN_QUOTA_TEST) if ENABLE_TEST_RUN TESTS = \ + test_transport_testing_startstop \ + test_transport_testing_restart \ test_transport_testing \ test_transport_startonly \ + test_plugin_tcp \ + test_plugin_udp \ + $(UNIX_TEST) \ + $(WLAN_PLUGIN_TEST) \ test_transport_api_blacklisting \ test_transport_api_disconnect_tcp \ test_transport_api_bidirectional_connect \ @@ -309,32 +387,46 @@ TESTS = \ $(UNIX_PLUGIN_TIMEOUT_TEST) \ test_transport_api_udp_nat \ $(HTTP_API_TEST) \ - $(HTTP_NAT_API_TEST) \ $(HTTP_API_TIMEOUT_TEST) \ $(HTTPS_API_TEST) \ - $(HTTPS_NAT_API_TEST) \ $(HTTPS_API_TIMEOUT_TEST) \ + $(WLAN_API_TEST) \ test_transport_api_multi \ + test_transport_api_manipulation_send_tcp \ + test_transport_api_manipulation_recv_tcp \ test_transport_api_reliability_tcp \ test_transport_api_reliability_tcp_nat \ test_transport_api_unreliability_udp \ test_transport_api_unreliability_constant_udp \ $(UNIX_REL_TEST) \ $(HTTP_REL_TEST) \ - $(HTTP_NAT_REL_TEST) \ $(HTTPS_REL_TEST) \ - $(HTTPS_NAT_REL_TEST) \ + $(WLAN_REL_TEST) \ + $(WLAN_UREL_TEST) \ test_quota_compliance_tcp \ test_quota_compliance_tcp_asymmetric \ test_quota_compliance_udp \ $(UNIX_QUOTA_TEST) \ $(HTTP_QUOTA_TEST) \ - $(HTTPS_QUOTA_TEST) \ - $(WLAN_API_TEST) \ - $(WLAN_REL_TEST) \ - $(WLAN_UREL_TEST) + $(HTTPS_QUOTA_TEST) endif +test_transport_testing_startstop_SOURCES = \ + test_transport_testing_startstop.c +test_transport_testing_startstop_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_transport_testing_restart_SOURCES = \ + test_transport_testing_restart.c +test_transport_testing_restart_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + test_transport_testing_SOURCES = \ test_transport_testing.c test_transport_testing_LDADD = \ @@ -343,14 +435,6 @@ test_transport_testing_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -#gnunet_transport_connect_running_peers_SOURCES = \ -# gnunet-transport-connect-running-peers.c -#gnunet_transport_connect_running_peers_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/hello/libgnunethello.la \ -# $(top_builddir)/src/util/libgnunetutil.la \ -# $(top_builddir)/src/transport/libgnunettransporttesting.la - test_transport_api_blacklisting_SOURCES = \ test_transport_api_blacklisting.c test_transport_api_blacklisting_LDADD = \ @@ -378,6 +462,88 @@ test_transport_startonly_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +test_plugin_tcp_SOURCES = \ + test_plugin_transport.c +test_plugin_tcp_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_udp_SOURCES = \ + test_plugin_transport.c +test_plugin_udp_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_unix_SOURCES = \ + test_plugin_transport.c +test_plugin_unix_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_wlan_SOURCES = \ + test_plugin_transport.c +test_plugin_wlan_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + + +test_http_common_SOURCES = \ + test_http_common.c plugin_transport_http_common.c +test_http_common_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_http_server_SOURCES = \ + test_plugin_transport.c +test_plugin_http_server_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_https_server_SOURCES = \ + test_plugin_transport.c +test_plugin_https_server_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_http_client_SOURCES = \ + test_plugin_transport.c +test_plugin_http_client_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_https_client_SOURCES = \ + test_plugin_transport.c +test_plugin_https_client_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + test_transport_api_tcp_SOURCES = \ test_transport_api.c test_transport_api_tcp_LDADD = \ @@ -385,7 +551,7 @@ test_transport_api_tcp_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - + test_transport_api_bidirectional_connect_SOURCES = \ test_transport_api_bidirectional_connect.c test_transport_api_bidirectional_connect_LDADD = \ @@ -411,7 +577,7 @@ test_transport_api_restart_2peers_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - + test_transport_api_limited_sockets_tcp_SOURCES = \ test_transport_api_limited_sockets.c test_transport_api_limited_sockets_tcp_LDADD = \ @@ -428,46 +594,47 @@ test_transport_api_tcp_nat_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_tcp_SOURCES = \ - test_transport_api_reliability.c -test_transport_api_reliability_tcp_LDADD = \ +test_transport_api_manipulation_send_tcp_SOURCES = \ + test_transport_api_manipulation_send_tcp.c +test_transport_api_manipulation_send_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_tcp_SOURCES = \ - test_transport_api_timeout.c -test_transport_api_timeout_tcp_LDADD = \ +test_transport_api_manipulation_recv_tcp_SOURCES = \ + test_transport_api_manipulation_recv_tcp.c +test_transport_api_manipulation_recv_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_unix_SOURCES = \ - test_transport_api_timeout.c -test_transport_api_timeout_unix_LDADD = \ + +test_transport_api_reliability_tcp_SOURCES = \ + test_transport_api_reliability.c +test_transport_api_reliability_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_http_SOURCES = \ +test_transport_api_timeout_tcp_SOURCES = \ test_transport_api_timeout.c -test_transport_api_timeout_http_LDADD = \ +test_transport_api_timeout_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - -test_transport_api_timeout_https_SOURCES = \ + +test_transport_api_timeout_unix_SOURCES = \ test_transport_api_timeout.c -test_transport_api_timeout_https_LDADD = \ +test_transport_api_timeout_unix_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - + test_transport_api_reliability_tcp_nat_SOURCES = \ test_transport_api_reliability.c test_transport_api_reliability_tcp_nat_LDADD = \ @@ -491,7 +658,7 @@ test_transport_api_unreliability_wlan_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - + test_transport_api_udp_SOURCES = \ test_transport_api.c test_transport_api_udp_LDADD = \ @@ -499,7 +666,7 @@ test_transport_api_udp_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - + test_transport_api_timeout_udp_SOURCES = \ test_transport_api_timeout.c test_transport_api_timeout_udp_LDADD = \ @@ -524,21 +691,30 @@ test_transport_api_unix_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +# HTTP tests test_transport_api_http_SOURCES = \ test_transport_api.c test_transport_api_http_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - - test_transport_api_http_nat_SOURCES = \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_transport_api_http_reverse_SOURCES = \ test_transport_api.c -test_transport_api_http_nat_LDADD = \ +test_transport_api_http_reverse_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_transport_api_timeout_http_SOURCES = \ + test_transport_api_timeout.c +test_transport_api_timeout_http_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la test_transport_api_reliability_http_SOURCES = \ test_transport_api_reliability.c @@ -548,14 +724,39 @@ test_transport_api_reliability_http_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_http_nat_SOURCES = \ - test_transport_api_reliability.c -test_transport_api_reliability_http_nat_LDADD = \ +test_quota_compliance_http_SOURCES = \ + test_quota_compliance.c +test_quota_compliance_http_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +test_quota_compliance_http_asymmetric_SOURCES = \ + test_quota_compliance.c +test_quota_compliance_http_asymmetric_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_quota_compliance_https_SOURCES = \ + test_quota_compliance.c +test_quota_compliance_https_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_quota_compliance_https_asymmetric_SOURCES = \ + test_quota_compliance.c +test_quota_compliance_https_asymmetric_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +# HTTPS tests test_transport_api_https_SOURCES = \ test_transport_api.c test_transport_api_https_LDADD = \ @@ -564,13 +765,14 @@ test_transport_api_https_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_https_nat_SOURCES = \ - test_transport_api.c -test_transport_api_https_nat_LDADD = \ +test_transport_api_timeout_https_SOURCES = \ + test_transport_api_timeout.c +test_transport_api_timeout_https_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la + $(top_builddir)/src/transport/libgnunettransporttesting.la + test_transport_api_reliability_https_SOURCES = \ test_transport_api_reliability.c @@ -580,14 +782,6 @@ test_transport_api_reliability_https_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_https_nat_SOURCES = \ - test_transport_api_reliability.c -test_transport_api_reliability_https_nat_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - test_transport_api_unreliability_unix_SOURCES = \ test_transport_api_unreliability.c test_transport_api_unreliability_unix_LDADD = \ @@ -638,75 +832,41 @@ test_quota_compliance_tcp_asymmetric_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -#test_quota_compliance_tcp_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_tcp_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la - -test_quota_compliance_http_SOURCES = \ - test_quota_compliance.c -test_quota_compliance_http_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - - test_quota_compliance_http_asymmetric_SOURCES = \ - test_quota_compliance.c -test_quota_compliance_http_asymmetric_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - -#test_quota_compliance_http_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_http_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la - -test_quota_compliance_https_SOURCES = \ +test_quota_compliance_udp_SOURCES = \ test_quota_compliance.c -test_quota_compliance_https_LDADD = \ +test_quota_compliance_udp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - test_quota_compliance_https_asymmetric_SOURCES = \ +test_quota_compliance_unix_SOURCES = \ test_quota_compliance.c -test_quota_compliance_https_asymmetric_LDADD = \ +test_quota_compliance_unix_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -#test_quota_compliance_https_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_https_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la - -test_quota_compliance_udp_SOURCES = \ +test_quota_compliance_unix_asymmetric_SOURCES = \ test_quota_compliance.c -test_quota_compliance_udp_LDADD = \ +test_quota_compliance_unix_asymmetric_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_quota_compliance_unix_SOURCES = \ +test_quota_compliance_wlan_SOURCES = \ test_quota_compliance.c -test_quota_compliance_unix_LDADD = \ +test_quota_compliance_wlan_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_quota_compliance_unix_asymmetric_SOURCES = \ +test_quota_compliance_wlan_asymmetric_SOURCES = \ test_quota_compliance.c -test_quota_compliance_unix_asymmetric_LDADD = \ +test_quota_compliance_wlan_asymmetric_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -722,7 +882,8 @@ test_transport_api_multi_LDADD = \ EXTRA_DIST = \ -gnunet-transport-certificate-creation \ +test_plugin_hostkey \ +test_plugin_hostkey.ecc \ template_cfg_peer1.conf\ template_cfg_peer2.conf\ test_plugin_transport_data.conf\ @@ -738,6 +899,8 @@ test_quota_compliance_udp_peer1.conf\ test_quota_compliance_udp_peer2.conf\ test_quota_compliance_unix_peer1.conf\ test_quota_compliance_unix_peer2.conf\ +test_quota_compliance_wlan_peer1.conf\ +test_quota_compliance_wlan_peer2.conf\ test_quota_compliance_http_asymmetric_peer1.conf\ test_quota_compliance_http_asymmetric_peer2.conf\ test_quota_compliance_https_asymmetric_peer1.conf\ @@ -746,6 +909,8 @@ test_quota_compliance_tcp_asymmetric_peer1.conf\ test_quota_compliance_tcp_asymmetric_peer2.conf\ test_quota_compliance_unix_asymmetric_peer1.conf\ test_quota_compliance_unix_asymmetric_peer2.conf\ +test_quota_compliance_wlan_asymmetric_peer1.conf\ +test_quota_compliance_wlan_asymmetric_peer2.conf\ test_transport_api_data.conf\ test_transport_api_http_peer1.conf\ test_transport_api_http_peer2.conf\ @@ -769,6 +934,10 @@ test_transport_api_reliability_wlan_peer1.conf\ test_transport_api_reliability_wlan_peer2.conf\ test_transport_api_bidirectional_connect_peer1.conf\ test_transport_api_bidirectional_connect_peer2.conf\ +test_transport_api_manipulation_send_tcp_peer1.conf\ +test_transport_api_manipulation_send_tcp_peer2.conf\ +test_transport_api_manipulation_recv_tcp_peer1.conf\ +test_transport_api_manipulation_recv_tcp_peer2.conf\ test_transport_api_tcp_nat_peer1.conf\ test_transport_api_tcp_nat_peer2.conf\ test_transport_api_tcp_peer1.conf\ @@ -795,17 +964,11 @@ test_transport_defaults.conf\ test_transport_startonly.conf\ test_transport_api_disconnect_tcp_peer1.conf\ test_transport_api_disconnect_tcp_peer2.conf\ -test_transport_api_http_nat_peer1.conf\ -test_transport_api_http_nat_peer2.conf\ -test_transport_api_https_nat_peer1.conf\ -test_transport_api_https_nat_peer2.conf\ -test_transport_api_reliability_http_nat_peer1.conf\ -test_transport_api_reliability_http_nat_peer2.conf\ -test_transport_api_reliability_https_nat_peer1.conf\ -test_transport_api_reliability_https_nat_peer2.conf\ test_transport_api_timeout_http_peer1.conf\ test_transport_api_timeout_http_peer2.conf\ test_transport_api_timeout_https_peer1.conf\ test_transport_api_timeout_https_peer2.conf\ test_transport_api_unreliability_constant_udp_peer1.conf\ -test_transport_api_unreliability_constant_udp_peer2.conf +test_transport_api_unreliability_constant_udp_peer2.conf\ +test_transport_api_http_reverse_peer1.conf \ +test_transport_api_http_reverse_peer2.conf diff --git a/src/transport/Makefile.in b/src/transport/Makefile.in index b5f2c64..71e52e9 100644 --- a/src/transport/Makefile.in +++ b/src/transport/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 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. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. @@ -18,6 +18,23 @@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,12 +54,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -noinst_PROGRAMS = $(am__EXEEXT_22) -bin_PROGRAMS = gnunet-transport$(EXEEXT) $(am__EXEEXT_1) \ - $(am__EXEEXT_2) gnunet-service-transport$(EXEEXT) \ +noinst_PROGRAMS = $(am__EXEEXT_26) $(am__EXEEXT_27) +libexec_PROGRAMS = $(am__EXEEXT_24) $(am__EXEEXT_25) \ + gnunet-service-transport$(EXEEXT) +bin_PROGRAMS = gnunet-transport$(EXEEXT) \ gnunet-transport-certificate-creation$(EXEEXT) -check_PROGRAMS = test_transport_testing$(EXEEXT) \ - test_transport_startonly$(EXEEXT) \ +check_PROGRAMS = test_transport_testing_startstop$(EXEEXT) \ + test_transport_testing_restart$(EXEEXT) \ + test_transport_testing$(EXEEXT) \ + test_transport_startonly$(EXEEXT) test_plugin_tcp$(EXEEXT) \ + test_plugin_udp$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \ + test_http_common$(EXEEXT) $(am__EXEEXT_3) $(am__EXEEXT_4) \ + $(am__EXEEXT_5) $(am__EXEEXT_6) \ test_transport_api_blacklisting$(EXEEXT) \ test_transport_api_disconnect_tcp$(EXEEXT) \ test_transport_api_bidirectional_connect$(EXEEXT) \ @@ -53,24 +76,30 @@ 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_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_timeout_udp$(EXEEXT) $(am__EXEEXT_7) \ + $(am__EXEEXT_8) test_transport_api_udp_nat$(EXEEXT) \ + $(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_11) \ + $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) \ test_transport_api_multi$(EXEEXT) \ + test_transport_api_manipulation_send_tcp$(EXEEXT) \ + test_transport_api_manipulation_recv_tcp$(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_11) $(am__EXEEXT_12) $(am__EXEEXT_13) \ - $(am__EXEEXT_14) $(am__EXEEXT_15) \ + $(am__EXEEXT_15) $(am__EXEEXT_16) $(am__EXEEXT_17) \ + $(am__EXEEXT_18) $(am__EXEEXT_19) \ test_quota_compliance_tcp$(EXEEXT) \ test_quota_compliance_tcp_asymmetric$(EXEEXT) \ - 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) \ + test_quota_compliance_udp$(EXEEXT) $(am__EXEEXT_20) \ + $(am__EXEEXT_21) $(am__EXEEXT_22) $(am__EXEEXT_23) +@ENABLE_TEST_RUN_TRUE@TESTS = test_transport_testing_startstop$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_transport_testing_restart$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_transport_testing$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_startonly$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_plugin_tcp$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_plugin_udp$(EXEEXT) $(am__EXEEXT_1) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_2) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_blacklisting$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_disconnect_tcp$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_bidirectional_connect$(EXEEXT) \ @@ -82,39 +111,41 @@ 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_3) $(am__EXEEXT_4) \ -@ENABLE_TEST_RUN_TRUE@ test_transport_api_udp_nat$(EXEEXT) \ -@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_udp_nat$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_9) $(am__EXEEXT_11) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_12) $(am__EXEEXT_13) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_14) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_multi$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_transport_api_manipulation_send_tcp$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_transport_api_manipulation_recv_tcp$(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_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@ $(am__EXEEXT_15) $(am__EXEEXT_16) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_17) $(am__EXEEXT_18) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_19) \ @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_16) $(am__EXEEXT_17) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_18) $(am__EXEEXT_19) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_20) $(am__EXEEXT_21) +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_20) $(am__EXEEXT_21) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_22) subdir = src/transport DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/transport.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/gettext.m4 $(top_srcdir)/m4/glib-2.0.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/pkg.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) \ @@ -144,55 +175,97 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)" + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) -libgnunet_plugin_transport_http_la_DEPENDENCIES = \ +libgnunet_plugin_transport_http_client_la_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -am_libgnunet_plugin_transport_http_la_OBJECTS = \ - libgnunet_plugin_transport_http_la-plugin_transport_http.lo \ - libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo \ - libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo -libgnunet_plugin_transport_http_la_OBJECTS = \ - $(am_libgnunet_plugin_transport_http_la_OBJECTS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am_libgnunet_plugin_transport_http_client_la_OBJECTS = libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo \ + libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo +libgnunet_plugin_transport_http_client_la_OBJECTS = \ + $(am_libgnunet_plugin_transport_http_client_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent -libgnunet_plugin_transport_http_la_LINK = $(LIBTOOL) $(AM_V_lt) \ +libgnunet_plugin_transport_http_client_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) \ - $(libgnunet_plugin_transport_http_la_LDFLAGS) $(LDFLAGS) -o $@ -@HAVE_MHD_TRUE@am_libgnunet_plugin_transport_http_la_rpath = -rpath \ -@HAVE_MHD_TRUE@ $(plugindir) -libgnunet_plugin_transport_https_la_DEPENDENCIES = \ + $(CCLD) $(libgnunet_plugin_transport_http_client_la_CFLAGS) \ + $(CFLAGS) $(libgnunet_plugin_transport_http_client_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_LIBCURL_TRUE@am_libgnunet_plugin_transport_http_client_la_rpath = \ +@HAVE_LIBCURL_TRUE@ -rpath $(plugindir) +libgnunet_plugin_transport_http_server_la_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -am_libgnunet_plugin_transport_https_la_OBJECTS = \ - libgnunet_plugin_transport_https_la-plugin_transport_http.lo \ - libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo \ - libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo -libgnunet_plugin_transport_https_la_OBJECTS = \ - $(am_libgnunet_plugin_transport_https_la_OBJECTS) -libgnunet_plugin_transport_https_la_LINK = $(LIBTOOL) $(AM_V_lt) \ +am_libgnunet_plugin_transport_http_server_la_OBJECTS = libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo \ + libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo +libgnunet_plugin_transport_http_server_la_OBJECTS = \ + $(am_libgnunet_plugin_transport_http_server_la_OBJECTS) +libgnunet_plugin_transport_http_server_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(libgnunet_plugin_transport_https_la_CFLAGS) \ - $(CFLAGS) $(libgnunet_plugin_transport_https_la_LDFLAGS) \ + $(CCLD) $(libgnunet_plugin_transport_http_server_la_CFLAGS) \ + $(CFLAGS) $(libgnunet_plugin_transport_http_server_la_LDFLAGS) \ $(LDFLAGS) -o $@ -@HAVE_MHD_TRUE@am_libgnunet_plugin_transport_https_la_rpath = -rpath \ -@HAVE_MHD_TRUE@ $(plugindir) -libgnunet_plugin_transport_tcp_la_DEPENDENCIES = \ +@HAVE_MHD_TRUE@am_libgnunet_plugin_transport_http_server_la_rpath = \ +@HAVE_MHD_TRUE@ -rpath $(plugindir) +libgnunet_plugin_transport_https_client_la_DEPENDENCIES = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunet_plugin_transport_https_client_la_OBJECTS = libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo \ + libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo +libgnunet_plugin_transport_https_client_la_OBJECTS = \ + $(am_libgnunet_plugin_transport_https_client_la_OBJECTS) +libgnunet_plugin_transport_https_client_la_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) \ + $(libgnunet_plugin_transport_https_client_la_CFLAGS) $(CFLAGS) \ + $(libgnunet_plugin_transport_https_client_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_LIBCURL_TRUE@am_libgnunet_plugin_transport_https_client_la_rpath = \ +@HAVE_LIBCURL_TRUE@ -rpath $(plugindir) +libgnunet_plugin_transport_https_server_la_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la +am_libgnunet_plugin_transport_https_server_la_OBJECTS = libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.lo \ + libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.lo +libgnunet_plugin_transport_https_server_la_OBJECTS = \ + $(am_libgnunet_plugin_transport_https_server_la_OBJECTS) +libgnunet_plugin_transport_https_server_la_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) \ + $(libgnunet_plugin_transport_https_server_la_CFLAGS) $(CFLAGS) \ + $(libgnunet_plugin_transport_https_server_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_MHD_TRUE@am_libgnunet_plugin_transport_https_server_la_rpath = \ +@HAVE_MHD_TRUE@ -rpath $(plugindir) +am__DEPENDENCIES_1 = +libgnunet_plugin_transport_tcp_la_DEPENDENCIES = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) am_libgnunet_plugin_transport_tcp_la_OBJECTS = \ plugin_transport_tcp.lo libgnunet_plugin_transport_tcp_la_OBJECTS = \ @@ -202,7 +275,8 @@ libgnunet_plugin_transport_tcp_la_LINK = $(LIBTOOL) $(AM_V_lt) \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libgnunet_plugin_transport_tcp_la_LDFLAGS) $(LDFLAGS) -o $@ libgnunet_plugin_transport_template_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) am_libgnunet_plugin_transport_template_la_OBJECTS = \ plugin_transport_template.lo libgnunet_plugin_transport_template_la_OBJECTS = \ @@ -218,7 +292,8 @@ libgnunet_plugin_transport_udp_la_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) am_libgnunet_plugin_transport_udp_la_OBJECTS = \ plugin_transport_udp.lo plugin_transport_udp_broadcasting.lo libgnunet_plugin_transport_udp_la_OBJECTS = \ @@ -231,7 +306,8 @@ libgnunet_plugin_transport_unix_la_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) am_libgnunet_plugin_transport_unix_la_OBJECTS = \ plugin_transport_unix.lo libgnunet_plugin_transport_unix_la_OBJECTS = \ @@ -258,7 +334,6 @@ libgnunet_plugin_transport_wlan_la_LINK = $(LIBTOOL) $(AM_V_lt) \ $(libgnunet_plugin_transport_wlan_la_LDFLAGS) $(LDFLAGS) -o $@ @LINUX_TRUE@am_libgnunet_plugin_transport_wlan_la_rpath = -rpath \ @LINUX_TRUE@ $(plugindir) -am__DEPENDENCIES_1 = libgnunettransport_la_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -278,40 +353,42 @@ libgnunettransporttesting_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunettransporttesting_la_LDFLAGS) \ $(LDFLAGS) -o $@ -@LINUX_TRUE@am__EXEEXT_1 = gnunet-helper-transport-wlan$(EXEEXT) -@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_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_11 = \ +@MINGW_FALSE@am__EXEEXT_1 = test_plugin_unix$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_2 = test_plugin_wlan$(EXEEXT) +@HAVE_LIBCURL_TRUE@am__EXEEXT_3 = test_plugin_http_client$(EXEEXT) +@HAVE_LIBCURL_TRUE@am__EXEEXT_4 = test_plugin_https_client$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_5 = test_plugin_http_server$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_6 = test_plugin_https_server$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_7 = test_transport_api_unix$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_8 = test_transport_api_timeout_unix$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_9 = test_transport_api_http$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_10 = test_transport_api_http_reverse$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_11 = test_transport_api_timeout_http$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_12 = test_transport_api_https$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_13 = test_transport_api_timeout_https$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_14 = test_transport_api_wlan$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_15 = \ @MINGW_FALSE@ test_transport_api_unreliability_unix$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_12 = \ -@HAVE_MHD_TRUE@ test_transport_api_reliability_http$(EXEEXT) -@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_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_17 = test_quota_compliance_http$(EXEEXT) \ -@HAVE_MHD_TRUE@ test_quota_compliance_http_asymmetric$(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_19 = test_transport_api_wlan$(EXEEXT) -@LINUX_TRUE@am__EXEEXT_20 = \ +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_16 = test_transport_api_reliability_http$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_17 = test_transport_api_reliability_https$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_18 = \ @LINUX_TRUE@ test_transport_api_reliability_wlan$(EXEEXT) -@LINUX_TRUE@am__EXEEXT_21 = \ +@LINUX_TRUE@am__EXEEXT_19 = \ @LINUX_TRUE@ test_transport_api_unreliability_wlan$(EXEEXT) -@LINUX_TRUE@am__EXEEXT_22 = gnunet-transport-wlan-sender$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +@MINGW_FALSE@am__EXEEXT_20 = test_quota_compliance_unix$(EXEEXT) \ +@MINGW_FALSE@ test_quota_compliance_unix_asymmetric$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_21 = test_quota_compliance_http$(EXEEXT) \ +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@ test_quota_compliance_http_asymmetric$(EXEEXT) +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@am__EXEEXT_22 = test_quota_compliance_https$(EXEEXT) \ +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@ test_quota_compliance_https_asymmetric$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_23 = test_quota_compliance_wlan$(EXEEXT) \ +@LINUX_TRUE@ test_quota_compliance_wlan_asymmetric$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_24 = gnunet-helper-transport-wlan$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_25 = \ +@LINUX_TRUE@ gnunet-helper-transport-wlan-dummy$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_26 = gnunet-transport-wlan-sender$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_27 = gnunet-transport-wlan-receiver$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS) am_gnunet_helper_transport_wlan_OBJECTS = \ gnunet-helper-transport-wlan.$(OBJEXT) gnunet_helper_transport_wlan_OBJECTS = \ @@ -324,13 +401,14 @@ gnunet_helper_transport_wlan_dummy_OBJECTS = \ gnunet_helper_transport_wlan_dummy_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la am_gnunet_service_transport_OBJECTS = \ - gnunet-service-transport.$(OBJEXT) \ - gnunet-service-transport_blacklist.$(OBJEXT) \ - gnunet-service-transport_clients.$(OBJEXT) \ - gnunet-service-transport_hello.$(OBJEXT) \ - gnunet-service-transport_neighbours.$(OBJEXT) \ - gnunet-service-transport_plugins.$(OBJEXT) \ - gnunet-service-transport_validation.$(OBJEXT) + gnunet_service_transport-gnunet-service-transport.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_blacklist.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_clients.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_hello.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_neighbours.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_plugins.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_validation.$(OBJEXT) \ + gnunet_service_transport-gnunet-service-transport_manipulation.$(OBJEXT) gnunet_service_transport_OBJECTS = \ $(am_gnunet_service_transport_OBJECTS) gnunet_service_transport_DEPENDENCIES = \ @@ -340,6 +418,10 @@ gnunet_service_transport_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) +gnunet_service_transport_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(gnunet_service_transport_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ am_gnunet_transport_OBJECTS = gnunet-transport.$(OBJEXT) gnunet_transport_OBJECTS = $(am_gnunet_transport_OBJECTS) am_gnunet_transport_certificate_creation_OBJECTS = \ @@ -348,12 +430,95 @@ gnunet_transport_certificate_creation_OBJECTS = \ $(am_gnunet_transport_certificate_creation_OBJECTS) gnunet_transport_certificate_creation_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la +am_gnunet_transport_wlan_receiver_OBJECTS = \ + gnunet-transport-wlan-receiver.$(OBJEXT) +gnunet_transport_wlan_receiver_OBJECTS = \ + $(am_gnunet_transport_wlan_receiver_OBJECTS) +gnunet_transport_wlan_receiver_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la am_gnunet_transport_wlan_sender_OBJECTS = \ gnunet-transport-wlan-sender.$(OBJEXT) gnunet_transport_wlan_sender_OBJECTS = \ $(am_gnunet_transport_wlan_sender_OBJECTS) gnunet_transport_wlan_sender_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la +am_test_http_common_OBJECTS = test_http_common.$(OBJEXT) \ + plugin_transport_http_common.$(OBJEXT) +test_http_common_OBJECTS = $(am_test_http_common_OBJECTS) +test_http_common_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_http_client_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_http_client_OBJECTS = \ + $(am_test_plugin_http_client_OBJECTS) +test_plugin_http_client_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_http_server_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_http_server_OBJECTS = \ + $(am_test_plugin_http_server_OBJECTS) +test_plugin_http_server_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_https_client_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_https_client_OBJECTS = \ + $(am_test_plugin_https_client_OBJECTS) +test_plugin_https_client_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_https_server_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_https_server_OBJECTS = \ + $(am_test_plugin_https_server_OBJECTS) +test_plugin_https_server_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_tcp_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_tcp_OBJECTS = $(am_test_plugin_tcp_OBJECTS) +test_plugin_tcp_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_udp_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_udp_OBJECTS = $(am_test_plugin_udp_OBJECTS) +test_plugin_udp_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_unix_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_unix_OBJECTS = $(am_test_plugin_unix_OBJECTS) +test_plugin_unix_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_plugin_wlan_OBJECTS = test_plugin_transport.$(OBJEXT) +test_plugin_wlan_OBJECTS = $(am_test_plugin_wlan_OBJECTS) +test_plugin_wlan_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_quota_compliance_http_OBJECTS = \ test_quota_compliance.$(OBJEXT) test_quota_compliance_http_OBJECTS = \ @@ -435,6 +600,24 @@ test_quota_compliance_unix_asymmetric_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_quota_compliance_wlan_OBJECTS = \ + test_quota_compliance.$(OBJEXT) +test_quota_compliance_wlan_OBJECTS = \ + $(am_test_quota_compliance_wlan_OBJECTS) +test_quota_compliance_wlan_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_quota_compliance_wlan_asymmetric_OBJECTS = \ + test_quota_compliance.$(OBJEXT) +test_quota_compliance_wlan_asymmetric_OBJECTS = \ + $(am_test_quota_compliance_wlan_asymmetric_OBJECTS) +test_quota_compliance_wlan_asymmetric_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_transport_api_bidirectional_connect_OBJECTS = \ test_transport_api_bidirectional_connect.$(OBJEXT) test_transport_api_bidirectional_connect_OBJECTS = \ @@ -472,10 +655,11 @@ test_transport_api_http_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -am_test_transport_api_http_nat_OBJECTS = test_transport_api.$(OBJEXT) -test_transport_api_http_nat_OBJECTS = \ - $(am_test_transport_api_http_nat_OBJECTS) -test_transport_api_http_nat_DEPENDENCIES = \ +am_test_transport_api_http_reverse_OBJECTS = \ + test_transport_api.$(OBJEXT) +test_transport_api_http_reverse_OBJECTS = \ + $(am_test_transport_api_http_reverse_OBJECTS) +test_transport_api_http_reverse_DEPENDENCIES = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -488,15 +672,6 @@ test_transport_api_https_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -am_test_transport_api_https_nat_OBJECTS = \ - test_transport_api.$(OBJEXT) -test_transport_api_https_nat_OBJECTS = \ - $(am_test_transport_api_https_nat_OBJECTS) -test_transport_api_https_nat_DEPENDENCIES = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_transport_api_limited_sockets_tcp_OBJECTS = \ test_transport_api_limited_sockets.$(OBJEXT) test_transport_api_limited_sockets_tcp_OBJECTS = \ @@ -506,6 +681,24 @@ test_transport_api_limited_sockets_tcp_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_transport_api_manipulation_recv_tcp_OBJECTS = \ + test_transport_api_manipulation_recv_tcp.$(OBJEXT) +test_transport_api_manipulation_recv_tcp_OBJECTS = \ + $(am_test_transport_api_manipulation_recv_tcp_OBJECTS) +test_transport_api_manipulation_recv_tcp_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_transport_api_manipulation_send_tcp_OBJECTS = \ + test_transport_api_manipulation_send_tcp.$(OBJEXT) +test_transport_api_manipulation_send_tcp_OBJECTS = \ + $(am_test_transport_api_manipulation_send_tcp_OBJECTS) +test_transport_api_manipulation_send_tcp_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_transport_api_multi_OBJECTS = test_transport_api.$(OBJEXT) test_transport_api_multi_OBJECTS = \ $(am_test_transport_api_multi_OBJECTS) @@ -523,15 +716,6 @@ test_transport_api_reliability_http_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -am_test_transport_api_reliability_http_nat_OBJECTS = \ - test_transport_api_reliability.$(OBJEXT) -test_transport_api_reliability_http_nat_OBJECTS = \ - $(am_test_transport_api_reliability_http_nat_OBJECTS) -test_transport_api_reliability_http_nat_DEPENDENCIES = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_transport_api_reliability_https_OBJECTS = \ test_transport_api_reliability.$(OBJEXT) test_transport_api_reliability_https_OBJECTS = \ @@ -541,15 +725,6 @@ test_transport_api_reliability_https_DEPENDENCIES = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -am_test_transport_api_reliability_https_nat_OBJECTS = \ - test_transport_api_reliability.$(OBJEXT) -test_transport_api_reliability_https_nat_OBJECTS = \ - $(am_test_transport_api_reliability_https_nat_OBJECTS) -test_transport_api_reliability_https_nat_DEPENDENCIES = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la am_test_transport_api_reliability_tcp_OBJECTS = \ test_transport_api_reliability.$(OBJEXT) test_transport_api_reliability_tcp_OBJECTS = \ @@ -742,6 +917,24 @@ test_transport_testing_DEPENDENCIES = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_transport_testing_restart_OBJECTS = \ + test_transport_testing_restart.$(OBJEXT) +test_transport_testing_restart_OBJECTS = \ + $(am_test_transport_testing_restart_OBJECTS) +test_transport_testing_restart_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la +am_test_transport_testing_startstop_OBJECTS = \ + test_transport_testing_startstop.$(OBJEXT) +test_transport_testing_startstop_OBJECTS = \ + $(am_test_transport_testing_startstop_OBJECTS) +test_transport_testing_startstop_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -752,24 +945,26 @@ 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 = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) 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 = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 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 = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) 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 = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ - $(libgnunet_plugin_transport_https_la_SOURCES) \ +SOURCES = $(libgnunet_plugin_transport_http_client_la_SOURCES) \ + $(libgnunet_plugin_transport_http_server_la_SOURCES) \ + $(libgnunet_plugin_transport_https_client_la_SOURCES) \ + $(libgnunet_plugin_transport_https_server_la_SOURCES) \ $(libgnunet_plugin_transport_tcp_la_SOURCES) \ $(libgnunet_plugin_transport_template_la_SOURCES) \ $(libgnunet_plugin_transport_udp_la_SOURCES) \ @@ -782,7 +977,14 @@ SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(gnunet_service_transport_SOURCES) \ $(gnunet_transport_SOURCES) \ $(gnunet_transport_certificate_creation_SOURCES) \ + $(gnunet_transport_wlan_receiver_SOURCES) \ $(gnunet_transport_wlan_sender_SOURCES) \ + $(test_http_common_SOURCES) $(test_plugin_http_client_SOURCES) \ + $(test_plugin_http_server_SOURCES) \ + $(test_plugin_https_client_SOURCES) \ + $(test_plugin_https_server_SOURCES) $(test_plugin_tcp_SOURCES) \ + $(test_plugin_udp_SOURCES) $(test_plugin_unix_SOURCES) \ + $(test_plugin_wlan_SOURCES) \ $(test_quota_compliance_http_SOURCES) \ $(test_quota_compliance_http_asymmetric_SOURCES) \ $(test_quota_compliance_https_SOURCES) \ @@ -792,19 +994,20 @@ SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(test_quota_compliance_udp_SOURCES) \ $(test_quota_compliance_unix_SOURCES) \ $(test_quota_compliance_unix_asymmetric_SOURCES) \ + $(test_quota_compliance_wlan_SOURCES) \ + $(test_quota_compliance_wlan_asymmetric_SOURCES) \ $(test_transport_api_bidirectional_connect_SOURCES) \ $(test_transport_api_blacklisting_SOURCES) \ $(test_transport_api_disconnect_tcp_SOURCES) \ $(test_transport_api_http_SOURCES) \ - $(test_transport_api_http_nat_SOURCES) \ + $(test_transport_api_http_reverse_SOURCES) \ $(test_transport_api_https_SOURCES) \ - $(test_transport_api_https_nat_SOURCES) \ $(test_transport_api_limited_sockets_tcp_SOURCES) \ + $(test_transport_api_manipulation_recv_tcp_SOURCES) \ + $(test_transport_api_manipulation_send_tcp_SOURCES) \ $(test_transport_api_multi_SOURCES) \ $(test_transport_api_reliability_http_SOURCES) \ - $(test_transport_api_reliability_http_nat_SOURCES) \ $(test_transport_api_reliability_https_SOURCES) \ - $(test_transport_api_reliability_https_nat_SOURCES) \ $(test_transport_api_reliability_tcp_SOURCES) \ $(test_transport_api_reliability_tcp_nat_SOURCES) \ $(test_transport_api_reliability_wlan_SOURCES) \ @@ -826,9 +1029,13 @@ SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(test_transport_api_unreliability_wlan_SOURCES) \ $(test_transport_api_wlan_SOURCES) \ $(test_transport_startonly_SOURCES) \ - $(test_transport_testing_SOURCES) -DIST_SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ - $(libgnunet_plugin_transport_https_la_SOURCES) \ + $(test_transport_testing_SOURCES) \ + $(test_transport_testing_restart_SOURCES) \ + $(test_transport_testing_startstop_SOURCES) +DIST_SOURCES = $(libgnunet_plugin_transport_http_client_la_SOURCES) \ + $(libgnunet_plugin_transport_http_server_la_SOURCES) \ + $(libgnunet_plugin_transport_https_client_la_SOURCES) \ + $(libgnunet_plugin_transport_https_server_la_SOURCES) \ $(libgnunet_plugin_transport_tcp_la_SOURCES) \ $(libgnunet_plugin_transport_template_la_SOURCES) \ $(libgnunet_plugin_transport_udp_la_SOURCES) \ @@ -841,7 +1048,14 @@ DIST_SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(gnunet_service_transport_SOURCES) \ $(gnunet_transport_SOURCES) \ $(gnunet_transport_certificate_creation_SOURCES) \ + $(gnunet_transport_wlan_receiver_SOURCES) \ $(gnunet_transport_wlan_sender_SOURCES) \ + $(test_http_common_SOURCES) $(test_plugin_http_client_SOURCES) \ + $(test_plugin_http_server_SOURCES) \ + $(test_plugin_https_client_SOURCES) \ + $(test_plugin_https_server_SOURCES) $(test_plugin_tcp_SOURCES) \ + $(test_plugin_udp_SOURCES) $(test_plugin_unix_SOURCES) \ + $(test_plugin_wlan_SOURCES) \ $(test_quota_compliance_http_SOURCES) \ $(test_quota_compliance_http_asymmetric_SOURCES) \ $(test_quota_compliance_https_SOURCES) \ @@ -851,19 +1065,20 @@ DIST_SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(test_quota_compliance_udp_SOURCES) \ $(test_quota_compliance_unix_SOURCES) \ $(test_quota_compliance_unix_asymmetric_SOURCES) \ + $(test_quota_compliance_wlan_SOURCES) \ + $(test_quota_compliance_wlan_asymmetric_SOURCES) \ $(test_transport_api_bidirectional_connect_SOURCES) \ $(test_transport_api_blacklisting_SOURCES) \ $(test_transport_api_disconnect_tcp_SOURCES) \ $(test_transport_api_http_SOURCES) \ - $(test_transport_api_http_nat_SOURCES) \ + $(test_transport_api_http_reverse_SOURCES) \ $(test_transport_api_https_SOURCES) \ - $(test_transport_api_https_nat_SOURCES) \ $(test_transport_api_limited_sockets_tcp_SOURCES) \ + $(test_transport_api_manipulation_recv_tcp_SOURCES) \ + $(test_transport_api_manipulation_send_tcp_SOURCES) \ $(test_transport_api_multi_SOURCES) \ $(test_transport_api_reliability_http_SOURCES) \ - $(test_transport_api_reliability_http_nat_SOURCES) \ $(test_transport_api_reliability_https_SOURCES) \ - $(test_transport_api_reliability_https_nat_SOURCES) \ $(test_transport_api_reliability_tcp_SOURCES) \ $(test_transport_api_reliability_tcp_nat_SOURCES) \ $(test_transport_api_reliability_wlan_SOURCES) \ @@ -885,7 +1100,14 @@ DIST_SOURCES = $(libgnunet_plugin_transport_http_la_SOURCES) \ $(test_transport_api_unreliability_wlan_SOURCES) \ $(am__test_transport_api_wlan_SOURCES_DIST) \ $(test_transport_startonly_SOURCES) \ - $(test_transport_testing_SOURCES) + $(test_transport_testing_SOURCES) \ + $(test_transport_testing_restart_SOURCES) \ + $(test_transport_testing_startstop_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DATA = $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags @@ -927,6 +1149,10 @@ EXEEXT = @EXEEXT@ EXT_LIBS = @EXT_LIBS@ EXT_LIB_PATH = @EXT_LIB_PATH@ FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ @@ -937,6 +1163,7 @@ GN_LIBINTL = @GN_LIBINTL@ GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ INCLTDL = @INCLTDL@ @@ -959,6 +1186,8 @@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGTOP_CFLAGS = @LIBGTOP_CFLAGS@ +LIBGTOP_LIBS = @LIBGTOP_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBLTDL = @LIBLTDL@ @@ -980,6 +1209,7 @@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ @@ -989,6 +1219,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ NM = @NM@ NMEDIT = @NMEDIT@ +NSS_DIR = @NSS_DIR@ OBJC = @OBJC@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ @@ -1004,6 +1235,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ POSUB = @POSUB@ @@ -1035,6 +1267,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -1057,6 +1290,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gitcommand = @gitcommand@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -1067,10 +1301,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ -libexecdir = @libexecdir@ +libexecdir = $(pkglibdir)/libexec/ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ @@ -1088,6 +1321,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ +svnversioncommand = @svnversioncommand@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ @@ -1105,40 +1339,48 @@ pkgcfg_DATA = \ transport.conf @HAVE_MHD_TRUE@GN_LIBMHD = -lmicrohttpd -@HAVE_MHD_TRUE@HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la -@HAVE_MHD_TRUE@HTTP_API_TEST = test_transport_api_http -@HAVE_MHD_TRUE@HTTP_NAT_API_TEST = test_transport_api_http_nat -@HAVE_MHD_TRUE@HTTP_API_TIMEOUT_TEST = test_transport_api_timeout_http -@HAVE_MHD_TRUE@HTTP_REL_TEST = test_transport_api_reliability_http -@HAVE_MHD_TRUE@HTTP_NAT_REL_TEST = test_transport_api_reliability_http_nat -@HAVE_MHD_TRUE@HTTP_QUOTA_TEST = test_quota_compliance_http \ -@HAVE_MHD_TRUE@ test_quota_compliance_http_asymmetric - -@HAVE_MHD_TRUE@HTTPS_PLUGIN_LA = libgnunet_plugin_transport_https.la -@HAVE_MHD_TRUE@HTTPS_API_TEST = test_transport_api_https -@HAVE_MHD_TRUE@HTTPS_NAT_API_TEST = test_transport_api_https_nat -@HAVE_MHD_TRUE@HTTPS_API_TIMEOUT_TEST = test_transport_api_timeout_https -@HAVE_MHD_TRUE@HTTPS_REL_TEST = test_transport_api_reliability_https -@HAVE_MHD_TRUE@HTTPS_NAT_REL_TEST = test_transport_api_reliability_https_nat -@HAVE_MHD_TRUE@HTTPS_QUOTA_TEST = test_quota_compliance_https \ -@HAVE_MHD_TRUE@ test_quota_compliance_https_asymmetric +@HAVE_MHD_TRUE@HTTP_SERVER_PLUGIN_LA = libgnunet_plugin_transport_http_server.la +@HAVE_MHD_TRUE@HTTPS_SERVER_PLUGIN_LA = libgnunet_plugin_transport_https_server.la +@HAVE_MHD_TRUE@HTTP_SERVER_PLUGIN_TEST = test_plugin_http_server +@HAVE_MHD_TRUE@HTTPS_SERVER_PLUGIN_TEST = test_plugin_https_server +@HAVE_LIBCURL_TRUE@HTTP_CLIENT_PLUGIN_TEST = test_plugin_http_client +@HAVE_LIBCURL_TRUE@HTTPS_CLIENT_PLUGIN_TEST = test_plugin_https_client +@HAVE_LIBCURL_TRUE@HTTP_CLIENT_PLUGIN_LA = libgnunet_plugin_transport_http_client.la +@HAVE_LIBCURL_TRUE@HTTPS_CLIENT_PLUGIN_LA = libgnunet_plugin_transport_https_client.la +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTP_API_TEST = test_transport_api_http +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTP_REVERSE_API_TEST = test_transport_api_http_reverse +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTP_API_TIMEOUT_TEST = test_transport_api_timeout_http +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTP_REL_TEST = test_transport_api_reliability_http +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTP_QUOTA_TEST = test_quota_compliance_http \ +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@ test_quota_compliance_http_asymmetric + +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTPS_API_TEST = test_transport_api_https +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTPS_API_TIMEOUT_TEST = test_transport_api_timeout_https +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTPS_REL_TEST = test_transport_api_reliability_https +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@HTTPS_QUOTA_TEST = test_quota_compliance_https \ +@HAVE_LIBCURL_TRUE@@HAVE_MHD_TRUE@ test_quota_compliance_https_asymmetric @USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 @LINUX_TRUE@WLAN_BIN = gnunet-helper-transport-wlan @LINUX_TRUE@WLAN_BIN_DUMMY = gnunet-helper-transport-wlan-dummy @LINUX_TRUE@WLAN_BIN_SENDER = gnunet-transport-wlan-sender +@LINUX_TRUE@WLAN_BIN_RECEIVER = gnunet-transport-wlan-receiver @LINUX_TRUE@WLAN_PLUGIN_LA = libgnunet_plugin_transport_wlan.la +@LINUX_TRUE@WLAN_PLUGIN_TEST = test_plugin_wlan @LINUX_TRUE@WLAN_API_TEST = test_transport_api_wlan @LINUX_TRUE@WLAN_REL_TEST = test_transport_api_reliability_wlan @LINUX_TRUE@WLAN_UREL_TEST = test_transport_api_unreliability_wlan +@LINUX_TRUE@WLAN_QUOTA_TEST = test_quota_compliance_wlan \ +@LINUX_TRUE@ test_quota_compliance_wlan_asymmetric + @MINGW_FALSE@UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la @MINGW_FALSE@UNIX_PLUGIN_TEST = test_transport_api_unix +@MINGW_FALSE@UNIX_TEST = test_plugin_unix @MINGW_FALSE@UNIX_PLUGIN_TIMEOUT_TEST = test_transport_api_timeout_unix @MINGW_FALSE@UNIX_REL_TEST = test_transport_api_unreliability_unix @MINGW_FALSE@UNIX_QUOTA_TEST = test_quota_compliance_unix \ @MINGW_FALSE@ test_quota_compliance_unix_asymmetric -# gnunet-transport-connect-running-peers lib_LTLIBRARIES = \ libgnunettransport.la \ libgnunettransporttesting.la @@ -1150,6 +1392,7 @@ libgnunettransporttesting_la_LIBADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(GN_LIBINTL) libgnunettransporttesting_la_DEPENDENCIES = \ @@ -1171,7 +1414,7 @@ libgnunettransport_la_LIBADD = \ libgnunettransport_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:0 + -version-info 3:0:1 #bin_SCRIPTS = \ @@ -1197,6 +1440,12 @@ gnunet_transport_wlan_sender_SOURCES = \ gnunet_transport_wlan_sender_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +gnunet_transport_wlan_receiver_SOURCES = \ + gnunet-transport-wlan-receiver.c + +gnunet_transport_wlan_receiver_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + gnunet_transport_SOURCES = \ gnunet-transport.c @@ -1217,7 +1466,8 @@ gnunet_service_transport_SOURCES = \ gnunet-service-transport_hello.h gnunet-service-transport_hello.c \ gnunet-service-transport_neighbours.h gnunet-service-transport_neighbours.c \ gnunet-service-transport_plugins.h gnunet-service-transport_plugins.c \ - gnunet-service-transport_validation.h gnunet-service-transport_validation.c + gnunet-service-transport_validation.h gnunet-service-transport_validation.c \ + gnunet-service-transport_manipulation.h gnunet-service-transport_manipulation.c gnunet_service_transport_LDADD = \ $(top_builddir)/src/ats/libgnunetats.la \ @@ -1228,12 +1478,18 @@ gnunet_service_transport_LDADD = \ $(GN_GLPK) \ $(GN_LIBINTL) +gnunet_service_transport_CFLAGS = \ + $(CFLAGS) + +# -DANALYZE plugin_LTLIBRARIES = \ libgnunet_plugin_transport_tcp.la \ libgnunet_plugin_transport_udp.la \ $(UNIX_PLUGIN_LA) \ - $(HTTP_PLUGIN_LA) \ - $(HTTPS_PLUGIN_LA) \ + $(HTTP_CLIENT_PLUGIN_LA) \ + $(HTTPS_CLIENT_PLUGIN_LA) \ + $(HTTP_SERVER_PLUGIN_LA) \ + $(HTTPS_SERVER_PLUGIN_LA) \ $(WLAN_PLUGIN_LA) \ libgnunet_plugin_transport_template.la @@ -1245,7 +1501,8 @@ libgnunet_plugin_transport_tcp_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_tcp_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -1254,7 +1511,8 @@ libgnunet_plugin_transport_template_la_SOURCES = \ plugin_transport_template.c libgnunet_plugin_transport_template_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_template_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -1282,7 +1540,8 @@ libgnunet_plugin_transport_udp_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/nat/libgnunetnat.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_udp_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -1294,16 +1553,16 @@ libgnunet_plugin_transport_unix_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_transport_unix_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_http_la_SOURCES = \ - plugin_transport_http.c plugin_transport_http.h \ - plugin_transport_http_client.c plugin_transport_http_server.c +libgnunet_plugin_transport_http_client_la_SOURCES = \ + plugin_transport_http_client.c plugin_transport_http_common.c plugin_transport_http_common.h -libgnunet_plugin_transport_http_la_LIBADD = \ +libgnunet_plugin_transport_http_client_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ @@ -1311,38 +1570,87 @@ libgnunet_plugin_transport_http_la_LIBADD = \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_transport_http_la_LDFLAGS = \ - $(GN_LIBMHD) \ +libgnunet_plugin_transport_http_client_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_http_la_CFLAGS = \ +libgnunet_plugin_transport_http_client_la_CFLAGS = \ $(CFLAGS) -libgnunet_plugin_transport_http_la_CPPFLAGS = \ +libgnunet_plugin_transport_http_client_la_CPPFLAGS = \ @LIBCURL_CPPFLAGS@ -libgnunet_plugin_transport_https_la_SOURCES = \ - plugin_transport_http.c plugin_transport_http.h \ - plugin_transport_http_client.c plugin_transport_http_server.c +libgnunet_plugin_transport_http_server_la_SOURCES = \ + plugin_transport_http_server.c plugin_transport_http_common.c -libgnunet_plugin_transport_https_la_LIBADD = \ +libgnunet_plugin_transport_http_server_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ - @LIBCURL@ \ $(top_builddir)/src/nat/libgnunetnat.la \ $(top_builddir)/src/util/libgnunetutil.la -libgnunet_plugin_transport_https_la_LDFLAGS = \ +libgnunet_plugin_transport_http_server_la_LDFLAGS = \ $(GN_LIBMHD) \ $(GN_PLUGIN_LDFLAGS) -libgnunet_plugin_transport_https_la_CFLAGS = \ +libgnunet_plugin_transport_http_server_la_CFLAGS = \ + $(CFLAGS) + +libgnunet_plugin_transport_https_client_la_SOURCES = \ + plugin_transport_http_client.c plugin_transport_http_common.c + +libgnunet_plugin_transport_https_client_la_LIBADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + @LIBCURL@ \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunet_plugin_transport_https_client_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + +libgnunet_plugin_transport_https_client_la_CFLAGS = \ $(CFLAGS) -DBUILD_HTTPS -libgnunet_plugin_transport_https_la_CPPFLAGS = \ +libgnunet_plugin_transport_https_client_la_CPPFLAGS = \ @LIBCURL_CPPFLAGS@ +libgnunet_plugin_transport_https_server_la_SOURCES = \ + plugin_transport_http_server.c plugin_transport_http_common.c + +libgnunet_plugin_transport_https_server_la_LIBADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/nat/libgnunetnat.la \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunet_plugin_transport_https_server_la_LDFLAGS = \ + $(GN_LIBMHD) \ + $(GN_PLUGIN_LDFLAGS) + +libgnunet_plugin_transport_https_server_la_CFLAGS = \ + $(CFLAGS) -DBUILD_HTTPS + +test_transport_testing_startstop_SOURCES = \ + test_transport_testing_startstop.c + +test_transport_testing_startstop_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_transport_testing_restart_SOURCES = \ + test_transport_testing_restart.c + +test_transport_testing_restart_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + test_transport_testing_SOURCES = \ test_transport_testing.c @@ -1352,14 +1660,6 @@ test_transport_testing_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - -#gnunet_transport_connect_running_peers_SOURCES = \ -# gnunet-transport-connect-running-peers.c -#gnunet_transport_connect_running_peers_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/hello/libgnunethello.la \ -# $(top_builddir)/src/util/libgnunetutil.la \ -# $(top_builddir)/src/transport/libgnunettransporttesting.la test_transport_api_blacklisting_SOURCES = \ test_transport_api_blacklisting.c @@ -1390,6 +1690,96 @@ test_transport_startonly_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +test_plugin_tcp_SOURCES = \ + test_plugin_transport.c + +test_plugin_tcp_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_udp_SOURCES = \ + test_plugin_transport.c + +test_plugin_udp_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_unix_SOURCES = \ + test_plugin_transport.c + +test_plugin_unix_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_wlan_SOURCES = \ + test_plugin_transport.c + +test_plugin_wlan_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_http_common_SOURCES = \ + test_http_common.c plugin_transport_http_common.c + +test_http_common_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_http_server_SOURCES = \ + test_plugin_transport.c + +test_plugin_http_server_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_https_server_SOURCES = \ + test_plugin_transport.c + +test_plugin_https_server_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_http_client_SOURCES = \ + test_plugin_transport.c + +test_plugin_http_client_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_plugin_https_client_SOURCES = \ + test_plugin_transport.c + +test_plugin_https_client_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + test_transport_api_tcp_SOURCES = \ test_transport_api.c @@ -1446,46 +1836,46 @@ test_transport_api_tcp_nat_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_tcp_SOURCES = \ - test_transport_api_reliability.c +test_transport_api_manipulation_send_tcp_SOURCES = \ + test_transport_api_manipulation_send_tcp.c -test_transport_api_reliability_tcp_LDADD = \ +test_transport_api_manipulation_send_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_tcp_SOURCES = \ - test_transport_api_timeout.c +test_transport_api_manipulation_recv_tcp_SOURCES = \ + test_transport_api_manipulation_recv_tcp.c -test_transport_api_timeout_tcp_LDADD = \ +test_transport_api_manipulation_recv_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_unix_SOURCES = \ - test_transport_api_timeout.c +test_transport_api_reliability_tcp_SOURCES = \ + test_transport_api_reliability.c -test_transport_api_timeout_unix_LDADD = \ +test_transport_api_reliability_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_http_SOURCES = \ +test_transport_api_timeout_tcp_SOURCES = \ test_transport_api_timeout.c -test_transport_api_timeout_http_LDADD = \ +test_transport_api_timeout_tcp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_timeout_https_SOURCES = \ +test_transport_api_timeout_unix_SOURCES = \ test_transport_api_timeout.c -test_transport_api_timeout_https_LDADD = \ +test_transport_api_timeout_unix_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -1554,6 +1944,8 @@ test_transport_api_unix_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la + +# HTTP tests test_transport_api_http_SOURCES = \ test_transport_api.c @@ -1561,16 +1953,25 @@ test_transport_api_http_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la + $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_http_nat_SOURCES = \ +test_transport_api_http_reverse_SOURCES = \ test_transport_api.c -test_transport_api_http_nat_LDADD = \ +test_transport_api_http_reverse_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_transport_api_timeout_http_SOURCES = \ + test_transport_api_timeout.c + +test_transport_api_timeout_http_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la test_transport_api_reliability_http_SOURCES = \ test_transport_api_reliability.c @@ -1581,15 +1982,44 @@ test_transport_api_reliability_http_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_http_nat_SOURCES = \ - test_transport_api_reliability.c +test_quota_compliance_http_SOURCES = \ + test_quota_compliance.c -test_transport_api_reliability_http_nat_LDADD = \ +test_quota_compliance_http_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la +test_quota_compliance_http_asymmetric_SOURCES = \ + test_quota_compliance.c + +test_quota_compliance_http_asymmetric_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_quota_compliance_https_SOURCES = \ + test_quota_compliance.c + +test_quota_compliance_https_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + +test_quota_compliance_https_asymmetric_SOURCES = \ + test_quota_compliance.c + +test_quota_compliance_https_asymmetric_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/transport/libgnunettransporttesting.la + + +# HTTPS tests test_transport_api_https_SOURCES = \ test_transport_api.c @@ -1599,14 +2029,14 @@ test_transport_api_https_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_https_nat_SOURCES = \ - test_transport_api.c +test_transport_api_timeout_https_SOURCES = \ + test_transport_api_timeout.c -test_transport_api_https_nat_LDADD = \ +test_transport_api_timeout_https_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la + $(top_builddir)/src/transport/libgnunettransporttesting.la test_transport_api_reliability_https_SOURCES = \ test_transport_api_reliability.c @@ -1617,15 +2047,6 @@ test_transport_api_reliability_https_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_transport_api_reliability_https_nat_SOURCES = \ - test_transport_api_reliability.c - -test_transport_api_reliability_https_nat_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - test_transport_api_unreliability_unix_SOURCES = \ test_transport_api_unreliability.c @@ -1680,82 +2101,46 @@ test_quota_compliance_tcp_asymmetric_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - -#test_quota_compliance_tcp_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_tcp_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la -test_quota_compliance_http_SOURCES = \ - test_quota_compliance.c - -test_quota_compliance_http_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - -test_quota_compliance_http_asymmetric_SOURCES = \ - test_quota_compliance.c - -test_quota_compliance_http_asymmetric_LDADD = \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/transport/libgnunettransporttesting.la - - -#test_quota_compliance_http_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_http_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la -test_quota_compliance_https_SOURCES = \ +test_quota_compliance_udp_SOURCES = \ test_quota_compliance.c -test_quota_compliance_https_LDADD = \ +test_quota_compliance_udp_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_quota_compliance_https_asymmetric_SOURCES = \ +test_quota_compliance_unix_SOURCES = \ test_quota_compliance.c -test_quota_compliance_https_asymmetric_LDADD = \ +test_quota_compliance_unix_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la - -#test_quota_compliance_https_asymmetric_send_constant_SOURCES = \ -# test_quota_compliance.c -#test_quota_compliance_https_asymmetric_send_constant_LDADD = \ -# $(top_builddir)/src/transport/libgnunettransport.la \ -# $(top_builddir)/src/util/libgnunetutil.la -test_quota_compliance_udp_SOURCES = \ +test_quota_compliance_unix_asymmetric_SOURCES = \ test_quota_compliance.c -test_quota_compliance_udp_LDADD = \ +test_quota_compliance_unix_asymmetric_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_quota_compliance_unix_SOURCES = \ +test_quota_compliance_wlan_SOURCES = \ test_quota_compliance.c -test_quota_compliance_unix_LDADD = \ +test_quota_compliance_wlan_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/transport/libgnunettransporttesting.la -test_quota_compliance_unix_asymmetric_SOURCES = \ +test_quota_compliance_wlan_asymmetric_SOURCES = \ test_quota_compliance.c -test_quota_compliance_unix_asymmetric_LDADD = \ +test_quota_compliance_wlan_asymmetric_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -1771,7 +2156,8 @@ test_transport_api_multi_LDADD = \ $(top_builddir)/src/transport/libgnunettransporttesting.la EXTRA_DIST = \ -gnunet-transport-certificate-creation \ +test_plugin_hostkey \ +test_plugin_hostkey.ecc \ template_cfg_peer1.conf\ template_cfg_peer2.conf\ test_plugin_transport_data.conf\ @@ -1787,6 +2173,8 @@ test_quota_compliance_udp_peer1.conf\ test_quota_compliance_udp_peer2.conf\ test_quota_compliance_unix_peer1.conf\ test_quota_compliance_unix_peer2.conf\ +test_quota_compliance_wlan_peer1.conf\ +test_quota_compliance_wlan_peer2.conf\ test_quota_compliance_http_asymmetric_peer1.conf\ test_quota_compliance_http_asymmetric_peer2.conf\ test_quota_compliance_https_asymmetric_peer1.conf\ @@ -1795,6 +2183,8 @@ test_quota_compliance_tcp_asymmetric_peer1.conf\ test_quota_compliance_tcp_asymmetric_peer2.conf\ test_quota_compliance_unix_asymmetric_peer1.conf\ test_quota_compliance_unix_asymmetric_peer2.conf\ +test_quota_compliance_wlan_asymmetric_peer1.conf\ +test_quota_compliance_wlan_asymmetric_peer2.conf\ test_transport_api_data.conf\ test_transport_api_http_peer1.conf\ test_transport_api_http_peer2.conf\ @@ -1818,6 +2208,10 @@ test_transport_api_reliability_wlan_peer1.conf\ test_transport_api_reliability_wlan_peer2.conf\ test_transport_api_bidirectional_connect_peer1.conf\ test_transport_api_bidirectional_connect_peer2.conf\ +test_transport_api_manipulation_send_tcp_peer1.conf\ +test_transport_api_manipulation_send_tcp_peer2.conf\ +test_transport_api_manipulation_recv_tcp_peer1.conf\ +test_transport_api_manipulation_recv_tcp_peer2.conf\ test_transport_api_tcp_nat_peer1.conf\ test_transport_api_tcp_nat_peer2.conf\ test_transport_api_tcp_peer1.conf\ @@ -1844,20 +2238,14 @@ test_transport_defaults.conf\ test_transport_startonly.conf\ test_transport_api_disconnect_tcp_peer1.conf\ test_transport_api_disconnect_tcp_peer2.conf\ -test_transport_api_http_nat_peer1.conf\ -test_transport_api_http_nat_peer2.conf\ -test_transport_api_https_nat_peer1.conf\ -test_transport_api_https_nat_peer2.conf\ -test_transport_api_reliability_http_nat_peer1.conf\ -test_transport_api_reliability_http_nat_peer2.conf\ -test_transport_api_reliability_https_nat_peer1.conf\ -test_transport_api_reliability_https_nat_peer2.conf\ test_transport_api_timeout_http_peer1.conf\ test_transport_api_timeout_http_peer2.conf\ test_transport_api_timeout_https_peer1.conf\ test_transport_api_timeout_https_peer2.conf\ test_transport_api_unreliability_constant_udp_peer1.conf\ -test_transport_api_unreliability_constant_udp_peer2.conf +test_transport_api_unreliability_constant_udp_peer2.conf\ +test_transport_api_http_reverse_peer1.conf \ +test_transport_api_http_reverse_peer2.conf all: all-am @@ -1897,7 +2285,6 @@ transport.conf: $(top_builddir)/config.status $(srcdir)/transport.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 \ @@ -1905,6 +2292,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ 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)"; \ } @@ -1928,7 +2317,6 @@ clean-libLTLIBRARIES: done install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -1936,6 +2324,8 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } @@ -1957,28 +2347,35 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgnunet_plugin_transport_http.la: $(libgnunet_plugin_transport_http_la_OBJECTS) $(libgnunet_plugin_transport_http_la_DEPENDENCIES) - $(AM_V_CCLD)$(libgnunet_plugin_transport_http_la_LINK) $(am_libgnunet_plugin_transport_http_la_rpath) $(libgnunet_plugin_transport_http_la_OBJECTS) $(libgnunet_plugin_transport_http_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_https.la: $(libgnunet_plugin_transport_https_la_OBJECTS) $(libgnunet_plugin_transport_https_la_DEPENDENCIES) - $(AM_V_CCLD)$(libgnunet_plugin_transport_https_la_LINK) $(am_libgnunet_plugin_transport_https_la_rpath) $(libgnunet_plugin_transport_https_la_OBJECTS) $(libgnunet_plugin_transport_https_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_tcp.la: $(libgnunet_plugin_transport_tcp_la_OBJECTS) $(libgnunet_plugin_transport_tcp_la_DEPENDENCIES) +libgnunet_plugin_transport_http_client.la: $(libgnunet_plugin_transport_http_client_la_OBJECTS) $(libgnunet_plugin_transport_http_client_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_http_client_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunet_plugin_transport_http_client_la_LINK) $(am_libgnunet_plugin_transport_http_client_la_rpath) $(libgnunet_plugin_transport_http_client_la_OBJECTS) $(libgnunet_plugin_transport_http_client_la_LIBADD) $(LIBS) +libgnunet_plugin_transport_http_server.la: $(libgnunet_plugin_transport_http_server_la_OBJECTS) $(libgnunet_plugin_transport_http_server_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_http_server_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunet_plugin_transport_http_server_la_LINK) $(am_libgnunet_plugin_transport_http_server_la_rpath) $(libgnunet_plugin_transport_http_server_la_OBJECTS) $(libgnunet_plugin_transport_http_server_la_LIBADD) $(LIBS) +libgnunet_plugin_transport_https_client.la: $(libgnunet_plugin_transport_https_client_la_OBJECTS) $(libgnunet_plugin_transport_https_client_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_https_client_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunet_plugin_transport_https_client_la_LINK) $(am_libgnunet_plugin_transport_https_client_la_rpath) $(libgnunet_plugin_transport_https_client_la_OBJECTS) $(libgnunet_plugin_transport_https_client_la_LIBADD) $(LIBS) +libgnunet_plugin_transport_https_server.la: $(libgnunet_plugin_transport_https_server_la_OBJECTS) $(libgnunet_plugin_transport_https_server_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_https_server_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunet_plugin_transport_https_server_la_LINK) $(am_libgnunet_plugin_transport_https_server_la_rpath) $(libgnunet_plugin_transport_https_server_la_OBJECTS) $(libgnunet_plugin_transport_https_server_la_LIBADD) $(LIBS) +libgnunet_plugin_transport_tcp.la: $(libgnunet_plugin_transport_tcp_la_OBJECTS) $(libgnunet_plugin_transport_tcp_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_tcp_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_transport_tcp_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_transport_tcp_la_OBJECTS) $(libgnunet_plugin_transport_tcp_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_template.la: $(libgnunet_plugin_transport_template_la_OBJECTS) $(libgnunet_plugin_transport_template_la_DEPENDENCIES) +libgnunet_plugin_transport_template.la: $(libgnunet_plugin_transport_template_la_OBJECTS) $(libgnunet_plugin_transport_template_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_template_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_transport_template_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_transport_template_la_OBJECTS) $(libgnunet_plugin_transport_template_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_udp.la: $(libgnunet_plugin_transport_udp_la_OBJECTS) $(libgnunet_plugin_transport_udp_la_DEPENDENCIES) +libgnunet_plugin_transport_udp.la: $(libgnunet_plugin_transport_udp_la_OBJECTS) $(libgnunet_plugin_transport_udp_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_udp_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_transport_udp_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_transport_udp_la_OBJECTS) $(libgnunet_plugin_transport_udp_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_unix.la: $(libgnunet_plugin_transport_unix_la_OBJECTS) $(libgnunet_plugin_transport_unix_la_DEPENDENCIES) +libgnunet_plugin_transport_unix.la: $(libgnunet_plugin_transport_unix_la_OBJECTS) $(libgnunet_plugin_transport_unix_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_unix_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_transport_unix_la_LINK) $(am_libgnunet_plugin_transport_unix_la_rpath) $(libgnunet_plugin_transport_unix_la_OBJECTS) $(libgnunet_plugin_transport_unix_la_LIBADD) $(LIBS) -libgnunet_plugin_transport_wlan.la: $(libgnunet_plugin_transport_wlan_la_OBJECTS) $(libgnunet_plugin_transport_wlan_la_DEPENDENCIES) +libgnunet_plugin_transport_wlan.la: $(libgnunet_plugin_transport_wlan_la_OBJECTS) $(libgnunet_plugin_transport_wlan_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_transport_wlan_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_transport_wlan_la_LINK) $(am_libgnunet_plugin_transport_wlan_la_rpath) $(libgnunet_plugin_transport_wlan_la_OBJECTS) $(libgnunet_plugin_transport_wlan_la_LIBADD) $(LIBS) -libgnunettransport.la: $(libgnunettransport_la_OBJECTS) $(libgnunettransport_la_DEPENDENCIES) +libgnunettransport.la: $(libgnunettransport_la_OBJECTS) $(libgnunettransport_la_DEPENDENCIES) $(EXTRA_libgnunettransport_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunettransport_la_LINK) -rpath $(libdir) $(libgnunettransport_la_OBJECTS) $(libgnunettransport_la_LIBADD) $(LIBS) -libgnunettransporttesting.la: $(libgnunettransporttesting_la_OBJECTS) $(libgnunettransporttesting_la_DEPENDENCIES) +libgnunettransporttesting.la: $(libgnunettransporttesting_la_OBJECTS) $(libgnunettransporttesting_la_DEPENDENCIES) $(EXTRA_libgnunettransporttesting_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunettransporttesting_la_LINK) -rpath $(libdir) $(libgnunettransporttesting_la_OBJECTS) $(libgnunettransporttesting_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ @@ -2027,6 +2424,52 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + 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)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || 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)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_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-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ @@ -2036,156 +2479,195 @@ clean-noinstPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -gnunet-helper-transport-wlan$(EXEEXT): $(gnunet_helper_transport_wlan_OBJECTS) $(gnunet_helper_transport_wlan_DEPENDENCIES) +gnunet-helper-transport-wlan$(EXEEXT): $(gnunet_helper_transport_wlan_OBJECTS) $(gnunet_helper_transport_wlan_DEPENDENCIES) $(EXTRA_gnunet_helper_transport_wlan_DEPENDENCIES) @rm -f gnunet-helper-transport-wlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_helper_transport_wlan_OBJECTS) $(gnunet_helper_transport_wlan_LDADD) $(LIBS) -gnunet-helper-transport-wlan-dummy$(EXEEXT): $(gnunet_helper_transport_wlan_dummy_OBJECTS) $(gnunet_helper_transport_wlan_dummy_DEPENDENCIES) +gnunet-helper-transport-wlan-dummy$(EXEEXT): $(gnunet_helper_transport_wlan_dummy_OBJECTS) $(gnunet_helper_transport_wlan_dummy_DEPENDENCIES) $(EXTRA_gnunet_helper_transport_wlan_dummy_DEPENDENCIES) @rm -f gnunet-helper-transport-wlan-dummy$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_helper_transport_wlan_dummy_OBJECTS) $(gnunet_helper_transport_wlan_dummy_LDADD) $(LIBS) -gnunet-service-transport$(EXEEXT): $(gnunet_service_transport_OBJECTS) $(gnunet_service_transport_DEPENDENCIES) +gnunet-service-transport$(EXEEXT): $(gnunet_service_transport_OBJECTS) $(gnunet_service_transport_DEPENDENCIES) $(EXTRA_gnunet_service_transport_DEPENDENCIES) @rm -f gnunet-service-transport$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(gnunet_service_transport_OBJECTS) $(gnunet_service_transport_LDADD) $(LIBS) -gnunet-transport$(EXEEXT): $(gnunet_transport_OBJECTS) $(gnunet_transport_DEPENDENCIES) + $(AM_V_CCLD)$(gnunet_service_transport_LINK) $(gnunet_service_transport_OBJECTS) $(gnunet_service_transport_LDADD) $(LIBS) +gnunet-transport$(EXEEXT): $(gnunet_transport_OBJECTS) $(gnunet_transport_DEPENDENCIES) $(EXTRA_gnunet_transport_DEPENDENCIES) @rm -f gnunet-transport$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_transport_OBJECTS) $(gnunet_transport_LDADD) $(LIBS) -gnunet-transport-certificate-creation$(EXEEXT): $(gnunet_transport_certificate_creation_OBJECTS) $(gnunet_transport_certificate_creation_DEPENDENCIES) +gnunet-transport-certificate-creation$(EXEEXT): $(gnunet_transport_certificate_creation_OBJECTS) $(gnunet_transport_certificate_creation_DEPENDENCIES) $(EXTRA_gnunet_transport_certificate_creation_DEPENDENCIES) @rm -f gnunet-transport-certificate-creation$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_transport_certificate_creation_OBJECTS) $(gnunet_transport_certificate_creation_LDADD) $(LIBS) -gnunet-transport-wlan-sender$(EXEEXT): $(gnunet_transport_wlan_sender_OBJECTS) $(gnunet_transport_wlan_sender_DEPENDENCIES) +gnunet-transport-wlan-receiver$(EXEEXT): $(gnunet_transport_wlan_receiver_OBJECTS) $(gnunet_transport_wlan_receiver_DEPENDENCIES) $(EXTRA_gnunet_transport_wlan_receiver_DEPENDENCIES) + @rm -f gnunet-transport-wlan-receiver$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_transport_wlan_receiver_OBJECTS) $(gnunet_transport_wlan_receiver_LDADD) $(LIBS) +gnunet-transport-wlan-sender$(EXEEXT): $(gnunet_transport_wlan_sender_OBJECTS) $(gnunet_transport_wlan_sender_DEPENDENCIES) $(EXTRA_gnunet_transport_wlan_sender_DEPENDENCIES) @rm -f gnunet-transport-wlan-sender$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_transport_wlan_sender_OBJECTS) $(gnunet_transport_wlan_sender_LDADD) $(LIBS) -test_quota_compliance_http$(EXEEXT): $(test_quota_compliance_http_OBJECTS) $(test_quota_compliance_http_DEPENDENCIES) +test_http_common$(EXEEXT): $(test_http_common_OBJECTS) $(test_http_common_DEPENDENCIES) $(EXTRA_test_http_common_DEPENDENCIES) + @rm -f test_http_common$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_http_common_OBJECTS) $(test_http_common_LDADD) $(LIBS) +test_plugin_http_client$(EXEEXT): $(test_plugin_http_client_OBJECTS) $(test_plugin_http_client_DEPENDENCIES) $(EXTRA_test_plugin_http_client_DEPENDENCIES) + @rm -f test_plugin_http_client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_http_client_OBJECTS) $(test_plugin_http_client_LDADD) $(LIBS) +test_plugin_http_server$(EXEEXT): $(test_plugin_http_server_OBJECTS) $(test_plugin_http_server_DEPENDENCIES) $(EXTRA_test_plugin_http_server_DEPENDENCIES) + @rm -f test_plugin_http_server$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_http_server_OBJECTS) $(test_plugin_http_server_LDADD) $(LIBS) +test_plugin_https_client$(EXEEXT): $(test_plugin_https_client_OBJECTS) $(test_plugin_https_client_DEPENDENCIES) $(EXTRA_test_plugin_https_client_DEPENDENCIES) + @rm -f test_plugin_https_client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_https_client_OBJECTS) $(test_plugin_https_client_LDADD) $(LIBS) +test_plugin_https_server$(EXEEXT): $(test_plugin_https_server_OBJECTS) $(test_plugin_https_server_DEPENDENCIES) $(EXTRA_test_plugin_https_server_DEPENDENCIES) + @rm -f test_plugin_https_server$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_https_server_OBJECTS) $(test_plugin_https_server_LDADD) $(LIBS) +test_plugin_tcp$(EXEEXT): $(test_plugin_tcp_OBJECTS) $(test_plugin_tcp_DEPENDENCIES) $(EXTRA_test_plugin_tcp_DEPENDENCIES) + @rm -f test_plugin_tcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_tcp_OBJECTS) $(test_plugin_tcp_LDADD) $(LIBS) +test_plugin_udp$(EXEEXT): $(test_plugin_udp_OBJECTS) $(test_plugin_udp_DEPENDENCIES) $(EXTRA_test_plugin_udp_DEPENDENCIES) + @rm -f test_plugin_udp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_udp_OBJECTS) $(test_plugin_udp_LDADD) $(LIBS) +test_plugin_unix$(EXEEXT): $(test_plugin_unix_OBJECTS) $(test_plugin_unix_DEPENDENCIES) $(EXTRA_test_plugin_unix_DEPENDENCIES) + @rm -f test_plugin_unix$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_unix_OBJECTS) $(test_plugin_unix_LDADD) $(LIBS) +test_plugin_wlan$(EXEEXT): $(test_plugin_wlan_OBJECTS) $(test_plugin_wlan_DEPENDENCIES) $(EXTRA_test_plugin_wlan_DEPENDENCIES) + @rm -f test_plugin_wlan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_wlan_OBJECTS) $(test_plugin_wlan_LDADD) $(LIBS) +test_quota_compliance_http$(EXEEXT): $(test_quota_compliance_http_OBJECTS) $(test_quota_compliance_http_DEPENDENCIES) $(EXTRA_test_quota_compliance_http_DEPENDENCIES) @rm -f test_quota_compliance_http$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_http_OBJECTS) $(test_quota_compliance_http_LDADD) $(LIBS) -test_quota_compliance_http_asymmetric$(EXEEXT): $(test_quota_compliance_http_asymmetric_OBJECTS) $(test_quota_compliance_http_asymmetric_DEPENDENCIES) +test_quota_compliance_http_asymmetric$(EXEEXT): $(test_quota_compliance_http_asymmetric_OBJECTS) $(test_quota_compliance_http_asymmetric_DEPENDENCIES) $(EXTRA_test_quota_compliance_http_asymmetric_DEPENDENCIES) @rm -f test_quota_compliance_http_asymmetric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_http_asymmetric_OBJECTS) $(test_quota_compliance_http_asymmetric_LDADD) $(LIBS) -test_quota_compliance_https$(EXEEXT): $(test_quota_compliance_https_OBJECTS) $(test_quota_compliance_https_DEPENDENCIES) +test_quota_compliance_https$(EXEEXT): $(test_quota_compliance_https_OBJECTS) $(test_quota_compliance_https_DEPENDENCIES) $(EXTRA_test_quota_compliance_https_DEPENDENCIES) @rm -f test_quota_compliance_https$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_https_OBJECTS) $(test_quota_compliance_https_LDADD) $(LIBS) -test_quota_compliance_https_asymmetric$(EXEEXT): $(test_quota_compliance_https_asymmetric_OBJECTS) $(test_quota_compliance_https_asymmetric_DEPENDENCIES) +test_quota_compliance_https_asymmetric$(EXEEXT): $(test_quota_compliance_https_asymmetric_OBJECTS) $(test_quota_compliance_https_asymmetric_DEPENDENCIES) $(EXTRA_test_quota_compliance_https_asymmetric_DEPENDENCIES) @rm -f test_quota_compliance_https_asymmetric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_https_asymmetric_OBJECTS) $(test_quota_compliance_https_asymmetric_LDADD) $(LIBS) -test_quota_compliance_tcp$(EXEEXT): $(test_quota_compliance_tcp_OBJECTS) $(test_quota_compliance_tcp_DEPENDENCIES) +test_quota_compliance_tcp$(EXEEXT): $(test_quota_compliance_tcp_OBJECTS) $(test_quota_compliance_tcp_DEPENDENCIES) $(EXTRA_test_quota_compliance_tcp_DEPENDENCIES) @rm -f test_quota_compliance_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_tcp_OBJECTS) $(test_quota_compliance_tcp_LDADD) $(LIBS) -test_quota_compliance_tcp_asymmetric$(EXEEXT): $(test_quota_compliance_tcp_asymmetric_OBJECTS) $(test_quota_compliance_tcp_asymmetric_DEPENDENCIES) +test_quota_compliance_tcp_asymmetric$(EXEEXT): $(test_quota_compliance_tcp_asymmetric_OBJECTS) $(test_quota_compliance_tcp_asymmetric_DEPENDENCIES) $(EXTRA_test_quota_compliance_tcp_asymmetric_DEPENDENCIES) @rm -f test_quota_compliance_tcp_asymmetric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_tcp_asymmetric_OBJECTS) $(test_quota_compliance_tcp_asymmetric_LDADD) $(LIBS) -test_quota_compliance_udp$(EXEEXT): $(test_quota_compliance_udp_OBJECTS) $(test_quota_compliance_udp_DEPENDENCIES) +test_quota_compliance_udp$(EXEEXT): $(test_quota_compliance_udp_OBJECTS) $(test_quota_compliance_udp_DEPENDENCIES) $(EXTRA_test_quota_compliance_udp_DEPENDENCIES) @rm -f test_quota_compliance_udp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_udp_OBJECTS) $(test_quota_compliance_udp_LDADD) $(LIBS) -test_quota_compliance_unix$(EXEEXT): $(test_quota_compliance_unix_OBJECTS) $(test_quota_compliance_unix_DEPENDENCIES) +test_quota_compliance_unix$(EXEEXT): $(test_quota_compliance_unix_OBJECTS) $(test_quota_compliance_unix_DEPENDENCIES) $(EXTRA_test_quota_compliance_unix_DEPENDENCIES) @rm -f test_quota_compliance_unix$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_unix_OBJECTS) $(test_quota_compliance_unix_LDADD) $(LIBS) -test_quota_compliance_unix_asymmetric$(EXEEXT): $(test_quota_compliance_unix_asymmetric_OBJECTS) $(test_quota_compliance_unix_asymmetric_DEPENDENCIES) +test_quota_compliance_unix_asymmetric$(EXEEXT): $(test_quota_compliance_unix_asymmetric_OBJECTS) $(test_quota_compliance_unix_asymmetric_DEPENDENCIES) $(EXTRA_test_quota_compliance_unix_asymmetric_DEPENDENCIES) @rm -f test_quota_compliance_unix_asymmetric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_quota_compliance_unix_asymmetric_OBJECTS) $(test_quota_compliance_unix_asymmetric_LDADD) $(LIBS) -test_transport_api_bidirectional_connect$(EXEEXT): $(test_transport_api_bidirectional_connect_OBJECTS) $(test_transport_api_bidirectional_connect_DEPENDENCIES) +test_quota_compliance_wlan$(EXEEXT): $(test_quota_compliance_wlan_OBJECTS) $(test_quota_compliance_wlan_DEPENDENCIES) $(EXTRA_test_quota_compliance_wlan_DEPENDENCIES) + @rm -f test_quota_compliance_wlan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_quota_compliance_wlan_OBJECTS) $(test_quota_compliance_wlan_LDADD) $(LIBS) +test_quota_compliance_wlan_asymmetric$(EXEEXT): $(test_quota_compliance_wlan_asymmetric_OBJECTS) $(test_quota_compliance_wlan_asymmetric_DEPENDENCIES) $(EXTRA_test_quota_compliance_wlan_asymmetric_DEPENDENCIES) + @rm -f test_quota_compliance_wlan_asymmetric$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_quota_compliance_wlan_asymmetric_OBJECTS) $(test_quota_compliance_wlan_asymmetric_LDADD) $(LIBS) +test_transport_api_bidirectional_connect$(EXEEXT): $(test_transport_api_bidirectional_connect_OBJECTS) $(test_transport_api_bidirectional_connect_DEPENDENCIES) $(EXTRA_test_transport_api_bidirectional_connect_DEPENDENCIES) @rm -f test_transport_api_bidirectional_connect$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_bidirectional_connect_OBJECTS) $(test_transport_api_bidirectional_connect_LDADD) $(LIBS) -test_transport_api_blacklisting$(EXEEXT): $(test_transport_api_blacklisting_OBJECTS) $(test_transport_api_blacklisting_DEPENDENCIES) +test_transport_api_blacklisting$(EXEEXT): $(test_transport_api_blacklisting_OBJECTS) $(test_transport_api_blacklisting_DEPENDENCIES) $(EXTRA_test_transport_api_blacklisting_DEPENDENCIES) @rm -f test_transport_api_blacklisting$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_blacklisting_OBJECTS) $(test_transport_api_blacklisting_LDADD) $(LIBS) -test_transport_api_disconnect_tcp$(EXEEXT): $(test_transport_api_disconnect_tcp_OBJECTS) $(test_transport_api_disconnect_tcp_DEPENDENCIES) +test_transport_api_disconnect_tcp$(EXEEXT): $(test_transport_api_disconnect_tcp_OBJECTS) $(test_transport_api_disconnect_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_disconnect_tcp_DEPENDENCIES) @rm -f test_transport_api_disconnect_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_disconnect_tcp_OBJECTS) $(test_transport_api_disconnect_tcp_LDADD) $(LIBS) -test_transport_api_http$(EXEEXT): $(test_transport_api_http_OBJECTS) $(test_transport_api_http_DEPENDENCIES) +test_transport_api_http$(EXEEXT): $(test_transport_api_http_OBJECTS) $(test_transport_api_http_DEPENDENCIES) $(EXTRA_test_transport_api_http_DEPENDENCIES) @rm -f test_transport_api_http$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_http_OBJECTS) $(test_transport_api_http_LDADD) $(LIBS) -test_transport_api_http_nat$(EXEEXT): $(test_transport_api_http_nat_OBJECTS) $(test_transport_api_http_nat_DEPENDENCIES) - @rm -f test_transport_api_http_nat$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_transport_api_http_nat_OBJECTS) $(test_transport_api_http_nat_LDADD) $(LIBS) -test_transport_api_https$(EXEEXT): $(test_transport_api_https_OBJECTS) $(test_transport_api_https_DEPENDENCIES) +test_transport_api_http_reverse$(EXEEXT): $(test_transport_api_http_reverse_OBJECTS) $(test_transport_api_http_reverse_DEPENDENCIES) $(EXTRA_test_transport_api_http_reverse_DEPENDENCIES) + @rm -f test_transport_api_http_reverse$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_transport_api_http_reverse_OBJECTS) $(test_transport_api_http_reverse_LDADD) $(LIBS) +test_transport_api_https$(EXEEXT): $(test_transport_api_https_OBJECTS) $(test_transport_api_https_DEPENDENCIES) $(EXTRA_test_transport_api_https_DEPENDENCIES) @rm -f test_transport_api_https$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_https_OBJECTS) $(test_transport_api_https_LDADD) $(LIBS) -test_transport_api_https_nat$(EXEEXT): $(test_transport_api_https_nat_OBJECTS) $(test_transport_api_https_nat_DEPENDENCIES) - @rm -f test_transport_api_https_nat$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_transport_api_https_nat_OBJECTS) $(test_transport_api_https_nat_LDADD) $(LIBS) -test_transport_api_limited_sockets_tcp$(EXEEXT): $(test_transport_api_limited_sockets_tcp_OBJECTS) $(test_transport_api_limited_sockets_tcp_DEPENDENCIES) +test_transport_api_limited_sockets_tcp$(EXEEXT): $(test_transport_api_limited_sockets_tcp_OBJECTS) $(test_transport_api_limited_sockets_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_limited_sockets_tcp_DEPENDENCIES) @rm -f test_transport_api_limited_sockets_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_limited_sockets_tcp_OBJECTS) $(test_transport_api_limited_sockets_tcp_LDADD) $(LIBS) -test_transport_api_multi$(EXEEXT): $(test_transport_api_multi_OBJECTS) $(test_transport_api_multi_DEPENDENCIES) +test_transport_api_manipulation_recv_tcp$(EXEEXT): $(test_transport_api_manipulation_recv_tcp_OBJECTS) $(test_transport_api_manipulation_recv_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_manipulation_recv_tcp_DEPENDENCIES) + @rm -f test_transport_api_manipulation_recv_tcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_transport_api_manipulation_recv_tcp_OBJECTS) $(test_transport_api_manipulation_recv_tcp_LDADD) $(LIBS) +test_transport_api_manipulation_send_tcp$(EXEEXT): $(test_transport_api_manipulation_send_tcp_OBJECTS) $(test_transport_api_manipulation_send_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_manipulation_send_tcp_DEPENDENCIES) + @rm -f test_transport_api_manipulation_send_tcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_transport_api_manipulation_send_tcp_OBJECTS) $(test_transport_api_manipulation_send_tcp_LDADD) $(LIBS) +test_transport_api_multi$(EXEEXT): $(test_transport_api_multi_OBJECTS) $(test_transport_api_multi_DEPENDENCIES) $(EXTRA_test_transport_api_multi_DEPENDENCIES) @rm -f test_transport_api_multi$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_multi_OBJECTS) $(test_transport_api_multi_LDADD) $(LIBS) -test_transport_api_reliability_http$(EXEEXT): $(test_transport_api_reliability_http_OBJECTS) $(test_transport_api_reliability_http_DEPENDENCIES) +test_transport_api_reliability_http$(EXEEXT): $(test_transport_api_reliability_http_OBJECTS) $(test_transport_api_reliability_http_DEPENDENCIES) $(EXTRA_test_transport_api_reliability_http_DEPENDENCIES) @rm -f test_transport_api_reliability_http$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_http_OBJECTS) $(test_transport_api_reliability_http_LDADD) $(LIBS) -test_transport_api_reliability_http_nat$(EXEEXT): $(test_transport_api_reliability_http_nat_OBJECTS) $(test_transport_api_reliability_http_nat_DEPENDENCIES) - @rm -f test_transport_api_reliability_http_nat$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_http_nat_OBJECTS) $(test_transport_api_reliability_http_nat_LDADD) $(LIBS) -test_transport_api_reliability_https$(EXEEXT): $(test_transport_api_reliability_https_OBJECTS) $(test_transport_api_reliability_https_DEPENDENCIES) +test_transport_api_reliability_https$(EXEEXT): $(test_transport_api_reliability_https_OBJECTS) $(test_transport_api_reliability_https_DEPENDENCIES) $(EXTRA_test_transport_api_reliability_https_DEPENDENCIES) @rm -f test_transport_api_reliability_https$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_https_OBJECTS) $(test_transport_api_reliability_https_LDADD) $(LIBS) -test_transport_api_reliability_https_nat$(EXEEXT): $(test_transport_api_reliability_https_nat_OBJECTS) $(test_transport_api_reliability_https_nat_DEPENDENCIES) - @rm -f test_transport_api_reliability_https_nat$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_https_nat_OBJECTS) $(test_transport_api_reliability_https_nat_LDADD) $(LIBS) -test_transport_api_reliability_tcp$(EXEEXT): $(test_transport_api_reliability_tcp_OBJECTS) $(test_transport_api_reliability_tcp_DEPENDENCIES) +test_transport_api_reliability_tcp$(EXEEXT): $(test_transport_api_reliability_tcp_OBJECTS) $(test_transport_api_reliability_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_reliability_tcp_DEPENDENCIES) @rm -f test_transport_api_reliability_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_tcp_OBJECTS) $(test_transport_api_reliability_tcp_LDADD) $(LIBS) -test_transport_api_reliability_tcp_nat$(EXEEXT): $(test_transport_api_reliability_tcp_nat_OBJECTS) $(test_transport_api_reliability_tcp_nat_DEPENDENCIES) +test_transport_api_reliability_tcp_nat$(EXEEXT): $(test_transport_api_reliability_tcp_nat_OBJECTS) $(test_transport_api_reliability_tcp_nat_DEPENDENCIES) $(EXTRA_test_transport_api_reliability_tcp_nat_DEPENDENCIES) @rm -f test_transport_api_reliability_tcp_nat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_tcp_nat_OBJECTS) $(test_transport_api_reliability_tcp_nat_LDADD) $(LIBS) -test_transport_api_reliability_wlan$(EXEEXT): $(test_transport_api_reliability_wlan_OBJECTS) $(test_transport_api_reliability_wlan_DEPENDENCIES) +test_transport_api_reliability_wlan$(EXEEXT): $(test_transport_api_reliability_wlan_OBJECTS) $(test_transport_api_reliability_wlan_DEPENDENCIES) $(EXTRA_test_transport_api_reliability_wlan_DEPENDENCIES) @rm -f test_transport_api_reliability_wlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_reliability_wlan_OBJECTS) $(test_transport_api_reliability_wlan_LDADD) $(LIBS) -test_transport_api_restart_1peer$(EXEEXT): $(test_transport_api_restart_1peer_OBJECTS) $(test_transport_api_restart_1peer_DEPENDENCIES) +test_transport_api_restart_1peer$(EXEEXT): $(test_transport_api_restart_1peer_OBJECTS) $(test_transport_api_restart_1peer_DEPENDENCIES) $(EXTRA_test_transport_api_restart_1peer_DEPENDENCIES) @rm -f test_transport_api_restart_1peer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_restart_1peer_OBJECTS) $(test_transport_api_restart_1peer_LDADD) $(LIBS) -test_transport_api_restart_2peers$(EXEEXT): $(test_transport_api_restart_2peers_OBJECTS) $(test_transport_api_restart_2peers_DEPENDENCIES) +test_transport_api_restart_2peers$(EXEEXT): $(test_transport_api_restart_2peers_OBJECTS) $(test_transport_api_restart_2peers_DEPENDENCIES) $(EXTRA_test_transport_api_restart_2peers_DEPENDENCIES) @rm -f test_transport_api_restart_2peers$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_restart_2peers_OBJECTS) $(test_transport_api_restart_2peers_LDADD) $(LIBS) -test_transport_api_tcp$(EXEEXT): $(test_transport_api_tcp_OBJECTS) $(test_transport_api_tcp_DEPENDENCIES) +test_transport_api_tcp$(EXEEXT): $(test_transport_api_tcp_OBJECTS) $(test_transport_api_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_tcp_DEPENDENCIES) @rm -f test_transport_api_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_tcp_OBJECTS) $(test_transport_api_tcp_LDADD) $(LIBS) -test_transport_api_tcp_nat$(EXEEXT): $(test_transport_api_tcp_nat_OBJECTS) $(test_transport_api_tcp_nat_DEPENDENCIES) +test_transport_api_tcp_nat$(EXEEXT): $(test_transport_api_tcp_nat_OBJECTS) $(test_transport_api_tcp_nat_DEPENDENCIES) $(EXTRA_test_transport_api_tcp_nat_DEPENDENCIES) @rm -f test_transport_api_tcp_nat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_tcp_nat_OBJECTS) $(test_transport_api_tcp_nat_LDADD) $(LIBS) -test_transport_api_timeout_http$(EXEEXT): $(test_transport_api_timeout_http_OBJECTS) $(test_transport_api_timeout_http_DEPENDENCIES) +test_transport_api_timeout_http$(EXEEXT): $(test_transport_api_timeout_http_OBJECTS) $(test_transport_api_timeout_http_DEPENDENCIES) $(EXTRA_test_transport_api_timeout_http_DEPENDENCIES) @rm -f test_transport_api_timeout_http$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_timeout_http_OBJECTS) $(test_transport_api_timeout_http_LDADD) $(LIBS) -test_transport_api_timeout_https$(EXEEXT): $(test_transport_api_timeout_https_OBJECTS) $(test_transport_api_timeout_https_DEPENDENCIES) +test_transport_api_timeout_https$(EXEEXT): $(test_transport_api_timeout_https_OBJECTS) $(test_transport_api_timeout_https_DEPENDENCIES) $(EXTRA_test_transport_api_timeout_https_DEPENDENCIES) @rm -f test_transport_api_timeout_https$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_timeout_https_OBJECTS) $(test_transport_api_timeout_https_LDADD) $(LIBS) -test_transport_api_timeout_tcp$(EXEEXT): $(test_transport_api_timeout_tcp_OBJECTS) $(test_transport_api_timeout_tcp_DEPENDENCIES) +test_transport_api_timeout_tcp$(EXEEXT): $(test_transport_api_timeout_tcp_OBJECTS) $(test_transport_api_timeout_tcp_DEPENDENCIES) $(EXTRA_test_transport_api_timeout_tcp_DEPENDENCIES) @rm -f test_transport_api_timeout_tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_timeout_tcp_OBJECTS) $(test_transport_api_timeout_tcp_LDADD) $(LIBS) -test_transport_api_timeout_udp$(EXEEXT): $(test_transport_api_timeout_udp_OBJECTS) $(test_transport_api_timeout_udp_DEPENDENCIES) +test_transport_api_timeout_udp$(EXEEXT): $(test_transport_api_timeout_udp_OBJECTS) $(test_transport_api_timeout_udp_DEPENDENCIES) $(EXTRA_test_transport_api_timeout_udp_DEPENDENCIES) @rm -f test_transport_api_timeout_udp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_timeout_udp_OBJECTS) $(test_transport_api_timeout_udp_LDADD) $(LIBS) -test_transport_api_timeout_unix$(EXEEXT): $(test_transport_api_timeout_unix_OBJECTS) $(test_transport_api_timeout_unix_DEPENDENCIES) +test_transport_api_timeout_unix$(EXEEXT): $(test_transport_api_timeout_unix_OBJECTS) $(test_transport_api_timeout_unix_DEPENDENCIES) $(EXTRA_test_transport_api_timeout_unix_DEPENDENCIES) @rm -f test_transport_api_timeout_unix$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_timeout_unix_OBJECTS) $(test_transport_api_timeout_unix_LDADD) $(LIBS) -test_transport_api_udp$(EXEEXT): $(test_transport_api_udp_OBJECTS) $(test_transport_api_udp_DEPENDENCIES) +test_transport_api_udp$(EXEEXT): $(test_transport_api_udp_OBJECTS) $(test_transport_api_udp_DEPENDENCIES) $(EXTRA_test_transport_api_udp_DEPENDENCIES) @rm -f test_transport_api_udp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_udp_OBJECTS) $(test_transport_api_udp_LDADD) $(LIBS) -test_transport_api_udp_nat$(EXEEXT): $(test_transport_api_udp_nat_OBJECTS) $(test_transport_api_udp_nat_DEPENDENCIES) +test_transport_api_udp_nat$(EXEEXT): $(test_transport_api_udp_nat_OBJECTS) $(test_transport_api_udp_nat_DEPENDENCIES) $(EXTRA_test_transport_api_udp_nat_DEPENDENCIES) @rm -f test_transport_api_udp_nat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_udp_nat_OBJECTS) $(test_transport_api_udp_nat_LDADD) $(LIBS) -test_transport_api_unix$(EXEEXT): $(test_transport_api_unix_OBJECTS) $(test_transport_api_unix_DEPENDENCIES) +test_transport_api_unix$(EXEEXT): $(test_transport_api_unix_OBJECTS) $(test_transport_api_unix_DEPENDENCIES) $(EXTRA_test_transport_api_unix_DEPENDENCIES) @rm -f test_transport_api_unix$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_unix_OBJECTS) $(test_transport_api_unix_LDADD) $(LIBS) -test_transport_api_unreliability_constant_udp$(EXEEXT): $(test_transport_api_unreliability_constant_udp_OBJECTS) $(test_transport_api_unreliability_constant_udp_DEPENDENCIES) +test_transport_api_unreliability_constant_udp$(EXEEXT): $(test_transport_api_unreliability_constant_udp_OBJECTS) $(test_transport_api_unreliability_constant_udp_DEPENDENCIES) $(EXTRA_test_transport_api_unreliability_constant_udp_DEPENDENCIES) @rm -f test_transport_api_unreliability_constant_udp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_unreliability_constant_udp_OBJECTS) $(test_transport_api_unreliability_constant_udp_LDADD) $(LIBS) -test_transport_api_unreliability_udp$(EXEEXT): $(test_transport_api_unreliability_udp_OBJECTS) $(test_transport_api_unreliability_udp_DEPENDENCIES) +test_transport_api_unreliability_udp$(EXEEXT): $(test_transport_api_unreliability_udp_OBJECTS) $(test_transport_api_unreliability_udp_DEPENDENCIES) $(EXTRA_test_transport_api_unreliability_udp_DEPENDENCIES) @rm -f test_transport_api_unreliability_udp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_unreliability_udp_OBJECTS) $(test_transport_api_unreliability_udp_LDADD) $(LIBS) -test_transport_api_unreliability_unix$(EXEEXT): $(test_transport_api_unreliability_unix_OBJECTS) $(test_transport_api_unreliability_unix_DEPENDENCIES) +test_transport_api_unreliability_unix$(EXEEXT): $(test_transport_api_unreliability_unix_OBJECTS) $(test_transport_api_unreliability_unix_DEPENDENCIES) $(EXTRA_test_transport_api_unreliability_unix_DEPENDENCIES) @rm -f test_transport_api_unreliability_unix$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_unreliability_unix_OBJECTS) $(test_transport_api_unreliability_unix_LDADD) $(LIBS) -test_transport_api_unreliability_wlan$(EXEEXT): $(test_transport_api_unreliability_wlan_OBJECTS) $(test_transport_api_unreliability_wlan_DEPENDENCIES) +test_transport_api_unreliability_wlan$(EXEEXT): $(test_transport_api_unreliability_wlan_OBJECTS) $(test_transport_api_unreliability_wlan_DEPENDENCIES) $(EXTRA_test_transport_api_unreliability_wlan_DEPENDENCIES) @rm -f test_transport_api_unreliability_wlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_unreliability_wlan_OBJECTS) $(test_transport_api_unreliability_wlan_LDADD) $(LIBS) -test_transport_api_wlan$(EXEEXT): $(test_transport_api_wlan_OBJECTS) $(test_transport_api_wlan_DEPENDENCIES) +test_transport_api_wlan$(EXEEXT): $(test_transport_api_wlan_OBJECTS) $(test_transport_api_wlan_DEPENDENCIES) $(EXTRA_test_transport_api_wlan_DEPENDENCIES) @rm -f test_transport_api_wlan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_api_wlan_OBJECTS) $(test_transport_api_wlan_LDADD) $(LIBS) -test_transport_startonly$(EXEEXT): $(test_transport_startonly_OBJECTS) $(test_transport_startonly_DEPENDENCIES) +test_transport_startonly$(EXEEXT): $(test_transport_startonly_OBJECTS) $(test_transport_startonly_DEPENDENCIES) $(EXTRA_test_transport_startonly_DEPENDENCIES) @rm -f test_transport_startonly$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_startonly_OBJECTS) $(test_transport_startonly_LDADD) $(LIBS) -test_transport_testing$(EXEEXT): $(test_transport_testing_OBJECTS) $(test_transport_testing_DEPENDENCIES) +test_transport_testing$(EXEEXT): $(test_transport_testing_OBJECTS) $(test_transport_testing_DEPENDENCIES) $(EXTRA_test_transport_testing_DEPENDENCIES) @rm -f test_transport_testing$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_transport_testing_OBJECTS) $(test_transport_testing_LDADD) $(LIBS) +test_transport_testing_restart$(EXEEXT): $(test_transport_testing_restart_OBJECTS) $(test_transport_testing_restart_DEPENDENCIES) $(EXTRA_test_transport_testing_restart_DEPENDENCIES) + @rm -f test_transport_testing_restart$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_transport_testing_restart_OBJECTS) $(test_transport_testing_restart_LDADD) $(LIBS) +test_transport_testing_startstop$(EXEEXT): $(test_transport_testing_startstop_OBJECTS) $(test_transport_testing_startstop_DEPENDENCIES) $(EXTRA_test_transport_testing_startstop_DEPENDENCIES) + @rm -f test_transport_testing_startstop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_transport_testing_startstop_OBJECTS) $(test_transport_testing_startstop_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -2195,34 +2677,43 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-helper-transport-wlan-dummy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-helper-transport-wlan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_blacklist.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_clients.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_hello.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_neighbours.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_plugins.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-transport_validation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-transport-certificate-creation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-transport-wlan-receiver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-transport-wlan-sender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-transport.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_server.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_http_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_tcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_template.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_udp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_udp_broadcasting.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_unix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_transport_wlan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_http_common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_transport.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_quota_compliance.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_bidirectional_connect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_blacklisting.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_disconnect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_limited_sockets.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_manipulation_recv_tcp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_manipulation_send_tcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_reliability.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_restart_1peer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_restart_2peers.Po@am__quote@ @@ -2231,6 +2722,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_api_unreliability_constant.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_startonly.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_testing.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_testing_restart.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_transport_testing_startstop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transport-testing.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transport_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transport_api_address_lookup.Plo@am__quote@ @@ -2240,74 +2733,191 @@ distclean-compile: .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@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo: plugin_transport_http_client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_client_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.Tpo -c -o libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_client.c' object='libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_client_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_client_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c + +libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo: plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_client_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.Tpo -c -o libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_common.c' object='libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_client_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_client_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c + +libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo: plugin_transport_http_server.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) $(libgnunet_plugin_transport_http_server_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.Tpo -c -o libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_server.c' object='libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_server_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_server_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c + +libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo: plugin_transport_http_common.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) $(libgnunet_plugin_transport_http_server_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.Tpo -c -o libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_common.c' object='libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_server_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_server_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c + +libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo: plugin_transport_http_client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_client_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.Tpo -c -o libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_client.c' object='libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_client_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_client_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c + +libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo: plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_client_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.Tpo -c -o libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_common.c' object='libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_client_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_client_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_client_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c -libgnunet_plugin_transport_http_la-plugin_transport_http.lo: plugin_transport_http.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_la-plugin_transport_http.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http.Tpo -c -o libgnunet_plugin_transport_http_la-plugin_transport_http.lo `test -f 'plugin_transport_http.c' || echo '$(srcdir)/'`plugin_transport_http.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http.c' object='libgnunet_plugin_transport_http_la-plugin_transport_http.lo' libtool=yes @AMDEPBACKSLASH@ +libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.lo: plugin_transport_http_server.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) $(libgnunet_plugin_transport_https_server_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.Tpo -c -o libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_server.c' object='libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.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) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_la-plugin_transport_http.lo `test -f 'plugin_transport_http.c' || echo '$(srcdir)/'`plugin_transport_http.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_server_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_server_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c -libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo: plugin_transport_http_client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_client.Tpo -c -o libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_client.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_client.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http_client.c' object='libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo' libtool=yes @AMDEPBACKSLASH@ +libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.lo: plugin_transport_http_common.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) $(libgnunet_plugin_transport_https_server_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.Tpo -c -o libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin_transport_http_common.c' object='libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.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) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_server_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_server_la-plugin_transport_http_common.lo `test -f 'plugin_transport_http_common.c' || echo '$(srcdir)/'`plugin_transport_http_common.c -libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo: plugin_transport_http_server.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_server.Tpo -c -o libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_server.Tpo $(DEPDIR)/libgnunet_plugin_transport_http_la-plugin_transport_http_server.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http_server.c' object='libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo' libtool=yes @AMDEPBACKSLASH@ +gnunet_service_transport-gnunet-service-transport.o: gnunet-service-transport.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Tpo -c -o gnunet_service_transport-gnunet-service-transport.o `test -f 'gnunet-service-transport.c' || echo '$(srcdir)/'`gnunet-service-transport.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport.c' object='gnunet_service_transport-gnunet-service-transport.o' libtool=no @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) $(libgnunet_plugin_transport_http_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_http_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_http_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport.o `test -f 'gnunet-service-transport.c' || echo '$(srcdir)/'`gnunet-service-transport.c -libgnunet_plugin_transport_https_la-plugin_transport_http.lo: plugin_transport_http.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_la-plugin_transport_http.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http.Tpo -c -o libgnunet_plugin_transport_https_la-plugin_transport_http.lo `test -f 'plugin_transport_http.c' || echo '$(srcdir)/'`plugin_transport_http.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http.c' object='libgnunet_plugin_transport_https_la-plugin_transport_http.lo' libtool=yes @AMDEPBACKSLASH@ +gnunet_service_transport-gnunet-service-transport.obj: gnunet-service-transport.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Tpo -c -o gnunet_service_transport-gnunet-service-transport.obj `if test -f 'gnunet-service-transport.c'; then $(CYGPATH_W) 'gnunet-service-transport.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport.c' object='gnunet_service_transport-gnunet-service-transport.obj' libtool=no @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) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_la-plugin_transport_http.lo `test -f 'plugin_transport_http.c' || echo '$(srcdir)/'`plugin_transport_http.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport.obj `if test -f 'gnunet-service-transport.c'; then $(CYGPATH_W) 'gnunet-service-transport.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport.c'; fi` -libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo: plugin_transport_http_client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_client.Tpo -c -o libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_client.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_client.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http_client.c' object='libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo' libtool=yes @AMDEPBACKSLASH@ +gnunet_service_transport-gnunet-service-transport_blacklist.o: gnunet-service-transport_blacklist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_blacklist.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Tpo -c -o gnunet_service_transport-gnunet-service-transport_blacklist.o `test -f 'gnunet-service-transport_blacklist.c' || echo '$(srcdir)/'`gnunet-service-transport_blacklist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_blacklist.c' object='gnunet_service_transport-gnunet-service-transport_blacklist.o' libtool=no @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) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_la-plugin_transport_http_client.lo `test -f 'plugin_transport_http_client.c' || echo '$(srcdir)/'`plugin_transport_http_client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_blacklist.o `test -f 'gnunet-service-transport_blacklist.c' || echo '$(srcdir)/'`gnunet-service-transport_blacklist.c -libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo: plugin_transport_http_server.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -MT libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo -MD -MP -MF $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_server.Tpo -c -o libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_server.Tpo $(DEPDIR)/libgnunet_plugin_transport_https_la-plugin_transport_http_server.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin_transport_http_server.c' object='libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo' libtool=yes @AMDEPBACKSLASH@ +gnunet_service_transport-gnunet-service-transport_blacklist.obj: gnunet-service-transport_blacklist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_blacklist.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Tpo -c -o gnunet_service_transport-gnunet-service-transport_blacklist.obj `if test -f 'gnunet-service-transport_blacklist.c'; then $(CYGPATH_W) 'gnunet-service-transport_blacklist.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_blacklist.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_blacklist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_blacklist.c' object='gnunet_service_transport-gnunet-service-transport_blacklist.obj' libtool=no @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) $(libgnunet_plugin_transport_https_la_CPPFLAGS) $(CPPFLAGS) $(libgnunet_plugin_transport_https_la_CFLAGS) $(CFLAGS) -c -o libgnunet_plugin_transport_https_la-plugin_transport_http_server.lo `test -f 'plugin_transport_http_server.c' || echo '$(srcdir)/'`plugin_transport_http_server.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_blacklist.obj `if test -f 'gnunet-service-transport_blacklist.c'; then $(CYGPATH_W) 'gnunet-service-transport_blacklist.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_blacklist.c'; fi` + +gnunet_service_transport-gnunet-service-transport_clients.o: gnunet-service-transport_clients.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_clients.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Tpo -c -o gnunet_service_transport-gnunet-service-transport_clients.o `test -f 'gnunet-service-transport_clients.c' || echo '$(srcdir)/'`gnunet-service-transport_clients.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_clients.c' object='gnunet_service_transport-gnunet-service-transport_clients.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_clients.o `test -f 'gnunet-service-transport_clients.c' || echo '$(srcdir)/'`gnunet-service-transport_clients.c + +gnunet_service_transport-gnunet-service-transport_clients.obj: gnunet-service-transport_clients.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_clients.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Tpo -c -o gnunet_service_transport-gnunet-service-transport_clients.obj `if test -f 'gnunet-service-transport_clients.c'; then $(CYGPATH_W) 'gnunet-service-transport_clients.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_clients.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_clients.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_clients.c' object='gnunet_service_transport-gnunet-service-transport_clients.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_clients.obj `if test -f 'gnunet-service-transport_clients.c'; then $(CYGPATH_W) 'gnunet-service-transport_clients.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_clients.c'; fi` + +gnunet_service_transport-gnunet-service-transport_hello.o: gnunet-service-transport_hello.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_hello.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Tpo -c -o gnunet_service_transport-gnunet-service-transport_hello.o `test -f 'gnunet-service-transport_hello.c' || echo '$(srcdir)/'`gnunet-service-transport_hello.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_hello.c' object='gnunet_service_transport-gnunet-service-transport_hello.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_hello.o `test -f 'gnunet-service-transport_hello.c' || echo '$(srcdir)/'`gnunet-service-transport_hello.c + +gnunet_service_transport-gnunet-service-transport_hello.obj: gnunet-service-transport_hello.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_hello.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Tpo -c -o gnunet_service_transport-gnunet-service-transport_hello.obj `if test -f 'gnunet-service-transport_hello.c'; then $(CYGPATH_W) 'gnunet-service-transport_hello.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_hello.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_hello.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_hello.c' object='gnunet_service_transport-gnunet-service-transport_hello.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_hello.obj `if test -f 'gnunet-service-transport_hello.c'; then $(CYGPATH_W) 'gnunet-service-transport_hello.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_hello.c'; fi` + +gnunet_service_transport-gnunet-service-transport_neighbours.o: gnunet-service-transport_neighbours.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_neighbours.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Tpo -c -o gnunet_service_transport-gnunet-service-transport_neighbours.o `test -f 'gnunet-service-transport_neighbours.c' || echo '$(srcdir)/'`gnunet-service-transport_neighbours.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_neighbours.c' object='gnunet_service_transport-gnunet-service-transport_neighbours.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_neighbours.o `test -f 'gnunet-service-transport_neighbours.c' || echo '$(srcdir)/'`gnunet-service-transport_neighbours.c + +gnunet_service_transport-gnunet-service-transport_neighbours.obj: gnunet-service-transport_neighbours.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_neighbours.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Tpo -c -o gnunet_service_transport-gnunet-service-transport_neighbours.obj `if test -f 'gnunet-service-transport_neighbours.c'; then $(CYGPATH_W) 'gnunet-service-transport_neighbours.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_neighbours.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_neighbours.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_neighbours.c' object='gnunet_service_transport-gnunet-service-transport_neighbours.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_neighbours.obj `if test -f 'gnunet-service-transport_neighbours.c'; then $(CYGPATH_W) 'gnunet-service-transport_neighbours.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_neighbours.c'; fi` + +gnunet_service_transport-gnunet-service-transport_plugins.o: gnunet-service-transport_plugins.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_plugins.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Tpo -c -o gnunet_service_transport-gnunet-service-transport_plugins.o `test -f 'gnunet-service-transport_plugins.c' || echo '$(srcdir)/'`gnunet-service-transport_plugins.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_plugins.c' object='gnunet_service_transport-gnunet-service-transport_plugins.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_plugins.o `test -f 'gnunet-service-transport_plugins.c' || echo '$(srcdir)/'`gnunet-service-transport_plugins.c + +gnunet_service_transport-gnunet-service-transport_plugins.obj: gnunet-service-transport_plugins.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_plugins.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Tpo -c -o gnunet_service_transport-gnunet-service-transport_plugins.obj `if test -f 'gnunet-service-transport_plugins.c'; then $(CYGPATH_W) 'gnunet-service-transport_plugins.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_plugins.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_plugins.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_plugins.c' object='gnunet_service_transport-gnunet-service-transport_plugins.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_plugins.obj `if test -f 'gnunet-service-transport_plugins.c'; then $(CYGPATH_W) 'gnunet-service-transport_plugins.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_plugins.c'; fi` + +gnunet_service_transport-gnunet-service-transport_validation.o: gnunet-service-transport_validation.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_validation.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Tpo -c -o gnunet_service_transport-gnunet-service-transport_validation.o `test -f 'gnunet-service-transport_validation.c' || echo '$(srcdir)/'`gnunet-service-transport_validation.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_validation.c' object='gnunet_service_transport-gnunet-service-transport_validation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_validation.o `test -f 'gnunet-service-transport_validation.c' || echo '$(srcdir)/'`gnunet-service-transport_validation.c + +gnunet_service_transport-gnunet-service-transport_validation.obj: gnunet-service-transport_validation.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_validation.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Tpo -c -o gnunet_service_transport-gnunet-service-transport_validation.obj `if test -f 'gnunet-service-transport_validation.c'; then $(CYGPATH_W) 'gnunet-service-transport_validation.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_validation.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_validation.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_validation.c' object='gnunet_service_transport-gnunet-service-transport_validation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_validation.obj `if test -f 'gnunet-service-transport_validation.c'; then $(CYGPATH_W) 'gnunet-service-transport_validation.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_validation.c'; fi` + +gnunet_service_transport-gnunet-service-transport_manipulation.o: gnunet-service-transport_manipulation.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_manipulation.o -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Tpo -c -o gnunet_service_transport-gnunet-service-transport_manipulation.o `test -f 'gnunet-service-transport_manipulation.c' || echo '$(srcdir)/'`gnunet-service-transport_manipulation.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_manipulation.c' object='gnunet_service_transport-gnunet-service-transport_manipulation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_manipulation.o `test -f 'gnunet-service-transport_manipulation.c' || echo '$(srcdir)/'`gnunet-service-transport_manipulation.c + +gnunet_service_transport-gnunet-service-transport_manipulation.obj: gnunet-service-transport_manipulation.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -MT gnunet_service_transport-gnunet-service-transport_manipulation.obj -MD -MP -MF $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Tpo -c -o gnunet_service_transport-gnunet-service-transport_manipulation.obj `if test -f 'gnunet-service-transport_manipulation.c'; then $(CYGPATH_W) 'gnunet-service-transport_manipulation.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_manipulation.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Tpo $(DEPDIR)/gnunet_service_transport-gnunet-service-transport_manipulation.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-transport_manipulation.c' object='gnunet_service_transport-gnunet-service-transport_manipulation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_transport_CFLAGS) $(CFLAGS) -c -o gnunet_service_transport-gnunet-service-transport_manipulation.obj `if test -f 'gnunet-service-transport_manipulation.c'; then $(CYGPATH_W) 'gnunet-service-transport_manipulation.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-transport_manipulation.c'; fi` mostlyclean-libtool: -rm -f *.lo @@ -2316,8 +2926,11 @@ 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=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgcfgdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -2331,9 +2944,7 @@ 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 + dir='$(DESTDIR)$(pkgcfgdir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -2468,14 +3079,15 @@ check-TESTS: $(TESTS) fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ - echo "$$grn$$dashes"; \ + col="$$grn"; \ else \ - echo "$$red$$dashes"; \ + col="$$red"; \ fi; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes$$std"; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi @@ -2517,7 +3129,7 @@ all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -2530,10 +3142,15 @@ install-am: all-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 + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -2548,8 +3165,8 @@ maintainer-clean-generic: clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \ - clean-pluginLTLIBRARIES mostlyclean-am + clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -2575,7 +3192,8 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \ + install-libexecPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am @@ -2617,32 +3235,34 @@ ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES + uninstall-libexecPROGRAMS uninstall-pkgcfgDATA \ + uninstall-pluginLTLIBRARIES .MAKE: check-am install-am install-exec-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 clean-noinstPROGRAMS \ - 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-exec-hook \ - install-html install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool \ + clean-noinstPROGRAMS 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-exec-hook install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-libexecPROGRAMS 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 + uninstall-libexecPROGRAMS uninstall-pkgcfgDATA \ + uninstall-pluginLTLIBRARIES @LINUX_TRUE@install-exec-hook: -@LINUX_TRUE@ $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-transport-wlan || true -@LINUX_TRUE@ $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-transport-wlan || true +@LINUX_TRUE@ $(top_srcdir)/src/transport/install-wlan-helper.sh $(libexecdir) $(SUDO_BINARY) || true @LINUX_FALSE@install-exec-hook: # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/transport/gnunet-helper-transport-wlan.c b/src/transport/gnunet-helper-transport-wlan.c index 363925c..3ad4d64 100644 --- a/src/transport/gnunet-helper-transport-wlan.c +++ b/src/transport/gnunet-helper-transport-wlan.c @@ -109,8 +109,7 @@ /* * parts taken from aircrack-ng, parts changend. */ - -#define _GNU_SOURCE +#include "gnunet_config.h" #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/types.h> @@ -140,11 +139,20 @@ /** * Packet format type for the messages we receive from + * the kernel. This is for Ethernet 10Mbps format (no + * performance information included). + */ +#define ARPHRD_ETHER 1 + + +/** + * 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. @@ -1589,6 +1597,15 @@ linux_read (struct HardwareInfos *dev, case ARPHRD_IEEE80211: n = 0; /* no header */ break; + case ARPHRD_ETHER: + { + if (sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen) + return 0; /* invalid */ + memcpy (&buf[sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)], + tmpbuf + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame), + caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4 /* 4 byte FCS */); + return caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4; + } default: errno = ENOTSUP; /* unsupported format */ return -1; @@ -1652,6 +1669,16 @@ open_device_raw (struct HardwareInfos *dev) IFNAMSIZ, dev->iface, strerror (errno)); return 1; } + if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ) + { + fprintf (stderr, "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n", + IFNAMSIZ, dev->iface, + ifr.ifr_hwaddr.sa_family); + return 1; + } /* lookup iw mode */ memset (&wrq, 0, sizeof (struct iwreq)); @@ -1663,13 +1690,12 @@ open_device_raw (struct HardwareInfos *dev) wrq.u.mode = IW_MODE_MONITOR; } - if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && - (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && - (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || - (wrq.u.mode != IW_MODE_MONITOR)) + if ( (wrq.u.mode != IW_MODE_MONITOR) && + (wrq.u.mode != IW_MODE_ADHOC) ) { - fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n", - IFNAMSIZ, dev->iface); + fprintf (stderr, "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n", + IFNAMSIZ, dev->iface, + wrq.u.mode); return 1; } @@ -1705,7 +1731,8 @@ open_device_raw (struct HardwareInfos *dev) memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); dev->arptype_in = ifr.ifr_hwaddr.sa_family; - if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) { @@ -1771,6 +1798,12 @@ static int mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev) { + static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros; + + if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) || + (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) ) + return 0; /* some drivers set no Macs, then assume it is all for us! */ + 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)) || @@ -1812,6 +1845,7 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader; size_t sendsize; struct RadiotapTransmissionHeader rtheader; + struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader; sendsize = ntohs (hdr->size); if ( (sendsize < @@ -1828,21 +1862,41 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) 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.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->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 to prevent mischief */ - mac_set (wlanheader, dev); - write_pout.size = sendsize + sizeof (rtheader); + switch (dev->arptype_in) + { + case ARPHRD_IEEE80211_PRISM: + case ARPHRD_IEEE80211_FULL: + case ARPHRD_IEEE80211: + rtheader.header.it_version = 0; + rtheader.header.it_pad = 0; + rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader)); + 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->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 to prevent mischief */ + mac_set (wlanheader, dev); + write_pout.size = sendsize + sizeof (rtheader); + break; + case ARPHRD_ETHER: + etheader.dst = header->frame.addr1; + /* etheader.src = header->frame.addr2; --- untrusted input */ + etheader.src = dev->pl_mac; + etheader.type = htons (ETH_P_IP); + memcpy (write_pout.buf, ðeader, sizeof (etheader)); + memcpy (&write_pout.buf[sizeof (etheader)], &header[1], sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)); + write_pout.size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame) + sizeof (etheader); + break; + default: + fprintf (stderr, + "Unsupported ARPTYPE!\n"); + break; + } } @@ -1867,33 +1921,29 @@ main (int argc, char *argv[]) int stdin_open; struct MessageStreamTokenizer *stdin_mst; int raw_eno; + uid_t uid; - memset (&dev, 0, sizeof (dev)); - dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); - raw_eno = errno; /* remember for later */ - - /* drop privs */ - { - uid_t uid = getuid (); + /* assert privs so we can modify the firewall rules! */ + uid = getuid (); #ifdef HAVE_SETRESUID - if (0 != setresuid (uid, uid, uid)) - { - fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); - if (-1 != dev.fd_raw) - (void) close (dev.fd_raw); - return 1; - } + if (0 != setresuid (uid, 0, 0)) + { + fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno)); + return 254; + } #else - if (0 != (setuid (uid) | seteuid (uid))) - { - fprintf (stderr, "Failed to setuid: %s\n", strerror (errno)); - if (-1 != dev.fd_raw) - (void) close (dev.fd_raw); - return 1; - } + if (0 != seteuid (0)) + { + fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno)); + return 254; } #endif + /* make use of SGID capabilities on POSIX */ + memset (&dev, 0, sizeof (dev)); + dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); + raw_eno = errno; /* remember for later */ + /* now that we've dropped root rights, we can do error checking */ if (2 != argc) { @@ -1928,6 +1978,29 @@ main (int argc, char *argv[]) return 1; } + /* drop privs */ + { + uid_t uid = getuid (); +#ifdef HAVE_SETRESUID + if (0 != setresuid (uid, uid, uid)) + { + fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); + if (-1 != dev.fd_raw) + (void) close (dev.fd_raw); + return 1; + } +#else + if (0 != (setuid (uid) | seteuid (uid))) + { + fprintf (stderr, "Failed to setuid: %s\n", strerror (errno)); + if (-1 != dev.fd_raw) + (void) close (dev.fd_raw); + return 1; + } +#endif + } + + /* send MAC address of the WLAN interface to STDOUT first */ { struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg; diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index c200cb5..e64cbfb 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -37,6 +37,7 @@ #include "gnunet-service-transport_neighbours.h" #include "gnunet-service-transport_plugins.h" #include "gnunet-service-transport_validation.h" +#include "gnunet-service-transport_manipulation.h" #include "transport.h" /* globals */ @@ -62,6 +63,16 @@ struct GNUNET_PeerIdentity GST_my_identity; struct GNUNET_PEERINFO_Handle *GST_peerinfo; /** + * Hostkey generation context + */ +struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen; + +/** + * Handle to our service's server. + */ +static struct GNUNET_SERVER_Handle *GST_server; + +/** * Our public key. */ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key; @@ -81,6 +92,11 @@ struct GNUNET_ATS_SchedulingHandle *GST_ats; */ static int connections; +/** + * Hello address expiration + */ +struct GNUNET_TIME_Relative hello_expiration; + /** * Transmit our HELLO message to the given (connected) neighbour. @@ -90,17 +106,21 @@ static int connections; * @param ats performance information (unused) * @param ats_count number of records in ats (unused) * @param address the address + * @param bandwidth_in inbound quota in NBO + * @param bandwidth_out outbound quota in NBO */ static void transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { const struct GNUNET_MessageHeader *hello = cls; GST_neighbours_send (target, (const char *) hello, ntohs (hello->size), - GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION, NULL, NULL); + hello_expiration, NULL, NULL); } @@ -179,6 +199,7 @@ process_payload (const struct GNUNET_PeerIdentity *peer, htonl ((uint32_t) GST_neighbour_get_latency (peer).rel_value); memcpy (&ap[ats_count + 1], message, ntohs (message->size)); + GNUNET_ATS_address_add (GST_ats, address, session, ap, ats_count + 1); GNUNET_ATS_address_update (GST_ats, address, session, ap, ats_count + 1); GST_clients_broadcast (&im->header, GNUNET_YES); @@ -209,8 +230,8 @@ process_payload (const struct GNUNET_PeerIdentity *peer, * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ -static struct GNUNET_TIME_Relative -plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, +struct GNUNET_TIME_Relative +GST_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, struct Session *session, @@ -287,11 +308,6 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, break; } end: -#if 1 - /* FIXME: this should not be needed, and not sure it's good to have it, but without - * this connections seem to go extra-slow */ - GNUNET_ATS_address_update (GST_ats, &address, session, ats, ats_count); -#endif 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); @@ -309,16 +325,17 @@ end: * @param addr one of the addresses of the host * the specific address format depends on the transport * @param addrlen length of the address + * @param dest_plugin destination plugin to use this address with */ static void plugin_env_address_change_notification (void *cls, int add_remove, - const void *addr, size_t addrlen) + const void *addr, size_t addrlen, + const char *dest_plugin) { - const char *plugin_name = cls; struct GNUNET_HELLO_Address address; address.peer = GST_my_identity; - address.transport_name = plugin_name; + address.transport_name = dest_plugin; address.address = addr; address.address_length = addrlen; GST_hello_modify_addresses (add_remove, &address); @@ -346,7 +363,7 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_HELLO_Address address; GNUNET_assert (strlen (transport_name) > 0); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' ended \n", session, GNUNET_i2s (peer)); if (NULL != session) GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, @@ -358,6 +375,8 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, address.address_length = 0; address.transport_name = transport_name; GST_neighbours_session_terminated (peer, session); + + /* Tell ATS that session has ended */ GNUNET_ATS_address_destroyed (GST_ats, &address, session); } @@ -392,7 +411,7 @@ plugin_env_address_to_type (void *cls, addrlen, GNUNET_a2s(addr, addrlen)); GNUNET_break (0); - return (const struct GNUNET_ATS_Information) ats; + return ats; } return GNUNET_ATS_address_get_type(GST_ats, addr, addrlen); } @@ -448,12 +467,16 @@ ats_request_address_change (void *cls, * @param peer the peer that connected * @param ats performance data * @param ats_count number of entries in ats + * @param bandwidth_in inbound bandwidth in NBO + * @param bandwidth_out outbound bandwidth in NBO */ static void neighbours_connect_notification (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + uint32_t ats_count, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { size_t len = sizeof (struct ConnectInfoMessage) + @@ -471,6 +494,8 @@ neighbours_connect_notification (void *cls, connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); connect_msg->ats_count = htonl (ats_count); connect_msg->id = *peer; + connect_msg->quota_in = bandwidth_in; + connect_msg->quota_out = bandwidth_out; ap = (struct GNUNET_ATS_Information *) &connect_msg[1]; memcpy (ap, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); GST_clients_broadcast (&connect_msg->header, GNUNET_NO); @@ -530,6 +555,11 @@ neighbours_address_notification (void *cls, static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + if (NULL != GST_keygen) + { + GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen); + GST_keygen = NULL; + } GST_neighbours_stop (); GST_validation_stop (); GST_plugins_unload (); @@ -539,61 +569,64 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GST_clients_stop (); GST_blacklist_stop (); GST_hello_stop (); + GST_manipulation_stop (); - if (GST_peerinfo != NULL) + if (NULL != GST_peerinfo) { GNUNET_PEERINFO_disconnect (GST_peerinfo); GST_peerinfo = NULL; } - if (GST_stats != NULL) + if (NULL != GST_stats) { GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); GST_stats = NULL; } - if (GST_my_private_key != NULL) + if (NULL != GST_my_private_key) { GNUNET_CRYPTO_rsa_key_free (GST_my_private_key); GST_my_private_key = NULL; } + GST_server = NULL; } /** - * Initiate transport service. + * Callback for hostkey read/generation * - * @param cls closure - * @param server the initialized server - * @param c configuration to use + * @param cls NULL + * @param pk the private key + * @param emsg error message */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +key_generation_cb (void *cls, + struct GNUNET_CRYPTO_RsaPrivateKey *pk, + const char *emsg) { - char *keyfile; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp; - /* setup globals */ - GST_cfg = c; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY", - &keyfile)) + long long unsigned int max_fd_cfg; + int max_fd_rlimit; + int max_fd; + + GST_keygen = NULL; + if (NULL == pk) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Transport service is lacking key configuration settings. Exiting.\n")); + _("Transport service could not access hostkey: %s. Exiting.\n"), + emsg); GNUNET_SCHEDULER_shutdown (); return; } - GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - GNUNET_free (keyfile); - if (GST_my_private_key == NULL) + GST_my_private_key = pk; + + GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg); + if (NULL == GST_stats) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Transport service could not access hostkey. Exiting.\n")); + _("Could not access STATISTICS service. Exiting.\n")); GNUNET_SCHEDULER_shutdown (); return; } - GST_stats = GNUNET_STATISTICS_create ("transport", c); - GST_peerinfo = GNUNET_PEERINFO_connect (c); + GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg); 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); @@ -605,7 +638,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); - if (GST_peerinfo == NULL) + if (NULL == GST_peerinfo) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access PEERINFO service. Exiting.\n")); @@ -613,22 +646,97 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, return; } + max_fd_rlimit = 0; + max_fd_cfg = 0; + max_fd = 0; +#if HAVE_GETRLIMIT + struct rlimit r_file; + if (0 == getrlimit (RLIMIT_NOFILE, &r_file)) + { + max_fd_rlimit = r_file.rlim_cur; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Maximum number of open files was: %u/%u\n", r_file.rlim_cur, + r_file.rlim_max); + } + max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */ +#endif + GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD", &max_fd_cfg); + + if (max_fd_cfg > max_fd_rlimit) + max_fd = max_fd_cfg; + else + max_fd = max_fd_rlimit; + if (max_fd < DEFAULT_MAX_FDS) + max_fd = DEFAULT_MAX_FDS; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Limiting number of sockets to %u: validation %u, neighbors: %u\n", + max_fd, (max_fd / 3) , (max_fd / 3) * 2); + /* start subsystems */ GST_hello_start (&process_hello_update, NULL); GNUNET_assert (NULL != GST_hello_get()); - GST_blacklist_start (server); + GST_blacklist_start (GST_server); GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); - GST_plugins_load (&plugin_env_receive_callback, + GST_manipulation_init (); + GST_plugins_load (&GST_manipulation_recv, &plugin_env_address_change_notification, &plugin_env_session_end, &plugin_env_address_to_type); GST_neighbours_start (NULL, &neighbours_connect_notification, &neighbours_disconnect_notification, - &neighbours_address_notification); - GST_clients_start (server); - GST_validation_start (); + &neighbours_address_notification, + (max_fd / 3) * 2); + GST_clients_start (GST_server); + GST_validation_start ((max_fd / 3)); + if (NULL != GST_server) + GNUNET_SERVER_resume (GST_server); +} + + +/** + * Initiate transport service. + * + * @param cls closure + * @param server the initialized server + * @param c configuration to use + */ +static void +run (void *cls, struct GNUNET_SERVER_Handle *server, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + char *keyfile; + + /* setup globals */ + GST_cfg = c; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY", + &keyfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _ + ("Transport service is lacking key configuration settings. Exiting.\n")); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (c, "transport", "HELLO_EXPIRATION", + &hello_expiration)) + { + hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION; + } + GST_server = server; + GNUNET_SERVER_suspend (server); + GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL); + GNUNET_free (keyfile); + if (NULL == GST_keygen) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Transport service is unable to access hostkey. Exiting.\n")); + GNUNET_SCHEDULER_shutdown (); + } } diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h index adc28ba..abc473e 100644 --- a/src/transport/gnunet-service-transport.h +++ b/src/transport/gnunet-service-transport.h @@ -67,6 +67,37 @@ extern struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key; */ extern struct GNUNET_ATS_SchedulingHandle *GST_ats; +/** + * Function called by the transport for each received message. + * This function should also be called with "NULL" for the + * message to signal that the other peer disconnected. + * + * @param cls closure, const char* with the name of the plugin we received the message from + * @param peer (claimed) identity of the other peer + * @param message the message, NULL if we only care about + * learning about the delay until we should receive again -- FIXME! + * @param ats performance information + * @param ats_count number of records in ats + * @param session identifier used for this session (NULL for plugins + * that do not offer bi-directional communication to the sender + * using the same "connection") + * @param sender_address binary address of the sender (if we established the + * connection or are otherwise sure of it; should be NULL + * for inbound TCP/UDP connections since it it not clear + * that we could establish ourselves a connection to that + * IP address and get the same system) + * @param sender_address_len number of bytes in sender_address + * @return how long the plugin should wait until receiving more data + * (plugins that do not support this, can ignore the return value) + */ +struct GNUNET_TIME_Relative +GST_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, struct Session *session, + const char *sender_address, + uint16_t sender_address_len); + #endif /* end of file gnunet-service-transport_plugins.h */ diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index 8c36888..479b30e 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c @@ -230,15 +230,15 @@ read_blacklist_file () GNUNET_CONFIGURATION_get_value_filename (GST_cfg, "TRANSPORT", "BLACKLIST_FILE", &fn)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Option `%s' in section `%s' not specified!\n", - "BLACKLIST_FILE", "TRANSPORT"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_DEBUG, + "transport", "BLACKLIST_FILE"); 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); + { + GNUNET_free (fn); + return; /* no blacklist */ + } if (GNUNET_OK != GNUNET_DISK_file_size (fn, &fsize, GNUNET_NO, GNUNET_YES)) { @@ -247,9 +247,9 @@ read_blacklist_file () GNUNET_free (fn); return; } - if (fsize == 0) + if (0 == fsize) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklist file `%s' is empty.\n"), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist file `%s' is empty.\n", fn); GNUNET_free (fn); return; @@ -395,7 +395,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server) * @return GNUNET_OK (continue to iterate) */ static int -free_blacklist_entry (void *cls, const GNUNET_HashCode * key, void *value) +free_blacklist_entry (void *cls, const struct GNUNET_HashCode * key, void *value) { char *be = value; @@ -543,12 +543,16 @@ struct TestConnectionContext * @param ats performance data * @param ats_count number of entries in ats (excluding 0-termination) * @param address the address + * @param bandwidth_in inbound quota in NBO + * @param bandwidth_out outbound quota in NBO */ static void test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *neighbour, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { struct TestConnectionContext *tcc = cls; struct GST_BlacklistCheck *bc; @@ -684,7 +688,8 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (peer), transport_name); if (blacklist == NULL) blacklist = - GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE); + GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE, + GNUNET_NO); GNUNET_CONTAINER_multihashmap_put (blacklist, &peer->hashPubKey, GNUNET_strdup (transport_name), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); @@ -701,7 +706,7 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, * @return GNUNET_OK if the entry does not match, GNUNET_NO if it matches */ static int -test_blacklisted (void *cls, const GNUNET_HashCode * key, void *value) +test_blacklisted (void *cls, const struct GNUNET_HashCode * key, void *value) { const char *transport_name = cls; char *be = value; diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index b298195..23fc727 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -30,9 +30,11 @@ #include "gnunet-service-transport_neighbours.h" #include "gnunet-service-transport_plugins.h" #include "gnunet-service-transport_validation.h" +#include "gnunet-service-transport_manipulation.h" #include "gnunet-service-transport.h" #include "transport.h" + /** * How many messages can we have pending for a given client process * before we start to drop incoming messages? We typically should @@ -115,6 +117,26 @@ struct TransportClient int send_payload; }; +/** + * Context for address to string operations + */ +struct AddressToStringContext +{ + /** + * This is a doubly-linked list. + */ + struct AddressToStringContext *next; + + /** + * This is a doubly-linked list. + */ + struct AddressToStringContext *prev; + + /** + * Transmission context + */ + struct GNUNET_SERVER_TransmitContext* tc; +}; /** * Client monitoring changes of active addresses of our neighbours. @@ -156,6 +178,16 @@ static struct TransportClient *clients_head; static struct TransportClient *clients_tail; /** + * Head of linked list of all pending address iterations + */ +struct AddressToStringContext *a2s_head; + +/** + * Tail of linked list of all pending address iterations + */ +struct AddressToStringContext *a2s_tail; + +/** * Head of linked list of monitoring clients. */ static struct MonitoringClient *monitoring_clients_head; @@ -250,6 +282,7 @@ setup_monitoring_client (struct GNUNET_SERVER_Client *client, struct GNUNET_PeerIdentity *peer) { struct MonitoringClient *mc; + static struct GNUNET_PeerIdentity all_zeros; GNUNET_assert (lookup_monitoring_client (client) == NULL); mc = GNUNET_malloc (sizeof (struct MonitoringClient)); @@ -260,9 +293,13 @@ setup_monitoring_client (struct GNUNET_SERVER_Client *client, mc); GNUNET_SERVER_notification_context_add (nc, client); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client %p started monitoring of the peer `%s'\n", - mc, GNUNET_i2s (peer)); + if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client %p started monitoring of the peer `%s'\n", + mc, GNUNET_i2s (peer)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client %p started monitoring all peers\n", mc); return mc; } @@ -431,13 +468,17 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) * @param ats performance data * @param ats_count number of entries in ats (excluding 0-termination) * @param address the address + * @param bandwidth_in inbound bandwidth in NBO + * @param bandwidth_out outbound bandwidth in NBO */ static void notify_client_about_neighbour (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { struct TransportClient *tc = cls; struct ConnectInfoMessage *cim; @@ -453,6 +494,8 @@ notify_client_about_neighbour (void *cls, cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); cim->ats_count = htonl (ats_count); cim->id = *peer; + cim->quota_in = bandwidth_in; + cim->quota_out = bandwidth_out; ap = (struct GNUNET_ATS_Information *) &cim[1]; memcpy (ap, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); unicast (tc, &cim->header, GNUNET_NO); @@ -553,15 +596,28 @@ struct SendTransmitContinuationContext * * @param cls closure * @param success GNUNET_OK on success, GNUNET_NO on failure, GNUNET_SYSERR if we're not connected + * @param bytes_payload bytes payload sent + * @param bytes_on_wire bytes sent on wire */ static void -handle_send_transmit_continuation (void *cls, int success) +handle_send_transmit_continuation (void *cls, int success, + size_t bytes_payload, size_t bytes_on_wire) { struct SendTransmitContinuationContext *stcc = cls; struct SendOkMessage send_ok_msg; + //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Payload: %u, On wire %u result: %i\n", bytes_payload, bytes_on_wire, success); + /* + if (GNUNET_OK == success) + GNUNET_assert (bytes_on_wire >= bytes_payload); + + else + GNUNET_assert (bytes_on_wire <= bytes_payload); +*/ send_ok_msg.header.size = htons (sizeof (send_ok_msg)); send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); + send_ok_msg.bytes_msg = htonl (bytes_payload); + send_ok_msg.bytes_physical = htonl (bytes_on_wire); send_ok_msg.success = htonl (success); send_ok_msg.latency = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_FOREVER_REL); @@ -638,7 +694,7 @@ clients_handle_send (void *cls, struct GNUNET_SERVER_Client *client, stcc->target = obm->peer; stcc->client = client; GNUNET_SERVER_client_keep (client); - GST_neighbours_send (&obm->peer, obmm, msize, + GST_manipulation_send (&obm->peer, obmm, msize, GNUNET_TIME_relative_ntoh (obm->timeout), &handle_send_transmit_continuation, stcc); } @@ -700,16 +756,17 @@ clients_handle_request_connect (void *cls, struct GNUNET_SERVER_Client *client, static void transmit_address_to_client (void *cls, const char *buf) { - struct GNUNET_SERVER_TransmitContext *tc = cls; - + struct AddressToStringContext *actx = cls; if (NULL == buf) { - GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, + GNUNET_SERVER_transmit_context_append_data (actx->tc, NULL, 0, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY); - GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_SERVER_transmit_context_run (actx->tc, GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CONTAINER_DLL_remove (a2s_head, a2s_tail, actx); + GNUNET_free (actx); return; } - GNUNET_SERVER_transmit_context_append_data (tc, buf, strlen (buf) + 1, + GNUNET_SERVER_transmit_context_append_data (actx->tc, buf, strlen (buf) + 1, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY); } @@ -733,6 +790,7 @@ clients_handle_address_to_string (void *cls, uint32_t address_len; uint16_t size; struct GNUNET_SERVER_TransmitContext *tc; + struct AddressToStringContext *actx; struct GNUNET_TIME_Relative rtimeout; int32_t numeric; @@ -763,7 +821,7 @@ clients_handle_address_to_string (void *cls, rtimeout = GNUNET_TIME_relative_ntoh (alum->timeout); numeric = ntohs (alum->numeric_only); tc = GNUNET_SERVER_transmit_context_create (client); - papi = GST_plugins_find (plugin_name); + papi = GST_plugins_printer_find (plugin_name); if (NULL == papi) { GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, @@ -771,10 +829,13 @@ clients_handle_address_to_string (void *cls, GNUNET_SERVER_transmit_context_run (tc, rtimeout); return; } + actx = GNUNET_malloc (sizeof (struct AddressToStringContext)); + actx->tc = tc; + GNUNET_CONTAINER_DLL_insert (a2s_head, a2s_tail, actx); GNUNET_SERVER_disable_receive_done_warning (client); papi->address_pretty_printer (papi->cls, plugin_name, address, address_len, numeric, rtimeout, &transmit_address_to_client, - tc); + actx); } @@ -832,11 +893,15 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity * @param ats performance data * @param ats_count number of entries in ats (excluding 0-termination) * @param address the address + * @param bandwidth_in inbound quota in NBO + * @param bandwidth_out outbound quota in NBO */ static void output_address (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { struct GNUNET_SERVER_TransmitContext *tc = cls; struct AddressIterateResponseMessage *msg; @@ -900,7 +965,9 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, /* just return one neighbour */ address = GST_neighbour_get_current_address (&msg->peer); if (address != NULL) - output_address (tc, &msg->peer, NULL, 0, address); + output_address (tc, &msg->peer, NULL, 0, address, + GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, + GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT); } if (GNUNET_YES != ntohl (msg->one_shot)) setup_monitoring_client (client, &msg->peer); @@ -940,6 +1007,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) {&GST_blacklist_handle_reply, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, sizeof (struct BlacklistMessage)}, + {&GST_manipulation_set_metric, NULL, + GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, 0}, {NULL, NULL, 0, 0} }; nc = GNUNET_SERVER_notification_context_create (server, 0); @@ -955,6 +1024,15 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) void GST_clients_stop () { + struct AddressToStringContext *cur; + + while (NULL != (cur = a2s_head)) + { + GNUNET_SERVER_transmit_context_destroy (cur->tc, GNUNET_NO); + GNUNET_CONTAINER_DLL_remove (a2s_head, a2s_tail, cur); + GNUNET_free (cur); + } + if (NULL != nc) { GNUNET_SERVER_notification_context_destroy (nc); @@ -962,7 +1040,6 @@ GST_clients_stop () } } - /** * Broadcast the given message to all of our clients. * @@ -1018,7 +1095,6 @@ GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity struct AddressIterateResponseMessage *msg; struct MonitoringClient *mc; static struct GNUNET_PeerIdentity all_zeros; - msg = compose_address_iterate_response_message (peer, address); mc = monitoring_clients_head; while (mc != NULL) diff --git a/src/transport/gnunet-service-transport_clients.h b/src/transport/gnunet-service-transport_clients.h index 9556620..25d0758 100644 --- a/src/transport/gnunet-service-transport_clients.h +++ b/src/transport/gnunet-service-transport_clients.h @@ -31,6 +31,7 @@ #include "gnunet_hello_lib.h" + /** * Start handling requests from clients. * diff --git a/src/transport/gnunet-service-transport_hello.c b/src/transport/gnunet-service-transport_hello.c index 870c083..247fbc8 100644 --- a/src/transport/gnunet-service-transport_hello.c +++ b/src/transport/gnunet-service-transport_hello.c @@ -38,6 +38,11 @@ */ #define HELLO_REFRESH_PERIOD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6) +/** + * Hello address expiration + */ +extern struct GNUNET_TIME_Relative hello_expiration; + /** * Entry in linked list of network addresses for ourselves. Also @@ -159,9 +164,7 @@ refresh_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) hello_task = GNUNET_SCHEDULER_NO_TASK; gc.addr_pos = oal_head; - gc.expiration = - GNUNET_TIME_relative_to_absolute - (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); + gc.expiration = GNUNET_TIME_relative_to_absolute (hello_expiration); GNUNET_free (our_hello); our_hello = GNUNET_HELLO_create (&GST_my_public_key, &address_generator, &gc); diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c new file mode 100644 index 0000000..34c8ab1 --- /dev/null +++ b/src/transport/gnunet-service-transport_manipulation.c @@ -0,0 +1,336 @@ +/* + 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 transport/gnunet-service-transport_manipulation.c + * @brief transport component manipulation traffic for simulation + * @author Christian Grothoff + * @author Matthias Wachs + */ +#include "platform.h" +#include "gnunet-service-transport_blacklist.h" +#include "gnunet-service-transport_clients.h" +#include "gnunet-service-transport_hello.h" +#include "gnunet-service-transport_neighbours.h" +#include "gnunet-service-transport_plugins.h" +#include "gnunet-service-transport_validation.h" +#include "gnunet-service-transport.h" +#include "transport.h" + +static struct GNUNET_CONTAINER_MultiHashMap *peers; + +#define DELAY 0 +#define DISTANCE 1 + +struct TM_Peer; + +struct DelayQueueEntry +{ + struct DelayQueueEntry *prev; + struct DelayQueueEntry *next; + struct TM_Peer *tmp; + struct GNUNET_TIME_Absolute sent_at; + void *msg; + size_t msg_size; + struct GNUNET_TIME_Relative timeout; + GST_NeighbourSendContinuation cont; + void *cont_cls; +}; + +struct TM_Peer +{ + struct GNUNET_PeerIdentity peer; + uint32_t metrics [TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; + GNUNET_SCHEDULER_TaskIdentifier send_delay_task; + struct DelayQueueEntry *send_head; + struct DelayQueueEntry *send_tail; +}; + + + +static void +set_delay(struct TM_Peer *tmp, struct GNUNET_PeerIdentity *peer, int direction, uint32_t value) +{ + uint32_t val; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Set traffic metrics %s for peer `%s' in direction %s to %u\n", + "DELAY", GNUNET_i2s(peer), + (TM_BOTH == direction) ? "BOTH" : (TM_SEND == direction) ? "SEND": "RECEIVE", value); + + if (UINT32_MAX == value) + val = UINT32_MAX - 1; /* prevent overflow */ + else if (0 == value) + val = UINT32_MAX; /* disable */ + else + val = value; + + switch (direction) { + case TM_BOTH: + tmp->metrics[TM_SEND][DELAY] = val; + tmp->metrics[TM_RECEIVE][DELAY] = val; + break; + case TM_SEND: + tmp->metrics[TM_SEND][DELAY] = val; + break; + case TM_RECEIVE: + tmp->metrics[TM_RECEIVE][DELAY] = val; + break; + default: + break; + } + +} + +static void +set_distance (struct TM_Peer *tmp, struct GNUNET_PeerIdentity *peer, int direction, uint32_t value) +{ + uint32_t val; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Set traffic metrics %s for peer `%s' in direction %s to %u\n", + "DISTANCE", GNUNET_i2s(peer), + (TM_BOTH == direction) ? "BOTH" : (TM_SEND == direction) ? "SEND": "RECEIVE", value); + + if (UINT32_MAX == value) + val = UINT32_MAX - 1; /* prevent overflow */ + else if (0 == value) + val = UINT32_MAX; /* disable */ + else + val = value; + + switch (direction) { + case TM_BOTH: + tmp->metrics[TM_SEND][DISTANCE] = val; + tmp->metrics[TM_RECEIVE][DISTANCE] = val; + break; + case TM_SEND: + tmp->metrics[TM_SEND][DISTANCE] = val; + break; + case TM_RECEIVE: + tmp->metrics[TM_RECEIVE][DISTANCE] = val; + break; + default: + break; + } +} + +void +GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; + struct GNUNET_ATS_Information *ats; + struct TM_Peer *tmp; + uint32_t type; + uint32_t value; + int c; + int c2; + + if (0 == ntohs (tm->ats_count)) + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received traffic metrics for peer `%s'\n", + GNUNET_i2s(&tm->peer)); + + if (NULL == (tmp = GNUNET_CONTAINER_multihashmap_get (peers, &tm->peer.hashPubKey))) + { + tmp = GNUNET_malloc (sizeof (struct TM_Peer)); + tmp->peer = (tm->peer); + for (c = 0; c < TM_BOTH; c++) + { + for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) + { + tmp->metrics[c][c2] = UINT32_MAX; + } + } + GNUNET_CONTAINER_multihashmap_put (peers, &tm->peer.hashPubKey, tmp, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } + + ats = (struct GNUNET_ATS_Information *) &tm[1]; + for (c = 0; c < ntohs (tm->ats_count); c++) + { + type = htonl (ats[c].type); + value = htonl (ats[c].value); + switch (type) { + case GNUNET_ATS_QUALITY_NET_DELAY: + set_delay (tmp, &tm->peer, ntohs (tm->direction), value); + break; + case GNUNET_ATS_QUALITY_NET_DISTANCE: + set_distance (tmp, &tm->peer, ntohs (tm->direction), value); + break; + default: + break; + } + } + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + +static void +send_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct DelayQueueEntry *dqe = cls; + struct DelayQueueEntry *next; + struct TM_Peer *tmp = dqe->tmp; + struct GNUNET_TIME_Relative delay; + tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe); + GST_neighbours_send (&tmp->peer, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls); + + next = tmp->send_head; + if (NULL != next) + { + /* More delayed messages */ + delay = GNUNET_TIME_absolute_get_remaining (next->sent_at); + tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); + } + + GNUNET_free (dqe); +} + +void +GST_manipulation_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 TM_Peer *tmp; + struct DelayQueueEntry *dqe; + struct GNUNET_TIME_Relative delay; + + if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (peers, &target->hashPubKey))) + { + /* Manipulate here */ + /* Delay */ + if (UINT32_MAX != tmp->metrics[TM_SEND][DELAY]) + { + /* We have a delay */ + delay.rel_value = tmp->metrics[TM_SEND][DELAY]; + dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); + dqe->tmp = tmp; + dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); + dqe->cont = cont; + dqe->cont_cls = cont_cls; + dqe->msg = &dqe[1]; + dqe->msg_size = msg_size; + dqe->timeout = timeout; + memcpy (dqe->msg, msg, msg_size); + GNUNET_CONTAINER_DLL_insert_tail (tmp->send_head, tmp->send_tail, dqe); + if (GNUNET_SCHEDULER_NO_TASK == tmp->send_delay_task) + tmp->send_delay_task =GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); + return; + } + } + /* Normal sending */ + GST_neighbours_send (target, msg, msg_size, timeout, cont, cont_cls); +} + +struct GNUNET_TIME_Relative +GST_manipulation_recv (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, struct Session *session, + const char *sender_address, + uint16_t sender_address_len) +{ + struct TM_Peer *tmp; + int d; + struct GNUNET_ATS_Information ats_new[ats_count]; + struct GNUNET_TIME_Relative q_delay; + struct GNUNET_TIME_Relative m_delay; + + for (d = 0; d < ats_count; d++) + + if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey))) + { + /* Manipulate distance */ + for (d = 0; d < ats_count; d++) + { + ats_new[d] = ats[d]; + /* Set distance */ + if ((ntohl(ats[d].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) && + (UINT32_MAX != tmp->metrics[TM_RECEIVE][DISTANCE])) + ats_new[d].value = htonl(tmp->metrics[TM_RECEIVE][DISTANCE]); + } + /* Manipulate receive delay */ + if (UINT32_MAX != tmp->metrics[TM_RECEIVE][DELAY]) + { + m_delay.rel_value = tmp->metrics[TM_RECEIVE][DELAY]; + q_delay = GST_receive_callback (cls, peer, message, &ats_new[0], ats_count, + session, sender_address, sender_address_len); + + if (q_delay.rel_value >= m_delay.rel_value) + { + return q_delay; + } + else + { + return m_delay; + } + } + else + return GST_receive_callback (cls, peer, message, &ats_new[0], ats_count, + session, sender_address, sender_address_len); + } + + return GST_receive_callback (cls, peer, message, ats, ats_count, + session, sender_address, sender_address_len); +} + +void +GST_manipulation_init () +{ + peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); +} + +int free_tmps (void *cls, + const struct GNUNET_HashCode * key, + void *value) +{ + struct DelayQueueEntry *dqe; + struct DelayQueueEntry *next; + if (NULL != value) + { + struct TM_Peer *tmp = (struct TM_Peer *) value; + GNUNET_CONTAINER_multihashmap_remove (peers, key, value); + next = tmp->send_head; + while (NULL != (dqe = next)) + { + next = dqe->next; + GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe); + GNUNET_free (dqe); + } + if (GNUNET_SCHEDULER_NO_TASK != tmp->send_delay_task) + { + GNUNET_SCHEDULER_cancel (tmp->send_delay_task); + tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_free (tmp); + } + return GNUNET_OK; +} + +void +GST_manipulation_stop () +{ + GNUNET_CONTAINER_multihashmap_iterate (peers, &free_tmps,NULL); + + GNUNET_CONTAINER_multihashmap_destroy (peers); + peers = NULL; +} + + +/* end of file gnunet-service-transport_manipulation.c */ diff --git a/src/transport/gnunet-service-transport_manipulation.h b/src/transport/gnunet-service-transport_manipulation.h new file mode 100644 index 0000000..f8faa85 --- /dev/null +++ b/src/transport/gnunet-service-transport_manipulation.h @@ -0,0 +1,63 @@ +/* + 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 transport/gnunet-service-transport_neighbours.h + * @brief neighbour management API + * @author Christian Grothoff + */ +#ifndef GNUNET_SERVICE_TRANSPORT_MANIPULATION_H +#define GNUNET_SERVICE_TRANSPORT_MANIPULATION_H + +#include "platform.h" +#include "gnunet-service-transport_blacklist.h" +#include "gnunet-service-transport_clients.h" +#include "gnunet-service-transport_hello.h" +#include "gnunet-service-transport_neighbours.h" +#include "gnunet-service-transport_plugins.h" +#include "gnunet-service-transport_validation.h" +#include "gnunet-service-transport.h" +#include "transport.h" + +void +GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message); + +void +GST_manipulation_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 GNUNET_TIME_Relative +GST_manipulation_recv (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, struct Session *session, + const char *sender_address, + uint16_t sender_address_len); + +void +GST_manipulation_init (); + +void +GST_manipulation_stop (); + +#endif +/* end of file gnunet-service-transport_neighbours.h */ diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index c580168..cad325d 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -40,6 +40,7 @@ #include "transport.h" + /** * Size of the neighbour hash map. */ @@ -91,6 +92,177 @@ */ #define BLACKLIST_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500) +#define DEBUG_MALLOC GNUNET_NO + +#if DEBUG_MALLOC + +struct Allocator +{ + struct Allocator *prev; + struct Allocator *next; + + unsigned int bytes_alloced; + unsigned int max_alloced; + unsigned int diff; + unsigned int line; + + struct GNUNET_TIME_Absolute max_alloced_when; + struct GNUNET_TIME_Absolute last_alloced_when; + +}; + +struct Allocator *aehead; +struct Allocator *aetail; + +struct Allocation +{ + struct Allocation *prev; + struct Allocation *next; + + struct Allocator *alloc; + unsigned int bytes_alloced; + void *p; + unsigned int line; +}; + +struct Allocation *ahead; +struct Allocation *atail; + +static int bytes_alloced; + +static struct Allocator * +find_allocator (int line) +{ + struct Allocator *cur = aehead; + while (NULL != cur) + { + if (line == cur->line) + return cur; + cur = cur->next; + } + return cur; +} + +static void +print_allocators () +{ + static int start = GNUNET_YES; + static struct GNUNET_TIME_Absolute next; + static struct GNUNET_TIME_Relative rem; + struct Allocator *cur = aehead; + if (start) + { + next = GNUNET_TIME_UNIT_ZERO_ABS; + start = GNUNET_NO; + } + if (0 == (rem = GNUNET_TIME_absolute_get_remaining(next)).rel_value) + { + fprintf (stderr, "Allocated in `%s' total: %5u bytes\n", __FILE__, bytes_alloced); + while (NULL != cur) + { + char *last_alloc = GNUNET_strdup (GNUNET_STRINGS_absolute_time_to_string(cur->max_alloced_when)); + fprintf (stderr, "Allocated from line %4u :%5u bytes (diff %5i bytes, max alloc: %5u @ %s, last alloc %s)\n", + cur->line, cur->bytes_alloced, cur->diff, cur->max_alloced, + last_alloc, + GNUNET_STRINGS_absolute_time_to_string(cur->last_alloced_when)); + GNUNET_free (last_alloc); + cur->diff = 0; + cur = cur->next; + } + fprintf (stderr, "\n"); + next = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS); + } +} + +#endif + +static void +MEMDEBUG_add_alloc (void *p, size_t size, int line) +{ +#if DEBUG_MALLOC + struct Allocation *alloc = GNUNET_malloc (sizeof (struct Allocation)); + struct Allocator *allocator = find_allocator(line); + if (NULL == allocator) + { + allocator = GNUNET_malloc (sizeof (struct Allocator)); + allocator->line = line; + GNUNET_CONTAINER_DLL_insert (aehead, aetail, allocator); + } + alloc->alloc = allocator; + alloc->p = p; + alloc->line = line; + alloc->bytes_alloced = size; + allocator->bytes_alloced += size; + allocator->last_alloced_when = GNUNET_TIME_absolute_get(); + if (allocator->bytes_alloced >= allocator->max_alloced) + { + allocator->max_alloced = allocator->bytes_alloced; + allocator->max_alloced_when = allocator->last_alloced_when; + } + allocator->diff += size; + GNUNET_CONTAINER_DLL_insert (ahead, atail, alloc); + print_allocators (); + bytes_alloced += size; +#endif +} + + +static void * +MEMDEBUG_malloc (size_t size, int line) +{ + void * ret; + + ret = GNUNET_malloc (size); +#if DEBUG_MALLOC + if (NULL != ret) + MEMDEBUG_add_alloc (ret, size, line); +#endif + return ret; + +} + +static void +MEMDEBUG_free (void * alloc, int line) +{ +#if DEBUG_MALLOC + struct Allocation *cur; + struct Allocator *allocator; + cur = ahead; + while (NULL != cur) + { + if (alloc == cur->p) + break; + cur = cur->next; + } + if (NULL == cur) + { + fprintf (stderr, "Unmonitored free from line %4u\n", line); + GNUNET_break (0); + return; + } + allocator = cur->alloc; + if (NULL == allocator) + { + GNUNET_break (0); + } + GNUNET_CONTAINER_DLL_remove (ahead, atail, cur); + allocator->bytes_alloced -= cur->bytes_alloced; + allocator->diff -= cur->bytes_alloced; + GNUNET_assert (allocator->bytes_alloced >= 0); + bytes_alloced -= cur->bytes_alloced; + GNUNET_assert (bytes_alloced >= 0); + GNUNET_free (cur); +#endif + GNUNET_free (alloc); +} + +static void +MEMDEBUG_free_non_null (void * alloc, int line) +{ + if (alloc != NULL) + MEMDEBUG_free (alloc, line); +} + GNUNET_NETWORK_STRUCT_BEGIN @@ -221,10 +393,10 @@ 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 + * first run a check against the blacklist (S_CONNECT_RECV_BLACKLIST_INBOUND). + * If this check is successful, we give the inbound address to ATS. + * After the check we ask ATS for a suggestion (S_CONNECT_RECV_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 @@ -302,6 +474,11 @@ enum State S_CONNECT_SENT, /** + * Received a CONNECT, do a blacklist check for inbound address + */ + S_CONNECT_RECV_BLACKLIST_INBOUND, + + /** * Received a CONNECT, asking ATS about address suggestions. */ S_CONNECT_RECV_ATS, @@ -363,7 +540,13 @@ enum State S_DISCONNECT, /** - * We're finished with the disconnect; clean up state now! + * We're finished with the disconnect; and are cleaning up the state + * now! We put the struct into this state when we are really in the + * task that calls 'free' on it and are about to remove the record + * from the map. We should never find a 'struct NeighbourMapEntry' + * in this state in the map. Accessing a 'struct NeighbourMapEntry' + * in this state virtually always means using memory that has been + * freed (the exception being the cleanup code in 'free_neighbour'). */ S_DISCONNECT_FINISHED }; @@ -474,6 +657,11 @@ struct NeighbourMapEntry struct GNUNET_TIME_Absolute connect_ack_timestamp; /** + * ATS address suggest handle + */ + struct GNUNET_ATS_SuggestHandle *suggest_handle; + + /** * 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). @@ -584,7 +772,7 @@ static void *callback_cls; /** * Function to call when we connected to a neighbour. */ -static GNUNET_TRANSPORT_NotifyConnect connect_notify_cb; +static NotifyConnect connect_notify_cb; /** * Function to call when we disconnected from a neighbour. @@ -629,56 +817,40 @@ print_state (int state) { case S_NOT_CONNECTED: return "S_NOT_CONNECTED"; - break; 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_BLACKLIST_INBOUND: + return "S_CONNECT_RECV_BLACKLIST_INBOUND"; 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_DISCONNECT_FINISHED: return "S_DISCONNECT_FINISHED"; - break; default: - return "UNDEFINED"; GNUNET_break (0); - break; + return "UNDEFINED"; } - GNUNET_break (0); - return "UNDEFINED"; } /** @@ -698,6 +870,7 @@ test_connected (struct NeighbourMapEntry *n) case S_INIT_ATS: case S_INIT_BLACKLIST: case S_CONNECT_SENT: + case S_CONNECT_RECV_BLACKLIST_INBOUND: case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: case S_CONNECT_RECV_ACK: @@ -757,11 +930,14 @@ free_address (struct NeighbourAddress *na) { 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); + address_change_cb (NULL, &na->address->peer, NULL); } + na->ats_active = GNUNET_NO; if (NULL != na->address) { - GNUNET_HELLO_address_free (na->address); + MEMDEBUG_free (na->address, __LINE__); + //GNUNET_HELLO_address_free (na->address); na->address = NULL; } na->session = NULL; @@ -789,7 +965,6 @@ set_address (struct NeighbourAddress *na, int is_active) { struct GNUNET_TRANSPORT_PluginFunctions *papi; - if (NULL == (papi = GST_plugins_find (address->transport_name))) { GNUNET_break (0); @@ -804,6 +979,8 @@ set_address (struct NeighbourAddress *na, 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__); + if (is_active) + address_change_cb (NULL, &address->peer, address); } if (GNUNET_YES == is_active) { @@ -825,6 +1002,7 @@ set_address (struct NeighbourAddress *na, return; } na->address = GNUNET_HELLO_address_copy (address); + MEMDEBUG_add_alloc (na->address, GNUNET_HELLO_address_get_size (na->address), __LINE__); na->bandwidth_in = bandwidth_in; na->bandwidth_out = bandwidth_out; na->session = session; @@ -832,10 +1010,9 @@ set_address (struct NeighbourAddress *na, if (GNUNET_YES == is_active) { /* 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__); - + address_change_cb (NULL, &address->peer, address); /* 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); @@ -855,6 +1032,7 @@ free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) { struct MessageQueue *mq; struct GNUNET_TRANSPORT_PluginFunctions *papi; + struct GNUNET_HELLO_Address *backup_primary; n->is_active = NULL; /* always free'd by its own continuation! */ @@ -863,8 +1041,8 @@ free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) { 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); + mq->cont (mq->cont_cls, GNUNET_SYSERR, mq->message_buf_size, 0); + MEMDEBUG_free (mq, __LINE__); } /* It is too late to send other peer disconnect notifications, but at least internally we need to get clean... */ @@ -877,6 +1055,20 @@ free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) disconnect_notify_cb (callback_cls, &n->id); } + n->state = S_DISCONNECT_FINISHED; + + if (NULL != n->primary_address.address) + { + backup_primary = GNUNET_HELLO_address_copy(n->primary_address.address); + MEMDEBUG_add_alloc (backup_primary, GNUNET_HELLO_address_get_size(backup_primary), __LINE__); + } + else + backup_primary = NULL; + + /* free addresses and mark as unused */ + free_address (&n->primary_address); + free_address (&n->alternative_address); + /* 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 @@ -886,26 +1078,28 @@ free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) 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. */ + + /* cut transport-level connection */ if ((GNUNET_NO == keep_sessions) && - (NULL != n->primary_address.address) && - (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name)))) + (NULL != backup_primary) && + (NULL != (papi = GST_plugins_find (backup_primary->transport_name)))) papi->disconnect (papi->cls, &n->id); - n->state = S_DISCONNECT_FINISHED; + MEMDEBUG_free_non_null (backup_primary, __LINE__); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (neighbours, &n->id.hashPubKey, n)); - /* cut transport-level connection */ - free_address (&n->primary_address); - free_address (&n->alternative_address); - // 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 (NULL != n->suggest_handle) + { + GNUNET_ATS_suggest_address_cancel (GST_ats, &n->id); + n->suggest_handle = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != n->task) { @@ -913,10 +1107,9 @@ free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) n->task = GNUNET_SCHEDULER_NO_TASK; } /* free rest of memory */ - GNUNET_free (n); + MEMDEBUG_free (n, __LINE__); } - /** * Transmit a message using the current session of the given * neighbour. @@ -940,15 +1133,15 @@ send_with_session (struct NeighbourMapEntry *n, struct GNUNET_TRANSPORT_PluginFunctions *papi; GNUNET_assert (n->primary_address.session != NULL); - if ( ( (NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name))) || + 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); + cont, cont_cls)))) && + (NULL != cont)) + cont (cont_cls, &n->id, GNUNET_SYSERR, msgbuf_size, 0); GNUNET_break (NULL != papi); } @@ -973,10 +1166,12 @@ master_task (void *cls, * @param cls NULL * @param target identity of the neighbour that was disconnected * @param result GNUNET_OK if the disconnect got out successfully + * @param payload bytes payload + * @param physical bytes physical */ static void send_disconnect_cont (void *cls, const struct GNUNET_PeerIdentity *target, - int result) + int result, size_t payload, size_t physical) { struct NeighbourMapEntry *n; @@ -1056,7 +1251,8 @@ disconnect_neighbour (struct NeighbourMapEntry *n) case S_CONNECT_SENT: send_disconnect (n); n->state = S_DISCONNECT; - break; + break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: /* we never ACK'ed the other peer's request, no need to send DISCONNECT */ @@ -1118,18 +1314,20 @@ disconnect_neighbour (struct NeighbourMapEntry *n) * @param cls the 'struct MessageQueue' of the message * @param receiver intended receiver * @param success whether it worked or not + * @param size_payload bytes payload sent + * @param physical bytes sent on wire */ static void transmit_send_continuation (void *cls, const struct GNUNET_PeerIdentity *receiver, - int success) + int success, size_t size_payload, size_t physical) { struct MessageQueue *mq = cls; struct NeighbourMapEntry *n; if (NULL == (n = lookup_neighbour (receiver))) { - GNUNET_free (mq); + MEMDEBUG_free (mq, __LINE__); return; /* disconnect or other error while transmitting, can happen */ } if (n->is_active == mq) @@ -1141,7 +1339,18 @@ transmit_send_continuation (void *cls, GNUNET_SCHEDULER_cancel (n->task); n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } - GNUNET_assert (bytes_in_send_queue >= mq->message_buf_size); + if (bytes_in_send_queue < mq->message_buf_size) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Bytes_in_send_queue `%u', Message_size %u, result: %s, payload %u, on wire %u\n", + bytes_in_send_queue, mq->message_buf_size, + (GNUNET_OK == success) ? "OK" : "FAIL", + size_payload, physical); + GNUNET_break (0); + } + + + GNUNET_break (size_payload == mq->message_buf_size); bytes_in_send_queue -= mq->message_buf_size; GNUNET_STATISTICS_set (GST_stats, gettext_noop @@ -1163,8 +1372,8 @@ transmit_send_continuation (void *cls, 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); + mq->cont (mq->cont_cls, success, size_payload, physical); + MEMDEBUG_free (mq, __LINE__); } @@ -1216,7 +1425,7 @@ try_transmission_to_peer (struct NeighbourMapEntry *n) 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 */ + transmit_send_continuation (mq, &n->id, GNUNET_SYSERR, mq->message_buf_size, 0); /* timeout */ } if (NULL == mq) return; /* no more messages */ @@ -1231,8 +1440,9 @@ try_transmission_to_peer (struct NeighbourMapEntry *n) /** * 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). + * if we are on 'connected' state or while trying to switch addresses. + * Will internally determine if a keepalive is truly needed (so can + * always be called). * * @param n neighbour that went idle and needs a keepalive */ @@ -1241,7 +1451,9 @@ send_keepalive (struct NeighbourMapEntry *n) { struct GNUNET_MessageHeader m; - GNUNET_assert (S_CONNECTED == n->state); + GNUNET_assert ((S_CONNECTED == n->state) || + (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || + (S_CONNECTED_SWITCHING_CONNECT_SENT)); 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)); @@ -1336,7 +1548,7 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, 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, + 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); @@ -1466,14 +1678,14 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, { GNUNET_break (0); if (NULL != cont) - cont (cont_cls, GNUNET_SYSERR); + cont (cont_cls, GNUNET_SYSERR, msg_size, 0); return; } if (GNUNET_YES != test_connected (n)) { GNUNET_break (0); if (NULL != cont) - cont (cont_cls, GNUNET_SYSERR); + cont (cont_cls, GNUNET_SYSERR, msg_size, 0); return; } bytes_in_send_queue += msg_size; @@ -1481,7 +1693,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, gettext_noop ("# bytes in message queue for other peers"), bytes_in_send_queue, GNUNET_NO); - mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size); + mq = MEMDEBUG_malloc (sizeof (struct MessageQueue) + msg_size, __LINE__); mq->cont = cont; mq->cont_cls = cont_cls; memcpy (&mq[1], msg, msg_size); @@ -1508,7 +1720,7 @@ send_session_connect (struct NeighbourAddress *na) { struct GNUNET_TRANSPORT_PluginFunctions *papi; struct SessionConnectMessage connect_msg; - + if (NULL == (papi = GST_plugins_find (na->address->transport_name))) { GNUNET_break (0); @@ -1532,6 +1744,7 @@ send_session_connect (struct NeighbourAddress *na) UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); + } @@ -1549,7 +1762,7 @@ send_session_connect_ack_message (const struct GNUNET_HELLO_Address *address, { struct GNUNET_TRANSPORT_PluginFunctions *papi; struct SessionConnectMessage connect_msg; - + if (NULL == (papi = GST_plugins_find (address->transport_name))) { GNUNET_break (0); @@ -1572,6 +1785,7 @@ send_session_connect_ack_message (const struct GNUNET_HELLO_Address *address, UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); + } @@ -1589,7 +1803,7 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating new neighbour entry for `%s'\n", GNUNET_i2s (peer)); - n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); + n = MEMDEBUG_malloc (sizeof (struct NeighbourMapEntry), __LINE__); n->id = *peer; n->state = S_NOT_CONNECTED; n->latency = GNUNET_TIME_UNIT_FOREVER_REL; @@ -1668,6 +1882,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) case S_INIT_ATS: case S_INIT_BLACKLIST: case S_CONNECT_SENT: + case S_CONNECT_RECV_BLACKLIST_INBOUND: case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: case S_CONNECT_RECV_ACK: @@ -1704,7 +1919,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); GNUNET_ATS_reset_backoff (GST_ats, target); - GNUNET_ATS_suggest_address (GST_ats, target); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, target); } @@ -1728,14 +1943,6 @@ handle_test_blacklist_cont (void *cls, "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) - { - /* valid new address, let ATS know! */ - GNUNET_ATS_address_update (GST_ats, - bcc->na.address, - bcc->na.session, - bcc->ats, bcc->ats_count); - } if (NULL == (n = lookup_neighbour (peer))) goto cleanup; /* nobody left to care about new address */ switch (n->state) @@ -1777,7 +1984,7 @@ handle_test_blacklist_cont (void *cls, 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); } break; case S_CONNECT_SENT: @@ -1791,9 +1998,23 @@ handle_test_blacklist_cont (void *cls, n->connect_ack_timestamp); } break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: + if (GNUNET_OK == result) + { + /* valid new address, let ATS know! */ + GNUNET_ATS_address_add (GST_ats, + bcc->na.address, + bcc->na.session, + bcc->ats, bcc->ats_count); + } + n->state = S_CONNECT_RECV_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + GNUNET_ATS_reset_backoff (GST_ats, peer); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer); + break; case S_CONNECT_RECV_ATS: /* still waiting on ATS suggestion, don't care about blacklist */ - break; + 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 */ @@ -1818,7 +2039,7 @@ handle_test_blacklist_cont (void *cls, 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); } break; case S_CONNECT_RECV_ACK: @@ -1863,7 +2084,7 @@ handle_test_blacklist_cont (void *cls, 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); } break; case S_RECONNECT_SENT: @@ -1919,11 +2140,12 @@ handle_test_blacklist_cont (void *cls, break; } cleanup: - GNUNET_HELLO_address_free (bcc->na.address); + MEMDEBUG_free (bcc->na.address, __LINE__); + //GNUNET_HELLO_address_free (bcc->na.address); GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bcc); - GNUNET_free (bcc); + MEMDEBUG_free (bcc, __LINE__); } @@ -1951,10 +2173,11 @@ check_blacklist (const struct GNUNET_PeerIdentity *peer, struct GST_BlacklistCheck *bc; bcc = - GNUNET_malloc (sizeof (struct BlackListCheckContext) + - sizeof (struct GNUNET_ATS_Information) * ats_count); + MEMDEBUG_malloc (sizeof (struct BlackListCheckContext) + + sizeof (struct GNUNET_ATS_Information) * ats_count, __LINE__); bcc->ats_count = ats_count; bcc->na.address = GNUNET_HELLO_address_copy (address); + MEMDEBUG_add_alloc (bcc->na.address, GNUNET_HELLO_address_get_size (address), __LINE__); bcc->na.session = session; bcc->na.connect_timestamp = ts; bcc->ats = (struct GNUNET_ATS_Information *) &bcc[1]; @@ -1998,6 +2221,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, 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); @@ -2013,18 +2237,21 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, 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); + n->state = S_CONNECT_RECV_BLACKLIST_INBOUND; + /* Do a blacklist check for the new address */ check_blacklist (peer, ts, address, session, ats, ats_count); break; case S_INIT_ATS: + /* CONNECT message takes priority over us asking ATS for address */ + n->state = S_CONNECT_RECV_BLACKLIST_INBOUND; + /* fallthrough */ case S_INIT_BLACKLIST: case S_CONNECT_SENT: + case S_CONNECT_RECV_BLACKLIST_INBOUND: case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: case S_CONNECT_RECV_ACK: @@ -2068,7 +2295,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, n = setup_neighbour (peer); n->state = S_CONNECT_RECV_ATS; GNUNET_ATS_reset_backoff (GST_ats, peer); - GNUNET_ATS_suggest_address (GST_ats, peer); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer); break; case S_DISCONNECT_FINISHED: /* should not be possible */ @@ -2118,6 +2345,8 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, if (NULL == (papi = GST_plugins_find (address->transport_name))) { /* we don't have the plugin for this address */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "2348 : `%s' \n", address->transport_name); GNUNET_ATS_address_destroyed (GST_ats, address, NULL); return; } @@ -2125,11 +2354,27 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, { GNUNET_break (0); if (strlen (address->transport_name) > 0) - GNUNET_ATS_address_destroyed (GST_ats, address, session); + GNUNET_ATS_address_destroyed (GST_ats, address, NULL); return; } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "ATS tells us to switch to address '%s' session %p for " + "peer `%s' in state %s (quota in/out %u %u )\n", + (address->address_length != 0) ? GST_plugins_a2s (address): "<inbound>", + session, + GNUNET_i2s (peer), + print_state (n->state), + ntohl (bandwidth_in.value__), + ntohl (bandwidth_out.value__)); + if (NULL == session) + { session = papi->get_session (papi->cls, address); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Obtained new session for peer `%s' and address '%s': %p\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address), session); + } if (NULL == session) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -2138,10 +2383,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, GNUNET_ATS_address_destroyed (GST_ats, address, NULL); return; } - 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): "<inbound>", - GNUNET_i2s (peer)); switch (n->state) { case S_NOT_CONNECTED: @@ -2185,6 +2426,12 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, n->connect_ack_timestamp, address, session, ats, ats_count); break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: + 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 @@ -2308,9 +2555,9 @@ master_task (void *cls, 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", + "Master task runs for neighbour `%s' in state %s with timeout in %llu ms\n", GNUNET_i2s (&n->id), - n->state, + print_state(n->state), (unsigned long long) delay.rel_value); switch (n->state) { @@ -2352,6 +2599,17 @@ master_task (void *cls, return; } break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting BLACKLIST to approve address to use for received CONNECT\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + } + break; case S_CONNECT_RECV_ATS: if (0 == delay.rel_value) { @@ -2454,7 +2712,6 @@ master_task (void *cls, 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: @@ -2530,6 +2787,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, 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); @@ -2568,7 +2826,14 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, gettext_noop ("# peers connected"), ++neighbours_connected, GNUNET_NO); - connect_notify_cb (callback_cls, &n->id, ats, ats_count); + connect_notify_cb (callback_cls, &n->id, ats, ats_count, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out); + /* Tell ATS that the outbound session we created to send CONNECT was successfull */ + GNUNET_ATS_address_add (GST_ats, + n->primary_address.address, + n->primary_address.session, + ats, ats_count); set_address (&n->primary_address, n->primary_address.address, n->primary_address.session, @@ -2577,6 +2842,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, GNUNET_YES); send_session_ack_message (n); break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: case S_CONNECT_RECV_ACK: @@ -2612,6 +2878,10 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, 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); + GNUNET_ATS_address_add(GST_ats, + n->alternative_address.address, + n->alternative_address.session, + ats, ats_count); set_address (&n->primary_address, n->alternative_address.address, n->alternative_address.session, @@ -2644,8 +2914,10 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, * * @param peer identity of the peer where the session died * @param session session that is gone + * @return GNUNET_YES if this was a session used, GNUNET_NO if + * this session was not in use */ -void +int GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, struct Session *session) { @@ -2661,15 +2933,16 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, if (bcc->na.session == session) { GST_blacklist_test_cancel (bcc->bc); - GNUNET_HELLO_address_free (bcc->na.address); + MEMDEBUG_free (bcc->na.address, __LINE__); + //GNUNET_HELLO_address_free (bcc->na.address); GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bcc); - GNUNET_free (bcc); + MEMDEBUG_free (bcc, __LINE__); } } if (NULL == (n = lookup_neighbour (peer))) - return; /* can't affect us */ + return GNUNET_NO; /* can't affect us */ if (session != n->primary_address.session) { if (session == n->alternative_address.session) @@ -2681,42 +2954,42 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, else GNUNET_break (0); } - return; /* doesn't affect us further */ + return GNUNET_NO; /* doesn't affect us further */ } n->expect_latency_response = GNUNET_NO; - switch (n->state) { case S_NOT_CONNECTED: GNUNET_break (0); free_neighbour (n, GNUNET_NO); - return; + return GNUNET_YES; case S_INIT_ATS: GNUNET_break (0); free_neighbour (n, GNUNET_NO); - return; + return GNUNET_YES; 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); break; + case S_CONNECT_RECV_BLACKLIST_INBOUND: 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; + return GNUNET_YES; 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); break; case S_RECONNECT_ATS: /* we don't have an address, how can it go down? */ @@ -2727,7 +3000,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, 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); + n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id); break; case S_CONNECTED_SWITCHING_BLACKLIST: /* primary went down while we were checking secondary against @@ -2752,6 +3025,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, break; case S_DISCONNECT_FINISHED: /* neighbour was freed and plugins told to terminate session */ + return GNUNET_NO; break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); @@ -2761,6 +3035,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, if (GNUNET_SCHEDULER_NO_TASK != n->task) GNUNET_SCHEDULER_cancel (n->task); n->task = GNUNET_SCHEDULER_add_now (&master_task, n); + return GNUNET_YES; } @@ -2814,7 +3089,13 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, gettext_noop ("# peers connected"), ++neighbours_connected, GNUNET_NO); - connect_notify_cb (callback_cls, &n->id, ats, ats_count); + connect_notify_cb (callback_cls, &n->id, ats, ats_count, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out); + GNUNET_ATS_address_add(GST_ats, + n->primary_address.address, + n->primary_address.session, + ats, ats_count); set_address (&n->primary_address, n->primary_address.address, n->primary_address.session, @@ -2888,7 +3169,7 @@ GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity { struct NeighbourMapEntry *n; const struct SessionDisconnectMessage *sdm; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received DISCONNECT message from peer `%s'\n", @@ -2972,13 +3253,31 @@ struct IteratorContext * @return GNUNET_OK (continue to iterate) */ static int -neighbours_iterate (void *cls, const GNUNET_HashCode * key, void *value) +neighbours_iterate (void *cls, const struct GNUNET_HashCode * key, void *value) { struct IteratorContext *ic = cls; struct NeighbourMapEntry *n = value; if (GNUNET_YES == test_connected (n)) - ic->cb (ic->cb_cls, &n->id, NULL, 0, n->primary_address.address); + { + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out; + + if (NULL != n->primary_address.address) + { + bandwidth_in = n->primary_address.bandwidth_in; + bandwidth_out = n->primary_address.bandwidth_out; + } + else + { + bandwidth_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; + bandwidth_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; + } + + ic->cb (ic->cb_cls, &n->id, NULL, 0, + n->primary_address.address, + bandwidth_in, bandwidth_out); + } return GNUNET_OK; } @@ -3041,14 +3340,20 @@ GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer) switch (n->state) { case S_CONNECTED: + case S_CONNECTED_SWITCHING_CONNECT_SENT: + case S_CONNECTED_SWITCHING_BLACKLIST: case S_RECONNECT_SENT: case S_RECONNECT_ATS: + case S_RECONNECT_BLACKLIST: return n->latency; case S_NOT_CONNECTED: case S_INIT_BLACKLIST: case S_INIT_ATS: - case S_CONNECT_SENT: + case S_CONNECT_RECV_BLACKLIST_INBOUND: + case S_CONNECT_RECV_ATS: case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + case S_CONNECT_SENT: case S_DISCONNECT: case S_DISCONNECT_FINISHED: return GNUNET_TIME_UNIT_FOREVER_REL; @@ -3087,18 +3392,20 @@ GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *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 max_fds maximum number of fds to use */ void GST_neighbours_start (void *cls, - GNUNET_TRANSPORT_NotifyConnect connect_cb, + NotifyConnect connect_cb, GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, - GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb) + GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb, + unsigned int max_fds) { 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); + neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO); } @@ -3111,7 +3418,7 @@ GST_neighbours_start (void *cls, * @return GNUNET_OK (continue to iterate) */ static int -disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value) +disconnect_all_neighbours (void *cls, const struct GNUNET_HashCode * key, void *value) { struct NeighbourMapEntry *n = value; diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 23091b7..f6e3387 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h @@ -29,6 +29,7 @@ #include "gnunet_statistics_service.h" #include "gnunet_transport_service.h" #include "gnunet_transport_plugin.h" +#include "transport.h" #include "gnunet_util_lib.h" // TODO: @@ -43,12 +44,14 @@ * @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 a neighbour's active address changes + * @param max_fds maximum number of fds to use */ void GST_neighbours_start (void *cls, - GNUNET_TRANSPORT_NotifyConnect connect_cb, + NotifyConnect connect_cb, GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, - GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb); + GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb, + unsigned int max_fds); /** @@ -83,7 +86,9 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target); * @param cls closure * @param success GNUNET_OK on success, GNUNET_NO on failure, GNUNET_SYSERR if we're not connected */ -typedef void (*GST_NeighbourSendContinuation) (void *cls, int success); +typedef void (*GST_NeighbourSendContinuation) (void *cls, int success, + size_t bytes_payload, + size_t bytes_on_wire); /** @@ -170,6 +175,8 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target); * @param ats performance data * @param ats_count number of entries in ats (including 0-termination) * @param address the address (or NULL) + * @param bandwidth_in inbound quota in NBO + * @param bandwidth_out outbound quota in NBO */ typedef void (*GST_NeighbourIterator) (void *cls, const struct GNUNET_PeerIdentity * @@ -177,7 +184,9 @@ typedef void (*GST_NeighbourIterator) (void *cls, const struct GNUNET_ATS_Information * ats, uint32_t ats_count, const struct GNUNET_HELLO_Address * - address); + address, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out); /** @@ -195,8 +204,10 @@ GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls); * * @param peer identity of the peer where the session died * @param session session that is gone + * @return GNUNET_YES if this was a session used, GNUNET_NO if + * this session was not in use */ -void +int GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, struct Session *session); diff --git a/src/transport/gnunet-service-transport_plugins.c b/src/transport/gnunet-service-transport_plugins.c index fc14b6e..1f3727b 100644 --- a/src/transport/gnunet-service-transport_plugins.c +++ b/src/transport/gnunet-service-transport_plugins.c @@ -197,6 +197,39 @@ GST_plugins_find (const char *name) /** + * Obtain the plugin API based on a the stripped plugin name after the underscore. + * + * Example: GST_plugins_printer_find (http_client) will return all plugins + * starting with the prefix "http": + * http_client or server if loaded + * + * @param name name of the plugin + * @return the plugin's API, NULL if the plugin is not loaded + */ +struct GNUNET_TRANSPORT_PluginFunctions * +GST_plugins_printer_find (const char *name) +{ + struct TransportPlugin *head = plugins_head; + + char *stripped = GNUNET_strdup (name); + char *sep = strchr (stripped, '_'); + if (NULL != sep) + sep[0] = '\0'; + + while (head != NULL) + { + if (head->short_name == strstr (head->short_name, stripped)) + break; + head = head->next; + } + GNUNET_free (stripped); + if (NULL == head) + return NULL; + return head->api; +} + + +/** * Convert a given address to a human-readable format. Note that the * return value will be overwritten on the next call to this function. * @@ -211,7 +244,7 @@ GST_plugins_a2s (const struct GNUNET_HELLO_Address *address) if (address == NULL) return "<inbound>"; - api = GST_plugins_find (address->transport_name); + api = GST_plugins_printer_find (address->transport_name); if (NULL == api) return "<plugin unknown>"; if (0 == address->address_length) diff --git a/src/transport/gnunet-service-transport_plugins.h b/src/transport/gnunet-service-transport_plugins.h index 04bb5ea..97e8f4c 100644 --- a/src/transport/gnunet-service-transport_plugins.h +++ b/src/transport/gnunet-service-transport_plugins.h @@ -66,6 +66,19 @@ GST_plugins_unload (void); struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find (const char *name); +/** + * Obtain the plugin API based on a the stripped plugin name after the underscore. + * + * Example: GST_plugins_printer_find (http_client) will return all plugins + * starting with the prefix "http": + * http_client or server if loaded + * + * @param name name of the plugin + * @return the plugin's API, NULL if the plugin is not loaded + */ +struct GNUNET_TRANSPORT_PluginFunctions * +GST_plugins_printer_find (const char *name); + /** * Convert a given address to a human-readable format. Note that the diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 8421969..3598a34 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -34,6 +34,7 @@ #include "gnunet_peerinfo_service.h" #include "gnunet_signatures.h" +#define KEEP_093_COMPATIBILITY GNUNET_NO /** * How long is a PONG signature valid? We'll recycle a signature until @@ -307,6 +308,16 @@ static struct GNUNET_PEERINFO_NotifyContext *pnc; /** + * Minimum delay between to validations + */ +static struct GNUNET_TIME_Relative validation_delay; + +/** + * When is next validation allowed + */ +static struct GNUNET_TIME_Absolute validation_next; + +/** * Context for the validation entry match function. */ struct ValidationEntryMatchContext @@ -334,7 +345,7 @@ struct ValidationEntryMatchContext * GNUNET_NO if the entry does match */ static int -validation_entry_match (void *cls, const GNUNET_HashCode * key, void *value) +validation_entry_match (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ValidationEntryMatchContext *vemc = cls; struct ValidationEntry *ve = value; @@ -357,7 +368,7 @@ validation_entry_match (void *cls, const GNUNET_HashCode * key, void *value) * @return GNUNET_YES (continue to iterate) */ static int -cleanup_validation_entry (void *cls, const GNUNET_HashCode * key, void *value) +cleanup_validation_entry (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ValidationEntry *ve = value; @@ -432,6 +443,7 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, struct ValidationEntry *ve = cls; struct TransportPingMessage ping; struct GNUNET_TRANSPORT_PluginFunctions *papi; + struct GNUNET_TIME_Absolute next; const struct GNUNET_MessageHeader *hello; ssize_t ret; size_t tsize; @@ -439,8 +451,20 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, uint16_t hsize; ve->bc = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s' %s\n", - GNUNET_i2s (pid), GST_plugins_a2s (ve->address)); + + if (GNUNET_NO == result) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist denies to send PING to `%s' %s %s\n", + GNUNET_i2s (pid), GST_plugins_a2s (ve->address), ve->address->transport_name); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s' %s %s\n", + GNUNET_i2s (pid), GST_plugins_a2s (ve->address), ve->address->transport_name); + + next = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), validation_delay); + if (next.abs_value > validation_next.abs_value) + validation_next = next; /* We're going to send a PING so delay next validation */ slen = strlen (ve->address->transport_name) + 1; hello = GST_hello_get (); @@ -478,7 +502,7 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, memcpy (&message_buf[sizeof (struct TransportPingMessage) + hsize], ve->address->transport_name, slen); memcpy (&message_buf[sizeof (struct TransportPingMessage) + slen + hsize], - ve->address, ve->address->address_length); + ve->address->address, ve->address->address_length); papi = GST_plugins_find (ve->address->transport_name); if (papi == NULL) ret = -1; @@ -528,6 +552,7 @@ revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct ValidationEntry *ve = cls; struct GNUNET_TIME_Relative canonical_delay; struct GNUNET_TIME_Relative delay; + struct GNUNET_TIME_Relative blocked_for; struct GST_BlacklistCheck *bc; uint32_t rdelay; @@ -552,16 +577,39 @@ revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); return; } + blocked_for = GNUNET_TIME_absolute_get_remaining(validation_next); + if ((blocked_for.rel_value) > 0) + { + /* Validations are blocked, have to wait for blocked_for ms */ + ve->revalidation_task = + GNUNET_SCHEDULER_add_delayed (blocked_for, &revalidate_address, ve); + return; + } ve->revalidation_block = GNUNET_TIME_relative_to_absolute (canonical_delay); /* schedule next PINGing with some extra random delay to avoid synchronous re-validations */ rdelay = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, canonical_delay.rel_value); - delay = - GNUNET_TIME_relative_add (canonical_delay, + + /* Debug code for mantis 0002726*/ + if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value == + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, rdelay).rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Revalidation interval for peer `%s' for is FOREVER (debug: rdelay: %llu, canonical delay %llu)\n", + GNUNET_i2s (&ve->pid), + (unsigned long long) delay.rel_value, + (unsigned long long) canonical_delay.rel_value); + delay = canonical_delay; + } + else + { + delay = GNUNET_TIME_relative_add (canonical_delay, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, rdelay)); + } + /* End debug code for mantis 0002726*/ ve->revalidation_task = GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); @@ -661,7 +709,7 @@ add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, if (GNUNET_SCHEDULER_NO_TASK == ve->revalidation_task) ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); - GNUNET_ATS_address_update (GST_ats, address, NULL, NULL, 0); + GNUNET_ATS_address_add (GST_ats, address, NULL, NULL, 0); return GNUNET_OK; } @@ -691,11 +739,17 @@ process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer, /** * Start the validation subsystem. + * + * @param max_fds maximum number of fds to use */ void -GST_validation_start () +GST_validation_start (unsigned int max_fds) { - validation_map = GNUNET_CONTAINER_multihashmap_create (VALIDATION_MAP_SIZE); + validation_next = GNUNET_TIME_absolute_get(); + validation_delay.rel_value = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value) / max_fds; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delay between validations: %u ms\n ", validation_delay.rel_value); + validation_map = GNUNET_CONTAINER_multihashmap_create (VALIDATION_MAP_SIZE, + GNUNET_NO); pnc = GNUNET_PEERINFO_notify (GST_cfg, &process_peerinfo_hello, NULL); } @@ -788,6 +842,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, size_t alen; size_t slen; ssize_t ret; + int buggy = GNUNET_NO; struct GNUNET_HELLO_Address address; if (ntohs (hdr->size) < sizeof (struct TransportPingMessage)) @@ -817,7 +872,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, sig_cache = NULL; sig_cache_exp = NULL; - if (0 < alen) + if (alen > 0) { addrend = memchr (addr, '\0', alen); if (NULL == addrend) @@ -831,15 +886,45 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, address.address = addrend; address.address_length = alen; address.transport_name = addr; - address.peer = *sender; - if (GNUNET_YES != - GST_hello_test_address (&address, &sig_cache, &sig_cache_exp)) + address.peer = GST_my_identity; + + + if (GNUNET_YES != GST_hello_test_address (&address, &sig_cache, &sig_cache_exp)) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _ - ("Not confirming PING with address `%s' since I cannot confirm having this address.\n"), - GST_plugins_a2s (&address)); - return; +#if KEEP_093_COMPATIBILITY + int idsize = sizeof (GST_my_identity); + if (alen <= idsize) + { + if (0 == memcmp (address.address, &GST_my_identity, alen)) + buggy = GNUNET_YES; + } + else if (alen <= (idsize + strlen (address.transport_name))) + { + char *achar = (char *) &address.address; + if ((0 == memcmp (address.address, &GST_my_identity, idsize)) && + (0 == memcmp (&achar[idsize], address.transport_name, alen - idsize))) + buggy = GNUNET_YES; + } + else + { + /* Not predicatable */ + return; + } +#endif + if (GNUNET_NO == buggy) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Not confirming PING from peer `%s' with address `%s' since I cannot confirm having this address.\n", + GNUNET_i2s (sender), + GST_plugins_a2s (&address)); + return; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Received a PING message with validation bug from `%s'\n"), + GNUNET_i2s (sender)); + } } } else @@ -853,6 +938,14 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, sig_cache_exp = &no_address_signature_expiration; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "I am `%s', sending PONG to peer `%s'\n", + GNUNET_h2s (&GST_my_identity.hashPubKey), + GNUNET_i2s (sender)); + + /* message with structure: + * [TransportPongMessage][Transport name][Address] */ + pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen); pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen); @@ -862,27 +955,64 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + alen + slen); pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN); - pong->challenge = ping->challenge; + memcpy (&pong->challenge, &ping->challenge, sizeof (ping->challenge)); pong->addrlen = htonl (alen + slen); - memcpy (&pong[1], addr, slen); - memcpy (&((char *) &pong[1])[slen], addrend, alen); - if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value < - PONG_SIGNATURE_LIFETIME.rel_value / 4) + memcpy (&pong[1], addr, slen); /* Copy transport plugin */ +#if KEEP_093_COMPATIBILITY + if (GNUNET_YES == buggy) { - /* create / update cached sig */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating PONG signature to indicate ownership.\n"); - *sig_cache_exp = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); - pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); + int idsize = sizeof (GST_my_identity); + if (alen <= idsize) + { + memcpy (&((char *) &pong[1])[slen], &GST_my_identity, alen); + } + else if (alen <= (idsize + strlen (address.transport_name) + 1)) + { + memcpy (&((char *) &pong[1])[slen], &GST_my_identity, idsize); + memcpy (&((char *) &pong[1])[slen + idsize], address.transport_name, alen-idsize); + } + else + { + /* If this would happen, we would have a inconsistent PING we cannot reproduce */ + GNUNET_free (pong); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating buggy PONG signature to indicate ownership.\n"); + pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME)); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (GST_my_private_key, &pong->purpose, - sig_cache)); + &pong->signature)); } else { - pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); +#endif + if (alen > 0) + { + GNUNET_assert (NULL != addrend); + memcpy (&((char *) &pong[1])[slen], addrend, alen); + } + if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value < + PONG_SIGNATURE_LIFETIME.rel_value / 4) + { + /* create / update cached sig */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating PONG signature to indicate ownership.\n"); + *sig_cache_exp = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); + pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_rsa_sign (GST_my_private_key, &pong->purpose, + sig_cache)); + } + else + { + pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); + } + pong->signature = *sig_cache; + +#if KEEP_093_COMPATIBILITY } - pong->signature = *sig_cache; +#endif GNUNET_assert (sender_address != NULL); @@ -1031,6 +1161,9 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, gettext_noop ("# PONG messages received"), 1, GNUNET_NO); + /* message with structure: + * [TransportPongMessage][Transport name][Address] */ + pong = (const struct TransportPongMessage *) hdr; tname = (const char *) &pong[1]; size = ntohs (hdr->size) - sizeof (struct TransportPongMessage); @@ -1068,7 +1201,10 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, &pong->purpose, &pong->signature, &ve->public_key)) { - GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid signature on address %s:%s from peer `%s'\n", + tname, GST_plugins_a2s (ve->address), + GNUNET_i2s (sender)); return; } @@ -1083,7 +1219,6 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Address validated for peer `%s' with plugin `%s': `%s'\n", - GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address)); /* validity achieved, remember it! */ ve->expecting_pong = GNUNET_NO; @@ -1091,10 +1226,9 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); { struct GNUNET_ATS_Information ats; - ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); ats.value = htonl ((uint32_t) ve->latency.rel_value); - GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1); + GNUNET_ATS_address_add (GST_ats, ve->address, NULL, &ats, 1); } /* build HELLO to store in PEERINFO */ ve->copied = GNUNET_NO; @@ -1131,11 +1265,11 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) /* Add peer identity without addresses to peerinfo service */ h = GNUNET_HELLO_create (&vac.public_key, NULL, NULL); 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", GNUNET_i2s (&vac.pid)); -#endif + GNUNET_free (h); GNUNET_assert (NULL == GNUNET_HELLO_iterate_addresses (hm, GNUNET_NO, @@ -1171,7 +1305,7 @@ struct IteratorContext * @return GNUNET_OK (continue to iterate) */ static int -iterate_addresses (void *cls, const GNUNET_HashCode * key, void *value) +iterate_addresses (void *cls, const struct GNUNET_HashCode * key, void *value) { struct IteratorContext *ic = cls; struct ValidationEntry *ve = value; diff --git a/src/transport/gnunet-service-transport_validation.h b/src/transport/gnunet-service-transport_validation.h index dd5bcd6..6f1206f 100644 --- a/src/transport/gnunet-service-transport_validation.h +++ b/src/transport/gnunet-service-transport_validation.h @@ -34,9 +34,11 @@ /** * Start the validation subsystem. + * + * @param max_fds maximum number of fds to use */ void -GST_validation_start (void); +GST_validation_start (unsigned int max_fds); /** diff --git a/src/transport/gnunet-transport-certificate-creation b/src/transport/gnunet-transport-certificate-creation deleted file mode 100755 index b5cffb2..0000000 --- a/src/transport/gnunet-transport-certificate-creation +++ /dev/null @@ -1,148 +0,0 @@ -#! /bin/bash - -# gnunet-transport-certificate-creation - temporary wrapper script for .libs/gnunet-transport-certificate-creation -# Generated by ltmain.sh (GNU libtool) 2.2.6b Debian-2.2.6b-2 -# -# The gnunet-transport-certificate-creation program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='/bin/sed -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -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 - # install mode needs the following variables: - generated_by_libtool_version='2.2.6b' - notinst_deplibs=' ../../src/util/libgnunetutil.la' -else - # When we are sourced in execute mode, $file and $ECHO are already set. - if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then - ECHO="echo" - file="$0" - # Make sure echo works. - if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then - # Yippee, $ECHO works! - : - else - # Restart under the correct shell, and then maybe $ECHO will work. - exec /bin/bash "$0" --no-reexec ${1+"$@"} - fi - fi - - # Find the directory that this script lives in. - thisdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "x$thisdir" = "x$file" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'` - while test -n "$file"; do - destdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'` - - # If there was a directory component, then change thisdir. - if test "x$destdir" != "x$file"; then - case "$destdir" in - [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; - *) thisdir="$thisdir/$destdir" ;; - esac - fi - - file=`$ECHO "X$file" | $Xsed -e 's%^.*/%%'` - file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'` - done - - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no - if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then - # special case for '.' - if test "$thisdir" = "."; then - thisdir=`pwd` - fi - # remove .libs from thisdir - case "$thisdir" in - *[\\/].libs ) thisdir=`$ECHO "X$thisdir" | $Xsed -e 's%[\\/][^\\/]*$%%'` ;; - .libs ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=`cd "$thisdir" && pwd` - test -n "$absdir" && thisdir="$absdir" - - program=lt-'gnunet-transport-certificate-creation' - progdir="$thisdir/.libs" - - if test ! -f "$progdir/$program" || - { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \ - test "X$file" != "X$progdir/$program"; }; then - - file="$$-$program" - - if test ! -d "$progdir"; then - mkdir "$progdir" - else - rm -f "$progdir/$file" - fi - - # relink executable if necessary - if test -n "$relink_command"; then - if relink_command_output=`eval $relink_command 2>&1`; then : - else - echo "$relink_command_output" >&2 - rm -f "$progdir/$file" - exit 1 - fi - fi - - mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || - { rm -f "$progdir/$program"; - mv -f "$progdir/$file" "$progdir/$program"; } - rm -f "$progdir/$file" - fi - - if test -f "$progdir/$program"; then - if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then - # Run the actual program with our arguments. - - exec "$progdir/$program" ${1+"$@"} - - $ECHO "$0: cannot exec $program $*" 1>&2 - exit 1 - fi - else - # The program doesn't exist. - $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2 - $ECHO "This script is just a wrapper for $program." 1>&2 - echo "See the libtool documentation for more information." 1>&2 - exit 1 - fi -fi diff --git a/src/transport/gnunet-transport-certificate-creation.c b/src/transport/gnunet-transport-certificate-creation.c index c4c13dc..5ecc7de 100644 --- a/src/transport/gnunet-transport-certificate-creation.c +++ b/src/transport/gnunet-transport-certificate-creation.c @@ -22,7 +22,6 @@ * @file transport/gnunet-transport-certificate-creation.c * @brief create certificate for HTTPS transport * @author LRN - * */ #include "platform.h" #include "gnunet_disk_lib.h" @@ -32,15 +31,19 @@ static void removecerts (const char *file1, const char *file2) { - if (GNUNET_DISK_file_test (file1) == GNUNET_YES) + if (GNUNET_YES == GNUNET_DISK_file_test (file1)) { - CHMOD (file1, S_IWUSR | S_IRUSR); - REMOVE (file1); + if (0 != CHMOD (file1, S_IWUSR | S_IRUSR)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", file1); + if (0 != REMOVE (file1)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove", file1); } - if (GNUNET_DISK_file_test (file2) == GNUNET_YES) + if (GNUNET_YES == GNUNET_DISK_file_test (file2)) { - CHMOD (file2, S_IWUSR | S_IRUSR); - REMOVE (file2); + if (0 != CHMOD (file2, S_IWUSR | S_IRUSR)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", file2); + if (0 != REMOVE (file2)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove", file2); } } @@ -50,32 +53,34 @@ main (int argc, char **argv) { struct GNUNET_OS_Process *openssl; - if (argc != 3) + if (3 != argc) return 1; removecerts (argv[1], argv[2]); - close (2); /* eliminate stderr */ + (void) close (2); /* eliminate stderr */ /* Create RSA Private Key */ /* openssl genrsa -out $1 1024 2> /dev/null */ openssl = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "openssl", "openssl", "genrsa", + GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, "openssl", "openssl", "genrsa", "-out", argv[1], "1024", NULL); - if (openssl == NULL) + if (NULL == openssl) return 2; - GNUNET_assert (GNUNET_OS_process_wait (openssl) == GNUNET_OK); + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (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 */ openssl = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "openssl", "openssl", "req", + GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, "openssl", "openssl", "req", "-batch", "-days", "365", "-out", argv[2], "-new", "-x509", "-key", argv[1], NULL); - if (openssl == NULL) + if (NULL == openssl) return 3; - GNUNET_assert (GNUNET_OS_process_wait (openssl) == GNUNET_OK); + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (openssl)); GNUNET_OS_process_destroy (openssl); - CHMOD (argv[1], S_IRUSR); - CHMOD (argv[2], S_IRUSR); + if (0 != CHMOD (argv[1], S_IRUSR)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", argv[1]); + if (0 != CHMOD (argv[2], S_IRUSR)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", argv[2]); return 0; } diff --git a/src/transport/gnunet-transport-wlan-receiver.c b/src/transport/gnunet-transport-wlan-receiver.c new file mode 100644 index 0000000..ccc1d29 --- /dev/null +++ b/src/transport/gnunet-transport-wlan-receiver.c @@ -0,0 +1,116 @@ +/* + 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 transport/gnunet-transport-wlan-receiver.c + * @brief program to send via WLAN as much as possible (to test physical/theoretical throughput) + * @author David Brodski + */ +#include "platform.h" +#include "gnunet_protocols.h" +#include "plugin_transport_wlan.h" + +int +main (int argc, char *argv[]) +{ + char msg_buf[65536]; + unsigned long long count; + double bytes_per_s; + time_t start; + time_t akt; + ssize_t ret; + pid_t pid; + int commpipe[2]; /* This holds the fd for the input & output of the pipe */ + + if (2 != argc) + { + fprintf (stderr, + "This program must be started with the interface name as argument.\n"); + fprintf (stderr, + "Usage: %s interface-name\n" + "e.g. %s mon0\n", + argv[0], argv[0]); + return 1; + } + + /* Setup communication pipeline first */ + if (pipe (commpipe)) + { + fprintf (stderr, + "Failed to create pipe: %s\n", + STRERROR (errno)); + exit (1); + } + + /* Attempt to fork and check for errors */ + if ((pid = fork ()) == -1) + { + fprintf (stderr, "Failed to fork: %s\n", + STRERROR (errno)); + exit (1); + } + + if (pid) + { + /* A positive (non-negative) PID indicates the parent process */ + if (0 != close (commpipe[1])) /* Close unused side of pipe (in side) */ + fprintf (stderr, + "Failed to close fd: %s\n", + strerror (errno)); + start = time (NULL); + count = 0; + while (1) + { + ret = read (commpipe[0], msg_buf, sizeof (msg_buf)); + if (0 > ret) + { + fprintf (stderr, "read failed: %s\n", strerror (errno)); + break; + } + count += ret; + akt = time (NULL); + if (akt - start > 30) + { + bytes_per_s = count / (akt - start); + bytes_per_s /= 1024; + printf ("recv %f kb/s\n", bytes_per_s); + start = akt; + count = 0; + } + } + } + else + { + /* A zero PID indicates that this is the child process */ + (void) close (1); + if (-1 == dup2 (commpipe[1], 1)) /* Replace stdin with the in side of the pipe */ + fprintf (stderr, "dup2 failed: %s\n", strerror (errno)); + (void) close (commpipe[0]); /* Close unused side of pipe (in side) */ + /* Replace the child fork with a new process */ + if (execlp + ("gnunet-helper-transport-wlan", "gnunet-helper-transport-wlan", + argv[1], NULL) == -1) + { + fprintf (stderr, "Could not start gnunet-helper-transport-wlan!"); + _exit (1); + } + } + return 0; +} diff --git a/src/transport/gnunet-transport-wlan-sender.c b/src/transport/gnunet-transport-wlan-sender.c index daa8f02..05d1d1e 100644 --- a/src/transport/gnunet-transport-wlan-sender.c +++ b/src/transport/gnunet-transport-wlan-sender.c @@ -101,47 +101,49 @@ main (int argc, char *argv[]) unsigned int temp[6]; struct GNUNET_TRANSPORT_WLAN_MacAddress inmac; struct GNUNET_TRANSPORT_WLAN_MacAddress outmac; - int pos; - long long count; + struct GNUNET_TRANSPORT_WLAN_HelperControlMessage hcm; + unsigned long long count; double bytes_per_s; time_t start; time_t akt; int i; + ssize_t ret; + pid_t pid; + int commpipe[2]; /* This holds the fd for the input & output of the pipe */ + int macpipe[2]; /* This holds the fd for the input & output of the pipe */ if (4 != argc) { fprintf (stderr, "This program must be started with the interface and the targets and source mac as argument.\n"); fprintf (stderr, - "Usage: interface-name mac-target mac-source\n" + "Usage: interface-name mac-DST mac-SRC\n" "e.g. mon0 11-22-33-44-55-66 12-34-56-78-90-ab\n"); return 1; } if (6 != - SSCANF (argv[3], "%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, - "Usage: interface-name mac-target mac-source\n" + "Usage: interface-name mac-DST mac-SRC\n" "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[3], "%x-%x-%x-%x-%x-%x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5])) { fprintf (stderr, - "Usage: interface-name mac-target mac-source\n" + "Usage: interface-name mac-DST mac-SRC\n" "e.g. mon0 11-22-33-44-55-66 12-34-56-78-90-ab\n"); return 1; } for (i = 0; i < 6; i++) inmac.mac[i] = temp[i]; - pid_t pid; - int commpipe[2]; /* This holds the fd for the input & output of the pipe */ /* Setup communication pipeline first */ if (pipe (commpipe)) @@ -151,6 +153,13 @@ main (int argc, char *argv[]) STRERROR (errno)); exit (1); } + if (pipe (macpipe)) + { + fprintf (stderr, + "Failed to create pipe: %s\n", + STRERROR (errno)); + exit (1); + } /* Attempt to fork and check for errors */ if ((pid = fork ()) == -1) @@ -159,49 +168,66 @@ main (int argc, char *argv[]) STRERROR (errno)); exit (1); } - + memset (msg_buf, 0x42, sizeof (msg_buf)); if (pid) { /* A positive (non-negative) PID indicates the parent process */ - close (commpipe[0]); /* Close unused side of pipe (in side) */ + if (0 != close (commpipe[0])) /* Close unused side of pipe (in side) */ + fprintf (stderr, + "Failed to close fd: %s\n", + strerror (errno)); setvbuf (stdout, (char *) NULL, _IONBF, 0); /* Set non-buffered output on stdout */ - + if (0 != close (macpipe[1])) + fprintf (stderr, + "Failed to close fd: %s\n", + strerror (errno)); + if (sizeof (hcm) != read (macpipe[0], &hcm, sizeof (hcm))) + fprintf (stderr, + "Failed to read hcm...\n"); + fprintf (stderr, + "Got MAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", + hcm.mac.mac[0], hcm.mac.mac[1], + hcm.mac.mac[2], hcm.mac.mac[3], hcm.mac.mac[4], hcm.mac.mac[5]); radiotap = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) msg_buf; getRadiotapHeader (radiotap, WLAN_MTU); - pos = 0; getWlanHeader (&radiotap->frame, &outmac, &inmac, WLAN_MTU); start = time (NULL); count = 0; while (1) { - pos += write (commpipe[1], msg_buf, WLAN_MTU - pos); - if (pos % WLAN_MTU == 0) + ret = write (commpipe[1], msg_buf, WLAN_MTU); + if (0 > ret) { - pos = 0; - count++; - - if (count % 1000 == 0) - { - akt = time (NULL); - bytes_per_s = count * WLAN_MTU / (akt - start); - bytes_per_s /= 1024; - printf ("send %f kbytes/s\n", bytes_per_s); - } + fprintf (stderr, "write failed: %s\n", strerror (errno)); + break; } - + count += ret; + akt = time (NULL); + if (akt - start > 30) + { + bytes_per_s = count / (akt - start); + bytes_per_s /= 1024; + printf ("send %f kbytes/s\n", bytes_per_s); + start = akt; + count = 0; + } } } else { /* A zero PID indicates that this is the child process */ (void) close (0); + (void) close (1); if (-1 == dup2 (commpipe[0], 0)) /* Replace stdin with the in side of the pipe */ fprintf (stderr, "dup2 failed: %s\n", strerror (errno)); + if (-1 == dup2 (macpipe[1], 1)) /* Replace stdout with the out side of the pipe */ + fprintf (stderr, "dup2 failed: %s\n", strerror (errno)); (void) close (commpipe[1]); /* Close unused side of pipe (out side) */ + (void) close (macpipe[0]); /* Close unused side of pipe (in side) */ /* Replace the child fork with a new process */ - if (execl + if (execlp ("gnunet-helper-transport-wlan", "gnunet-helper-transport-wlan", argv[1], NULL) == -1) { diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index 3b6b7e4..8dd7bda 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c @@ -39,8 +39,15 @@ * 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, 30) -#define RESOLUTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) +#define RESOLUTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +#define OP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +/** + * Benchmarking block size in KB + */ +#define BLOCKSIZE 4 + /** * Which peer should we connect to? @@ -53,6 +60,16 @@ static char *cpid; static struct GNUNET_TRANSPORT_Handle *handle; /** + * Configuration handle + */ +static struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Try_connect handle + */ +struct GNUNET_TRANSPORT_TryConnectHandle * tc_handle; + +/** * Option -s. */ static int benchmark_send; @@ -78,11 +95,21 @@ static int iterate_connections; static int test_configuration; /** + * Option -c. + */ +static int monitor_connects; + +/** * Option -m. */ static int monitor_connections; /** + * Option -C. + */ +static int try_connect; + +/** * Option -n. */ static int numeric; @@ -93,6 +120,11 @@ static int numeric; static int ret; /** + * Current number of connections in monitor mode + */ +static int monitor_connect_counter; + +/** * Number of bytes of traffic we received so far. */ static unsigned long long traffic_received; @@ -113,6 +145,11 @@ static struct GNUNET_TIME_Absolute start_time; static struct GNUNET_TRANSPORT_TransmitHandle *th; /** + * + */ +struct GNUNET_TRANSPORT_PeerIterateContext *pic; + +/** * Identity of the peer we transmit to / connect to. * (equivalent to 'cpid' string). */ @@ -123,6 +160,12 @@ static struct GNUNET_PeerIdentity pid; */ static GNUNET_SCHEDULER_TaskIdentifier end; +/** + * Task for operation timeout + */ +static GNUNET_SCHEDULER_TaskIdentifier op_timeout; + + static struct GNUNET_CONTAINER_MultiHashMap *peers; /** @@ -140,6 +183,15 @@ struct GNUNET_OS_Process *resolver; */ static unsigned int resolver_users; +/** + * Number of address resolutions pending + */ +static unsigned int address_resolutions; + +/** + * Address resolutions pending in progress + */ +static unsigned int address_resolution_in_progress; /** * Context for a plugin test. @@ -166,6 +218,123 @@ struct TestContext /** + * Task run in monitor mode when the user presses CTRL-C to abort. + * Stops monitoring activity. + * + * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *' + * @param tc scheduler context + */ +static void +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TIME_Relative duration; + end = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != tc_handle) + { + GNUNET_TRANSPORT_try_connect_cancel (tc_handle); + tc_handle = NULL; + } + if (NULL != pic) + { + GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic); + pic = NULL; + } + if (NULL != th) + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(th); + th = NULL; + } + if (NULL != handle) + { + GNUNET_TRANSPORT_disconnect(handle); + handle = NULL; + } + if (NULL != peers) + { + GNUNET_CONTAINER_multihashmap_destroy (peers); + peers = NULL; + } + if (benchmark_send) + { + duration = GNUNET_TIME_absolute_get_duration (start_time); + FPRINTF (stdout, _("Transmitted %llu bytes/s (%llu bytes in %s)\n"), + 1000 * traffic_sent / (1 + duration.rel_value), traffic_sent, + GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); + } + if (benchmark_receive) + { + duration = GNUNET_TIME_absolute_get_duration (start_time); + FPRINTF (stdout, _("Received %llu bytes/s (%llu bytes in %s)\n"), + 1000 * traffic_received / (1 + duration.rel_value), + traffic_received, + GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); + } +} + +struct ResolutionContext *rc_head; +struct ResolutionContext *rc_tail; + +struct ResolutionContext +{ + struct ResolutionContext *next; + struct ResolutionContext *prev; + struct GNUNET_HELLO_Address *addrcp; + struct GNUNET_TRANSPORT_AddressToStringContext *asc; + int printed; +}; + + +static void +operation_timeout (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ResolutionContext *cur; + struct ResolutionContext *next; + op_timeout = GNUNET_SCHEDULER_NO_TASK; + if ((try_connect) || (benchmark_send) || + (benchmark_receive)) + { + FPRINTF (stdout, _("Failed to connect to `%s'\n"), GNUNET_h2s_full (&pid.hashPubKey)); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + ret = 1; + return; + } + if (iterate_connections) + { + next = rc_head; + while (NULL != (cur = next)) + { + next = cur->next; + FPRINTF (stdout, _("Failed to resolve address for peer `%s'\n"), + GNUNET_i2s (&cur->addrcp->peer)); + + GNUNET_CONTAINER_DLL_remove (rc_head, rc_tail, cur); + GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); + GNUNET_free (cur->addrcp); + GNUNET_free (cur); + + } + FPRINTF (stdout, "%s", _("Failed to list connections, timeout occured\n")); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + ret = 1; + return; + } + +} + + + +/** * Display the result of the test. * * @param tc test context @@ -279,7 +448,7 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) adv_port = bnd_port; if (NULL == resolver) resolver = - GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-resolver", + GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, "gnunet-service-resolver", "gnunet-service-resolver", NULL); resolver_users++; GNUNET_RESOLVER_connect (cfg); @@ -302,38 +471,6 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_free (plugins); } - -/** - * Shutdown, print statistics. - */ -static void -do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TIME_Relative duration; - - if (NULL != th) - { - GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); - th = NULL; - } - GNUNET_TRANSPORT_disconnect (handle); - if (benchmark_receive) - { - duration = GNUNET_TIME_absolute_get_duration (start_time); - FPRINTF (stdout, _("Received %llu bytes/s (%llu bytes in %llu ms)\n"), - 1000 * traffic_received / (1 + duration.rel_value), - traffic_received, (unsigned long long) duration.rel_value); - } - if (benchmark_send) - { - duration = GNUNET_TIME_absolute_get_duration (start_time); - FPRINTF (stdout, _("Transmitted %llu bytes/s (%llu bytes in %llu ms)\n"), - 1000 * traffic_sent / (1 + duration.rel_value), traffic_sent, - (unsigned long long) duration.rel_value); - } -} - - /** * Function called to notify a client about the socket * begin ready to queue more data. "buf" will be @@ -350,13 +487,19 @@ transmit_data (void *cls, size_t size, void *buf) { struct GNUNET_MessageHeader *m = buf; + if ((NULL == buf) && (0 == size)) + { + th = NULL; + return 0; + } + GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); m->size = ntohs (size); m->type = ntohs (GNUNET_MESSAGE_TYPE_DUMMY); memset (&m[1], 52, size - sizeof (struct GNUNET_MessageHeader)); traffic_sent += size; - th = GNUNET_TRANSPORT_notify_transmit_ready (handle, &pid, 32 * 1024, 0, + th = GNUNET_TRANSPORT_notify_transmit_ready (handle, &pid, BLOCKSIZE * 1024, 0, GNUNET_TIME_UNIT_FOREVER_REL, &transmit_data, NULL); if (verbosity > 0) @@ -379,23 +522,45 @@ static void notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { - if (verbosity > 0) - FPRINTF (stdout, _("Connected to %s\n"), GNUNET_i2s (peer)); if (0 != memcmp (&pid, peer, sizeof (struct GNUNET_PeerIdentity))) return; ret = 0; - if (benchmark_send) + if (try_connect) { - start_time = GNUNET_TIME_absolute_get (); - th = GNUNET_TRANSPORT_notify_transmit_ready (handle, peer, 32 * 1024, 0, - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_data, NULL); + /* all done, terminate instantly */ + FPRINTF (stdout, _("Successfully connected to `%s'\n"), GNUNET_h2s_full (&peer->hashPubKey)); + ret = 0; + + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } + + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + return; } - else + if (benchmark_send) { - /* all done, terminate instantly */ - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&do_disconnect, NULL); + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } + if (verbosity > 0) + FPRINTF (stdout, _("Successfully connected to `%s', starting to send benchmark data in %u Kb blocks\n"), + GNUNET_i2s (&pid), BLOCKSIZE); + start_time = GNUNET_TIME_absolute_get (); + if (NULL == th) + th = GNUNET_TRANSPORT_notify_transmit_ready (handle, peer, + BLOCKSIZE * 1024, 0, + GNUNET_TIME_UNIT_FOREVER_REL, + &transmit_data, NULL); + else + GNUNET_break (0); + return; } } @@ -410,19 +575,73 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, static void notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { - if (verbosity > 0) - FPRINTF (stdout, _("Disconnected from %s\n"), GNUNET_i2s (peer)); - if ((0 == memcmp (&pid, peer, sizeof (struct GNUNET_PeerIdentity))) && - (NULL != th)) + if (0 != memcmp (&pid, peer, sizeof (struct GNUNET_PeerIdentity))) + return; + + if (NULL != th) { GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); th = NULL; - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&do_disconnect, NULL); } + if (benchmark_send) + { + FPRINTF (stdout, _("Disconnected from peer `%s' while benchmarking\n"), GNUNET_i2s (&pid)); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + return; + } +} + +/** + * Function called to notify transport users that another + * peer connected to us. + * + * @param cls closure + * @param peer the peer that connected + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) + */ +static void +monitor_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + monitor_connect_counter ++; + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); + const char *now_str = GNUNET_STRINGS_absolute_time_to_string (now); + + FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), + now_str, + _("Connected to"), + GNUNET_i2s (peer), + monitor_connect_counter); +} + + +/** + * Function called to notify transport users that another + * peer disconnected from us. + * + * @param cls closure + * @param peer the peer that disconnected + */ +static void +monitor_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); + const char *now_str = GNUNET_STRINGS_absolute_time_to_string (now); + + GNUNET_assert (monitor_connect_counter > 0); + monitor_connect_counter --; + + FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), + now_str, + _("Disconnected from"), + GNUNET_i2s (peer), + monitor_connect_counter); } + /** * Function called by the transport for each received message. * @@ -437,22 +656,24 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { - if (!benchmark_receive) + if (benchmark_receive) + { + if (GNUNET_MESSAGE_TYPE_DUMMY != ntohs (message->type)) + return; + if (verbosity > 0) + FPRINTF (stdout, _("Received %u bytes from %s\n"), + (unsigned int) ntohs (message->size), GNUNET_i2s (peer)); + + if (traffic_received == 0) + start_time = GNUNET_TIME_absolute_get (); + traffic_received += ntohs (message->size); return; - if (verbosity > 0) - FPRINTF (stdout, _("Received %u bytes from %s\n"), - (unsigned int) ntohs (message->size), GNUNET_i2s (peer)); - if (traffic_received == 0) - start_time = GNUNET_TIME_absolute_get (); - traffic_received += ntohs (message->size); + } } -struct ResolutionContext -{ - struct GNUNET_HELLO_Address *addrcp; - int printed; -}; +static void resolve_address (const struct GNUNET_HELLO_Address *address, + int numeric); static void @@ -469,13 +690,56 @@ process_string (void *cls, const char *address) else { /* done */ + GNUNET_assert (address_resolutions > 0); + address_resolutions --; if (GNUNET_NO == rc->printed) - FPRINTF (stdout, _("Peer `%s': %s <unable to resolve address>\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name); + { + if (numeric == GNUNET_NO) + { + resolve_address (rc->addrcp, GNUNET_YES ); /* Failed to resolve address, try numeric lookup */ + } + else + FPRINTF (stdout, _("Peer `%s': %s <unable to resolve address>\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name); + } GNUNET_free (rc->addrcp); + GNUNET_CONTAINER_DLL_remove (rc_head, rc_tail, rc); GNUNET_free (rc); + if ((0 == address_resolutions) && (iterate_connections)) + { + if (GNUNET_SCHEDULER_NO_TASK != end) + { + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } + ret = 0; + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + } } } +static void resolve_address (const struct GNUNET_HELLO_Address *address, + int numeric) +{ + struct ResolutionContext *rc; + + rc = GNUNET_malloc(sizeof (struct ResolutionContext)); + GNUNET_assert (NULL != rc); + GNUNET_CONTAINER_DLL_insert (rc_head, rc_tail, rc); + address_resolutions ++; + + rc->addrcp = GNUNET_HELLO_address_copy(address); + rc->printed = GNUNET_NO; + /* Resolve address to string */ + rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, + RESOLUTION_TIMEOUT, &process_string, + rc); +} + /** * Function to call with a binary address * @@ -487,148 +751,268 @@ static void 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) { /* done */ + address_resolution_in_progress = GNUNET_NO; + pic = NULL; + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } - if (address == NULL) { FPRINTF (stdout, _("Peer `%s' disconnected\n"), GNUNET_i2s (peer)); return; } - rc = GNUNET_malloc(sizeof (struct ResolutionContext)); - rc->addrcp = GNUNET_HELLO_address_copy(address); - rc->printed = GNUNET_NO; + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, + &operation_timeout, NULL); - GNUNET_assert (NULL != rc); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received address for peer `%s': %s\n", + GNUNET_i2s (peer), address->transport_name); + resolve_address (address, numeric); +} - /* Resolve address to string */ - GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, - RESOLUTION_TIMEOUT, &process_string, - rc); +void try_connect_cb (void *cls, + const int result) +{ + static int retries = 0; + if (GNUNET_OK == result) + { + tc_handle = NULL; + return; + } + retries ++; + if (retries < 10) + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + else + { + FPRINTF (stderr, "%s", _("Failed to send connect request to transport service\n")); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + ret = 1; + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + return; + } } -/** - * Task run in monitor mode when the user presses CTRL-C to abort. - * Stops monitoring activity. - * - * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *' - * @param tc scheduler context - */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +testservice_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_TRANSPORT_PeerIterateContext *pic = cls; + int counter = 0; + ret = 1; - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic); - - if (NULL != peers) + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { - GNUNET_CONTAINER_multihashmap_destroy (peers); - peers = NULL; + FPRINTF (stderr, _("Service `%s' is not running\n"), "transport"); + return; } -} + if ((NULL != cpid) && (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (cpid, &pid.hashPubKey))) + { + FPRINTF (stderr, _("Failed to parse peer identity `%s'\n"), cpid); + return; + } + counter = benchmark_send + benchmark_receive + iterate_connections + + monitor_connections + monitor_connects + try_connect; -/** - * 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 (test_configuration) + if (1 < counter) { - do_test_configuration (cfg); + FPRINTF (stderr, _("Multiple operations given. Please choose only one operation: %s, %s, %s, %s, %s, %s\n"), + "connect", "benchmark send", "benchmark receive", "information", "monitor", "events"); + return; } - if (benchmark_send && (NULL == cpid)) + if (0 == counter) { - FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"), - "-s", "-C"); + FPRINTF (stderr, _("No operation given. Please choose one operation: %s, %s, %s, %s, %s, %s\n"), + "connect", "benchmark send", "benchmark receive", "information", "monitor", "events"); return; } - if (NULL != cpid) + + if (try_connect) /* -C: Connect to peer */ { - ret = 1; - if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (cpid, &pid.hashPubKey)) + if (NULL == cpid) { - FPRINTF (stderr, _("Failed to parse peer identity `%s'\n"), cpid); + FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"), + "-C", "-p"); + ret = 1; return; } - handle = - GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); - GNUNET_TRANSPORT_try_connect (handle, &pid); - end = - GNUNET_SCHEDULER_add_delayed (benchmark_send ? - GNUNET_TIME_UNIT_FOREVER_REL : - GNUNET_TIME_UNIT_SECONDS, &do_disconnect, - NULL); + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, + ¬ify_receive, + ¬ify_connect, + ¬ify_disconnect); + if (NULL == handle) + { + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); + ret = 1; + return; + } + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + if (NULL == tc_handle) + { + FPRINTF (stderr, "%s", _("Failed to send request to transport service\n")); + ret = 1; + return; + } + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, + &operation_timeout, NULL); + } - else if (benchmark_receive) + else if (benchmark_send) /* -s: Benchmark sending */ + { + if (NULL == cpid) + { + FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"), + "-s", "-p"); + ret = 1; + return; + } + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, + ¬ify_receive, + ¬ify_connect, + ¬ify_disconnect); + if (NULL == handle) + { + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); + ret = 1; + return; + } + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + if (NULL == tc_handle) + { + FPRINTF (stderr, "%s", _("Failed to send request to transport service\n")); + ret = 1; + return; + } + start_time = GNUNET_TIME_absolute_get (); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, + &operation_timeout, NULL); + } + else if (benchmark_receive) /* -b: Benchmark receiving */ { handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); - GNUNET_TRANSPORT_try_connect (handle, &pid); - end = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &do_disconnect, NULL); + NULL, NULL); + if (NULL == handle) + { + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); + ret = 1; + return; + } + if (verbosity > 0) + FPRINTF (stdout, "%s", _("Starting to receive benchmark data\n")); + start_time = GNUNET_TIME_absolute_get (); + } - if (iterate_connections) + else if (iterate_connections) /* -i: List all active addresses once */ + { + peers = GNUNET_CONTAINER_multihashmap_create (20, GNUNET_NO); + address_resolution_in_progress = GNUNET_YES; + pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, + (NULL == cpid) ? NULL : &pid, + GNUNET_YES, + TIMEOUT, + &process_address, (void *) cfg); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, + &operation_timeout, NULL); + } + else if (monitor_connections) /* -m: List all active addresses continously */ { - peers = GNUNET_CONTAINER_multihashmap_create (20); - GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_YES, + peers = GNUNET_CONTAINER_multihashmap_create (20, GNUNET_NO); + address_resolution_in_progress = GNUNET_YES; + pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, + (NULL == cpid) ? NULL : &pid, + GNUNET_NO, TIMEOUT, &process_address, (void *) cfg); } - if (monitor_connections) + else if (monitor_connects) /* -e : Monitor (dis)connect events continously */ { - struct GNUNET_TRANSPORT_PeerIterateContext *pic; + monitor_connect_counter = 0; + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, NULL, + &monitor_notify_connect, + &monitor_notify_disconnect); + if (NULL == handle) + { + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); + ret = 1; + return; + } + ret = 0; + } + else + { + GNUNET_break (0); + return; + } + + end = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); + +} + - pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_NO, - GNUNET_TIME_UNIT_FOREVER_REL, - &process_address, (void *) cfg); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, - pic); +/** + * 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 *mycfg) +{ + cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg; + if (test_configuration) + { + do_test_configuration (cfg); + return; } + + GNUNET_CLIENT_service_test ("transport", cfg, + GNUNET_TIME_UNIT_SECONDS, + &testservice_task, + (void *) cfg); } int main (int argc, char *const *argv) { + int res; static const struct GNUNET_GETOPT_CommandLineOption options[] = { {'b', "benchmark", NULL, - gettext_noop ("measure how fast we are receiving data (until CTRL-C)"), + gettext_noop ("measure how fast we are receiving data from all peers (until CTRL-C)"), 0, &GNUNET_GETOPT_set_one, &benchmark_receive}, - {'C', "connect", "PEER", - gettext_noop ("try to connect to the given peer"), - 1, &GNUNET_GETOPT_set_string, &cpid}, + {'C', "connect", NULL, + gettext_noop ("connect to a peer"), + 0, &GNUNET_GETOPT_set_one, &try_connect}, {'i', "information", NULL, gettext_noop ("provide information about all current connections (once)"), 0, &GNUNET_GETOPT_set_one, &iterate_connections}, {'m', "monitor", NULL, gettext_noop ("provide information about all current connections (continuously)"), 0, &GNUNET_GETOPT_set_one, &monitor_connections}, + {'e', "events", NULL, + gettext_noop ("provide information about all connects and disconnect events (continuously)"), + 0, &GNUNET_GETOPT_set_one, &monitor_connects}, {'n', "numeric", NULL, gettext_noop ("do not resolve hostnames"), 0, &GNUNET_GETOPT_set_one, &numeric}, + {'p', "peer", "PEER", + gettext_noop ("peer identity"), + 1, &GNUNET_GETOPT_set_string, &cpid}, {'s', "send", NULL, gettext_noop ("send data for benchmarking to the other peer (until CTRL-C)"), @@ -639,11 +1023,18 @@ main (int argc, char *const *argv) GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-transport", + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + res = GNUNET_PROGRAM_run (argc, argv, "gnunet-transport", gettext_noop ("Direct access to transport service."), options, - &run, NULL)) ? ret : 1; + &run, NULL); + GNUNET_free ((void *) argv); + if (GNUNET_OK == res) + return ret; + return 1; } diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c deleted file mode 100644 index d99f531..0000000 --- a/src/transport/plugin_transport_http.c +++ /dev/null @@ -1,1743 +0,0 @@ -/* - This file is part of GNUnet - (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 transport/plugin_transport_http.c - * @brief http transport service plugin - * @author Matthias Wachs - */ - -#include "plugin_transport_http.h" - -/** - * After how long do we expire an address that we - * learned from another peer if it is not reconfirmed - * by anyone? - */ -#define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6) - -/** - * Wrapper to manage IPv4 addresses - */ -struct IPv4HttpAddressWrapper -{ - /** - * Linked list next - */ - struct IPv4HttpAddressWrapper *next; - - /** - * Linked list previous - */ - struct IPv4HttpAddressWrapper *prev; - - struct IPv4HttpAddress addr; -}; - -/** - * Wrapper for IPv4 addresses. - */ -struct IPv6HttpAddressWrapper -{ - /** - * Linked list next - */ - struct IPv6HttpAddressWrapper *next; - - /** - * Linked list previous - */ - struct IPv6HttpAddressWrapper *prev; - - struct IPv6HttpAddress addr6; -}; - - -/** - * Context for address to string conversion. - */ -struct PrettyPrinterContext -{ - /** - * Function to call with the result. - */ - GNUNET_TRANSPORT_AddressStringCallback asc; - - /** - * Plugin - */ - struct Plugin *plugin; - - /** - * Clsoure for 'asc'. - */ - void *asc_cls; - - /** - * Port to add after the IP address. - */ - uint16_t port; - - uint32_t addrlen; - - int numeric; -}; - - -/** - * Encapsulation of all of the state of the plugin. - */ -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. - * - * @param cls the 'struct PrettyPrinterContext*' - * @param hostname hostname part of the address - */ -static void -append_port (void *cls, const char *hostname) -{ - struct PrettyPrinterContext *ppc = cls; - static char rbuf[INET6_ADDRSTRLEN + 13]; - - if (hostname == NULL) - { - ppc->asc (ppc->asc_cls, NULL); - GNUNET_free (ppc); - return; - } - -#if !BUILD_HTTPS - const char *protocol = "http"; -#else - const char *protocol = "https"; -#endif - GNUNET_assert ((strlen (hostname) + 7) < (INET6_ADDRSTRLEN + 13)); - if (ppc->addrlen == sizeof (struct IPv6HttpAddress)) - { - if (ppc->numeric == GNUNET_YES) - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, hostname, ppc->port); - else - { - if (strchr(hostname, ':') != NULL) - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, hostname, ppc->port); - else - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, hostname, ppc->port); - } - } - else if (ppc->addrlen == sizeof (struct IPv4HttpAddress)) - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, hostname, ppc->port); - ppc->asc (ppc->asc_cls, rbuf); -} - - - - - -/** - * 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 -http_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) -{ - GNUNET_assert (cls != NULL); - struct PrettyPrinterContext *ppc; - const void *sb; - struct sockaddr_in s4; - struct sockaddr_in6 s6; - size_t sbs; - uint16_t port = 0; - - if ((addrlen == sizeof (struct IPv6HttpAddress)) && (addr != NULL)) - { - struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr; - s6.sin6_family = AF_INET6; - s6.sin6_addr = a6->ipv6_addr; - s6.sin6_port = a6->u6_port; -#if HAVE_SOCKADDR_IN_SIN_LEN - s6.sin6_len = sizeof (struct sockaddr_in6); -#endif - sb = &s6; - sbs = sizeof (struct sockaddr_in6); - port = ntohs (a6->u6_port); - - } - else if ((addrlen == sizeof (struct IPv4HttpAddress)) && (addr != NULL)) - { - struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr; - - s4.sin_family = AF_INET; - s4.sin_addr.s_addr = a4->ipv4_addr; - s4.sin_port = a4->u4_port; -#if HAVE_SOCKADDR_IN_SIN_LEN - s4.sin_len = sizeof (struct sockaddr_in); -#endif - sb = &s4; - sbs = sizeof (struct sockaddr_in); - port = ntohs (a4->u4_port); - } - else if (0 == addrlen) - { - asc (asc_cls, "<inbound connection>"); - asc (asc_cls, NULL); - return; - } - else - { - /* invalid address */ - GNUNET_break_op (0); - asc (asc_cls, NULL); - return; - } - ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); - ppc->asc = asc; - ppc->asc_cls = asc_cls; - ppc->port = port; - ppc->plugin = cls; - ppc->addrlen = addrlen; - ppc->numeric = numeric; - GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); -} - - - -/** - * 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 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))) - return GNUNET_SYSERR; - - if (addrlen == sizeof (struct IPv4HttpAddress)) - { - struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) addr; - - while (w_tv4 != NULL) - { - if ((0 == - memcmp (&w_tv4->addr.ipv4_addr, &a4->ipv4_addr, - sizeof (struct in_addr))) && - (w_tv4->addr.u4_port == a4->u4_port)) - break; - w_tv4 = w_tv4->next; - } - if (w_tv4 != NULL) - return GNUNET_OK; - else - return GNUNET_SYSERR; - } - if (addrlen == sizeof (struct sockaddr_in6)) - { - struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) addr; - - while (w_tv6 != NULL) - { - if ((0 == - memcmp (&w_tv6->addr6.ipv6_addr, &a6->ipv6_addr, - sizeof (struct in6_addr))) && - (w_tv6->addr6.u6_port == a6->u6_port)) - break; - w_tv6 = w_tv6->next; - } - if (w_tv6 != NULL) - return GNUNET_OK; - else - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -struct GNUNET_TIME_Relative -http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message, - struct Session *session, const char *sender_address, - uint16_t sender_address_len) -{ - struct Session *s = cls; - struct Plugin *plugin = s->plugin; - struct GNUNET_TIME_Relative delay; - struct GNUNET_ATS_Information atsi[2]; - - atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - atsi[0].value = htonl (1); - atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); - 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, - 2, s, s->addr, s->addrlen); - 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 - * 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 - */ -const char * -http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) -{ - - struct IPv4HttpAddress *a4; - struct IPv6HttpAddress *a6; - char *address; - static char rbuf[INET6_ADDRSTRLEN + 13]; - uint16_t port; - int res = 0; - - if (addrlen == sizeof (struct IPv6HttpAddress)) - { - a6 = (struct IPv6HttpAddress *) addr; - address = GNUNET_malloc (INET6_ADDRSTRLEN); - GNUNET_assert (NULL != - inet_ntop (AF_INET6, &a6->ipv6_addr, address, - INET6_ADDRSTRLEN)); - port = ntohs (a6->u6_port); - } - else if (addrlen == sizeof (struct IPv4HttpAddress)) - { - a4 = (struct IPv4HttpAddress *) addr; - address = GNUNET_malloc (INET_ADDRSTRLEN); - GNUNET_assert (NULL != - inet_ntop (AF_INET, &(a4->ipv4_addr), address, - INET_ADDRSTRLEN)); - port = ntohs (a4->u4_port); - } - else - { - /* invalid address */ - GNUNET_break (0); - return NULL; - } -#if !BUILD_HTTPS - char *protocol = "http"; -#else - char *protocol = "https"; -#endif - - GNUNET_assert (strlen (address) + 7 < (INET6_ADDRSTRLEN + 13)); - if (addrlen == sizeof (struct IPv6HttpAddress)) - res = - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, - address, port); - else if (addrlen == sizeof (struct IPv4HttpAddress)) - res = - GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, address, - port); - - GNUNET_free (address); - GNUNET_assert (res != 0); - return rbuf; -} - - -struct Session * -lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - struct Session *session, const void *addr, size_t addrlen, - int force_address) -{ - struct Session *t; - int e_peer; - int e_addr; - - for (t = plugin->head; NULL != t; t = t->next) - { -#if 0 - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - "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 %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", - memcmp (addr, t->addr, addrlen)); -#endif - e_peer = GNUNET_NO; - e_addr = GNUNET_NO; - if (0 == memcmp (target, &t->target, sizeof (struct GNUNET_PeerIdentity))) - { - e_peer = GNUNET_YES; - if ( (addrlen == t->addrlen) && - (0 == memcmp (addr, t->addr, addrlen)) ) - e_addr = GNUNET_YES; - if ( (t == session) && - (t->addrlen == session->addrlen) && - (0 == memcmp (session->addr, t->addr, t->addrlen)) ) - e_addr = GNUNET_YES; - } - - if ( ((e_peer == GNUNET_YES) && (force_address == GNUNET_NO)) || - ((e_peer == GNUNET_YES) && (force_address == GNUNET_YES) && (e_addr == GNUNET_YES)) || - ((e_peer == GNUNET_YES) && (force_address == GNUNET_SYSERR)) ) - return t; - } - return NULL; -} - - -struct Session * -lookup_session (struct Plugin *plugin, - const struct GNUNET_HELLO_Address *address) -{ - struct Session *pos; - - for (pos = plugin->head; NULL != pos; pos = pos->next) - if ( (0 == memcmp (&address->peer, &pos->target, sizeof (struct GNUNET_PeerIdentity))) && - (address->address_length == pos->addrlen) && - (0 == memcmp (address->address, pos->addr, pos->addrlen)) ) - return pos; - return NULL; -} - - -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); - s->msg_tk = NULL; - } - GNUNET_free (s->addr); - GNUNET_free_non_null (s->server_recv); - GNUNET_free_non_null (s->server_send); - GNUNET_free (s); -} - - -struct Session * -create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - const void *addr, size_t addrlen) -{ - struct Session *s = NULL; - - GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || - (addrlen == sizeof (struct IPv4HttpAddress))); - s = GNUNET_malloc (sizeof (struct Session)); - memcpy (&s->target, target, sizeof (struct GNUNET_PeerIdentity)); - s->plugin = plugin; - s->addr = GNUNET_malloc (addrlen); - memcpy (s->addr, addr, addrlen); - s->addrlen = addrlen; - 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) -{ - struct Plugin *plugin = cls; - - plugin->env->session_end (plugin->env->cls, peer, s); - GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); - delete_session (s); -} - - -/** - * Creates a new outbound session the transport service will use to send data to the - * peer - * - * @param cls the plugin - * @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) -{ - struct Plugin *plugin = cls; - struct Session * s = NULL; - struct GNUNET_ATS_Information ats; - size_t addrlen; - - GNUNET_assert (plugin != NULL); - GNUNET_assert (address != NULL); - GNUNET_assert (address->address != NULL); - - ats.type = htonl (GNUNET_ATS_ARRAY_TERMINATOR); - ats.value = htonl (GNUNET_ATS_ARRAY_TERMINATOR); - - /* find existing session */ - s = lookup_session (plugin, address); - if (s != NULL) - return s; - - if (plugin->max_connections <= plugin->cur_connections) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, - "Maximum number of connections reached, " - "cannot connect to peer `%s'\n", GNUNET_i2s (&address->peer)); - return NULL; - } - - /* create new session */ - addrlen = address->address_length; - - GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || - (addrlen == sizeof (struct IPv4HttpAddress))); - - s = create_session (plugin, &address->peer, address->address, address->address_length); - - /* Get ATS type */ - if (addrlen == sizeof (struct IPv4HttpAddress)) - { - struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) address->address; - struct sockaddr_in s4; - - s4.sin_family = AF_INET; - s4.sin_addr.s_addr = a4->ipv4_addr; - s4.sin_port = a4->u4_port; -#if HAVE_SOCKADDR_IN_SIN_LEN - s4.sin_len = sizeof (struct sockaddr_in); -#endif - ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s4, sizeof (struct sockaddr_in)); - } - if (addrlen == sizeof (struct IPv6HttpAddress)) - { - struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) address->address; - struct sockaddr_in6 s6; - - s6.sin6_family = AF_INET6; - s6.sin6_addr = a6->ipv6_addr; - s6.sin6_port = a6->u6_port; -#if HAVE_SOCKADDR_IN_SIN_LEN - s6.sin6_len = sizeof (struct sockaddr_in6); -#endif - ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6)); - } - s->ats_address_network_type = ats.value; - - /* add new session */ - GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); - /* initiate new connection */ - if (GNUNET_SYSERR == client_connect (s)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - "Cannot connect to peer `%s' address `%s''\n", - http_plugin_address_to_string(NULL, s->addr, s->addrlen), - GNUNET_i2s (&s->target)); - GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); - delete_session (s); - return NULL; - } - - 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 - * peer disconnecting, the continuation MUST be called - * prior to the disconnect notification itself. This function - * will be called with this peer's HELLO message to initiate - * a fresh connection to another peer. - * - * @param cls closure - * @param session which session must be used - * @param msgbuf the message to transmit - * @param msgbuf_size number of bytes in 'msgbuf' - * @param priority how important is the message (most plugins will - * ignore message priority and just FIFO) - * @param to how long to wait at most for the transmission (does not - * require plugins to discard the message after the timeout, - * just advisory for the desired delay; most plugins will ignore - * this as well) - * @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 - * @return number of bytes used (on the physical network, with overheads); - * -1 on hard errors (i.e. address invalid); 0 is a legal value - * and does NOT mean that the message was not transmitted (DV) - */ -static ssize_t -http_plugin_send (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 Plugin *plugin = cls; - struct HTTP_Message *msg; - struct Session *tmp; - size_t res = -1; - - GNUNET_assert (plugin != NULL); - GNUNET_assert (session != NULL); - - /* lookup if session is really existing */ - tmp = plugin->head; - while (tmp != NULL) - { - if ((tmp == session) && - (0 == memcmp (&session->target, &tmp->target, sizeof (struct GNUNET_PeerIdentity))) && - (session->addrlen == tmp->addrlen) && - (0 == memcmp (session->addr, tmp->addr, tmp->addrlen))) - break; - tmp = tmp->next; - } - if (tmp == NULL) - { - GNUNET_break_op (0); - return res; - } - - /* create new message and schedule */ - msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); - msg->next = NULL; - msg->size = msgbuf_size; - msg->pos = 0; - msg->buf = (char *) &msg[1]; - msg->transmit_cont = cont; - msg->transmit_cont_cls = cont_cls; - memcpy (msg->buf, msgbuf, msgbuf_size); - - reschedule_session_timeout (session); - - if (session->inbound == GNUNET_NO) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Using outbound client session %p to send to `%s'\n", session, - GNUNET_i2s (&session->target)); - client_send (session, msg); - res = msgbuf_size; - } - if (session->inbound == GNUNET_YES) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Using inbound server %p session to send to `%s'\n", session, - GNUNET_i2s (&session->target)); - server_send (session, msg); - res = msgbuf_size; - } - return res; - -} - - -/** - * Function that can be used to force the plugin to disconnect - * from the given peer and cancel all previous transmissions - * (and their continuationc). - * - * @param cls closure - * @param target peer from which to disconnect - */ -static void -http_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) -{ - struct Plugin *plugin = cls; - struct Session *next = NULL; - struct Session *s = plugin->head; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Transport tells me to disconnect `%s'\n", - GNUNET_i2s (target)); - while (s != NULL) - { - next = s->next; - if (0 == memcmp (target, &s->target, sizeof (struct GNUNET_PeerIdentity))) - { - if (s->inbound == GNUNET_NO) - GNUNET_assert (GNUNET_OK == client_disconnect (s)); - else - GNUNET_assert (GNUNET_OK == server_disconnect (s)); - GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); - - struct HTTP_Message *msg = s->msg_head; - struct HTTP_Message *tmp = NULL; - - while (msg != NULL) - { - tmp = msg->next; - - GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); - if (msg->transmit_cont != NULL) - { - msg->transmit_cont (msg->transmit_cont_cls, target, GNUNET_SYSERR); - } - GNUNET_free (msg); - msg = tmp; - } - - delete_session (s); - } - s = next; - } -} - - -static void * -find_address (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen) -{ - int af; - struct IPv4HttpAddressWrapper *w_t4 = NULL; - struct IPv6HttpAddressWrapper *w_t6 = NULL; - - af = addr->sa_family; - 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; - } - return 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; - } - 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); - - 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))); - plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, - sizeof (struct IPv6HttpAddress)); - } - break; - default: - return; - } - -} - - -static void -nat_remove_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) - return; - - - 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))); - plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, - sizeof (struct IPv4HttpAddress)); - - GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail, - w_t4); - GNUNET_free (w_t4); - break; - case AF_INET6: - w_t6 = find_address (plugin, addr, addrlen); - if (w_t6 == NULL) - return; - - 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))); - - plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, - sizeof (struct IPv6HttpAddress)); - - GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail, - w_t6); - GNUNET_free (w_t6); - break; - default: - return; - } -} - - -/** - * Our external IP address/port mapping has changed. - * - * @param cls closure, the 'struct LocalAddrList' - * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean - * the previous (now invalid) one - * @param addr either the previous or the new public IP address - * @param addrlen actual lenght of the address - */ -static void -nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr, - socklen_t addrlen) -{ - GNUNET_assert (cls != NULL); - struct Plugin *plugin = cls; - - 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)); - - switch (add_remove) - { - case GNUNET_YES: - nat_add_address (cls, add_remove, addr, addrlen); - break; - case GNUNET_NO: - nat_remove_address (cls, add_remove, addr, addrlen); - break; - } -} - - -void -http_check_ipv6 (struct Plugin *plugin) -{ - struct GNUNET_NETWORK_Handle *desc = NULL; - - if (plugin->ipv6 == GNUNET_YES) - { - /* probe IPv6 support */ - desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); - if (NULL == desc) - { - if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || - (errno == EACCES)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); - } - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, - _ - ("Disabling IPv6 since it is not supported on this system!\n")); - plugin->ipv6 = GNUNET_NO; - } - else - { - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); - desc = NULL; - } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Testing IPv6 on this system: %s\n", - (plugin->ipv6 == GNUNET_YES) ? "successful" : "failed"); - } -} - - -int -http_get_addresses (struct Plugin *plugin, const char *serviceName, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct sockaddr ***addrs, socklen_t ** addr_lens) -{ - int disablev6; - unsigned long long port; - struct addrinfo hints; - struct addrinfo *res; - struct addrinfo *pos; - struct addrinfo *next; - unsigned int i; - int resi; - int ret; - struct sockaddr **saddrs; - socklen_t *saddrlens; - char *hostname; - - *addrs = NULL; - *addr_lens = NULL; - - disablev6 = !plugin->ipv6; - - port = 0; - if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT")) - { - GNUNET_break (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (cfg, serviceName, - "PORT", &port)); - if (port > 65535) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Require valid port number for service in configuration!\n")); - return GNUNET_SYSERR; - } - } - - if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO")) - { - GNUNET_break (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, - "BINDTO", &hostname)); - } - else - hostname = NULL; - - if (hostname != NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Resolving `%s' since that is where `%s' will bind to.\n", - hostname, serviceName); - memset (&hints, 0, sizeof (struct addrinfo)); - if (disablev6) - hints.ai_family = AF_INET; - if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || - (res == NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"), - hostname, gai_strerror (ret)); - GNUNET_free (hostname); - return GNUNET_SYSERR; - } - next = res; - i = 0; - while (NULL != (pos = next)) - { - next = pos->ai_next; - if ((disablev6) && (pos->ai_family == AF_INET6)) - continue; - i++; - } - if (0 == i) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to find %saddress for `%s'.\n"), - disablev6 ? "IPv4 " : "", hostname); - freeaddrinfo (res); - GNUNET_free (hostname); - return GNUNET_SYSERR; - } - resi = i; - saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); - saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); - i = 0; - next = res; - while (NULL != (pos = next)) - { - next = pos->ai_next; - if ((disablev6) && (pos->ai_family == AF_INET6)) - continue; - if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0)) - continue; /* not TCP */ - if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0)) - continue; /* huh? */ - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Service will bind to `%s'\n", GNUNET_a2s (pos->ai_addr, - pos->ai_addrlen)); - if (pos->ai_family == AF_INET) - { - GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in)); - saddrlens[i] = pos->ai_addrlen; - saddrs[i] = GNUNET_malloc (saddrlens[i]); - memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); - ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); - } - else - { - GNUNET_assert (pos->ai_family == AF_INET6); - GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6)); - saddrlens[i] = pos->ai_addrlen; - saddrs[i] = GNUNET_malloc (saddrlens[i]); - memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); - ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); - } - i++; - } - GNUNET_free (hostname); - freeaddrinfo (res); - resi = i; - } - else - { - /* will bind against everything, just set port */ - if (disablev6) - { - /* V4-only */ - resi = 1; - i = 0; - saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); - saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); - - saddrlens[i] = sizeof (struct sockaddr_in); - saddrs[i] = GNUNET_malloc (saddrlens[i]); -#if HAVE_SOCKADDR_IN_SIN_LEN - ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; -#endif - ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; - ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); - } - else - { - /* dual stack */ - resi = 2; - saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); - saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); - i = 0; - saddrlens[i] = sizeof (struct sockaddr_in6); - saddrs[i] = GNUNET_malloc (saddrlens[i]); -#if HAVE_SOCKADDR_IN_SIN_LEN - ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; -#endif - ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; - ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); - i++; - saddrlens[i] = sizeof (struct sockaddr_in); - saddrs[i] = GNUNET_malloc (saddrlens[i]); -#if HAVE_SOCKADDR_IN_SIN_LEN - ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; -#endif - ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; - ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); - } - } - *addrs = saddrs; - *addr_lens = saddrlens; - return resi; -} - -static void -start_report_addresses (struct Plugin *plugin) -{ - int res = GNUNET_OK; - struct sockaddr **addrs; - socklen_t *addrlens; - - res = - http_get_addresses (plugin, plugin->name, plugin->env->cfg, &addrs, - &addrlens); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - _("Found %u addresses to report to NAT service\n"), res); - - if (res != GNUNET_SYSERR) - { - plugin->nat = - GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, plugin->port, - (unsigned int) res, - (const struct sockaddr **) addrs, addrlens, - &nat_port_map_callback, NULL, plugin); - while (res > 0) - { - res--; -#if 0 - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _("FREEING %s\n"), - GNUNET_a2s (addrs[res], addrlens[res])); -#endif - GNUNET_assert (addrs[res] != NULL); - GNUNET_free (addrs[res]); - } - GNUNET_free_non_null (addrs); - GNUNET_free_non_null (addrlens); - } - else - { - plugin->nat = - GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, 0, 0, NULL, NULL, - NULL, NULL, plugin); - } -} - - -static void -stop_report_addresses (struct Plugin *plugin) -{ - /* Stop NAT handle */ - GNUNET_NAT_unregister (plugin->nat); - - /* Clean up addresses */ - struct IPv4HttpAddressWrapper *w_t4; - struct IPv6HttpAddressWrapper *w_t6; - - while (plugin->ipv4_addr_head != NULL) - { - w_t4 = plugin->ipv4_addr_head; - GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail, - w_t4); - GNUNET_free (w_t4); - } - - while (plugin->ipv6_addr_head != NULL) - { - w_t6 = plugin->ipv6_addr_head; - GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail, - w_t6); - GNUNET_free (w_t6); - } -} - - -static int -configure_plugin (struct Plugin *plugin) -{ - int res = GNUNET_OK; - - /* Use IPv4? */ - if (GNUNET_CONFIGURATION_have_value - (plugin->env->cfg, plugin->name, "USE_IPv4")) - { - plugin->ipv4 = - GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, - "USE_IPv4"); - } - else - plugin->ipv4 = GNUNET_YES; - - /* Use IPv6? */ - if (GNUNET_CONFIGURATION_have_value - (plugin->env->cfg, plugin->name, "USE_IPv6")) - { - plugin->ipv6 = - GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, - "USE_IPv6"); - } - else - plugin->ipv6 = GNUNET_YES; - - if ((plugin->ipv4 == GNUNET_NO) && (plugin->ipv6 == GNUNET_NO)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("Neither IPv4 nor IPv6 are enabled! Fix in configuration\n"), - plugin->name); - res = GNUNET_SYSERR; - } - - /* Reading port number from config file */ - unsigned long long port; - - if ((GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, - "PORT", &port)) || (port > 65535)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _("Port is required! Fix in configuration\n"), - plugin->name); - res = GNUNET_SYSERR; - goto fail; - } - plugin->port = port; - - plugin->client_only = GNUNET_NO; - if (plugin->port == 0) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - _("Port 0, client only mode\n")); - plugin->client_only = GNUNET_YES; - } - - char *bind4_address = NULL; - - if ((plugin->ipv4 == GNUNET_YES) && - (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, - "BINDTO", &bind4_address))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Binding %s plugin to specific IPv4 address: `%s'\n", - plugin->protocol, bind4_address); - plugin->server_addr_v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); - if (1 != - inet_pton (AF_INET, bind4_address, &plugin->server_addr_v4->sin_addr)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("Specific IPv4 address `%s' for plugin %s in configuration file is invalid! Binding to all addresses!\n"), - bind4_address, plugin->protocol); - GNUNET_free (plugin->server_addr_v4); - plugin->server_addr_v4 = NULL; - } - else - { - plugin->server_addr_v4->sin_family = AF_INET; - plugin->server_addr_v4->sin_port = htons (plugin->port); - } - GNUNET_free (bind4_address); - } - - - char *bind6_address = NULL; - - if ((plugin->ipv6 == GNUNET_YES) && - (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, - "BINDTO6", &bind6_address))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Binding %s plugin to specific IPv6 address: `%s'\n", - plugin->protocol, bind6_address); - plugin->server_addr_v6 = GNUNET_malloc (sizeof (struct sockaddr_in6)); - if (1 != - inet_pton (AF_INET6, bind6_address, &plugin->server_addr_v6->sin6_addr)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("Specific IPv6 address `%s' for plugin %s in configuration file is invalid! Binding to all addresses!\n"), - bind6_address, plugin->protocol); - GNUNET_free (plugin->server_addr_v6); - plugin->server_addr_v6 = NULL; - } - else - { - plugin->server_addr_v6->sin6_family = AF_INET6; - plugin->server_addr_v6->sin6_port = htons (plugin->port); - } - GNUNET_free (bind6_address); - } - - - /* Optional parameters */ - unsigned long long maxneigh; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, - "MAX_CONNECTIONS", &maxneigh)) - maxneigh = 128; - plugin->max_connections = maxneigh; - -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. - */ -void * -LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) -{ - struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; - struct GNUNET_TRANSPORT_PluginFunctions *api; - 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; - -#if BUILD_HTTPS - plugin->name = "transport-https"; - plugin->protocol = "https"; -#else - plugin->name = "transport-http"; - plugin->protocol = "http"; -#endif - /* Configure plugin from configuration */ - res = configure_plugin (plugin); - if (res == GNUNET_SYSERR) - { - GNUNET_free_non_null (plugin->server_addr_v4); - GNUNET_free_non_null (plugin->server_addr_v6); - GNUNET_free (plugin); - GNUNET_free (api); - return NULL; - } - - /* checking IPv6 support */ - http_check_ipv6 (plugin); - - /* Start client */ - res = client_start (plugin); - if (res == GNUNET_SYSERR) - { - GNUNET_free_non_null (plugin->server_addr_v4); - GNUNET_free_non_null (plugin->server_addr_v6); - GNUNET_free (plugin); - GNUNET_free (api); - return NULL; - } - - /* Start server */ - if (plugin->client_only == GNUNET_NO) - { - res = server_start (plugin); - if (res == GNUNET_SYSERR) - { - server_stop (plugin); - client_stop (plugin); - - GNUNET_free_non_null (plugin->server_addr_v4); - GNUNET_free_non_null (plugin->server_addr_v6); - GNUNET_free (plugin); - GNUNET_free (api); - return NULL; - } - } - /* Report addresses to transport service */ - start_report_addresses (plugin); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Plugin `%s' loaded\n", plugin->name); - return api; -} - - -/** - * Exit point from the plugin. - */ -void * -LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) -{ - struct GNUNET_TRANSPORT_PluginFunctions *api = cls; - struct Plugin *plugin = api->cls; - struct Session *s; - - if (NULL == plugin) - { - GNUNET_free (api); - return NULL; - } - - /* Stop reporting addresses to transport service */ - stop_report_addresses (plugin); - - /* cleaning up sessions */ - s = plugin->head; - while (s != NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Disconnecting `%s' \n", GNUNET_i2s (&s->target)); - if (s->inbound == GNUNET_NO) - GNUNET_assert (GNUNET_OK == client_disconnect (s)); - else - GNUNET_assert (GNUNET_OK == server_disconnect (s)); - s = s->next; - } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Stopping server\n"); - /* Stop server */ - server_stop (plugin); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Stopping client\n"); - /* Stop client */ - client_stop (plugin); - - /* deleting up sessions */ - s = plugin->head; - while (s != NULL) - { - struct Session *t = s->next; - - GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); - - struct HTTP_Message *msg = s->msg_head; - struct HTTP_Message *tmp = NULL; - - while (msg != NULL) - { - tmp = msg->next; - - GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); - if (msg->transmit_cont != NULL) - { - msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); - } - GNUNET_free (msg); - msg = tmp; - } - - delete_session (s); - s = t; - } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Plugin `%s' unloaded\n", plugin->name); - GNUNET_free_non_null (plugin->server_addr_v4); - GNUNET_free_non_null (plugin->server_addr_v6); - GNUNET_free (plugin); - GNUNET_free (api); - return NULL; -} - -/* end of plugin_transport_http.c */ diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h deleted file mode 100644 index 986d7d7..0000000 --- a/src/transport/plugin_transport_http.h +++ /dev/null @@ -1,553 +0,0 @@ -/* - This file is part of GNUnet - (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 transport/plugin_transport_http.h - * @brief http transport service plugin - * @author Matthias Wachs - */ - -#include "platform.h" -#include "gnunet_common.h" -#include "gnunet_constants.h" -#include "gnunet_protocols.h" -#include "gnunet_connection_lib.h" -#include "gnunet_service_lib.h" -#include "gnunet_statistics_service.h" -#include "gnunet_transport_service.h" -#include "gnunet_resolver_service.h" -#include "gnunet_server_lib.h" -#include "gnunet_container_lib.h" -#include "gnunet_transport_plugin.h" -#include "gnunet_os_lib.h" -#include "gnunet_nat_lib.h" -#include "microhttpd.h" -#include <curl/curl.h> - - -#define DEBUG_HTTP GNUNET_EXTRA_LOGGING -#define VERBOSE_SERVER GNUNET_EXTRA_LOGGING -#define VERBOSE_CLIENT GNUNET_EXTRA_LOGGING -#define VERBOSE_CURL GNUNET_NO - -#if BUILD_HTTPS -#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init -#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_done -#else -#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_init -#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_done -#endif - -#define INBOUND GNUNET_YES -#define OUTBOUND GNUNET_NO - - -#define HTTP_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) - -/** - * Encapsulation of all of the state of the plugin. - */ -struct Plugin -{ - /** - * General handles - * --------------- - */ - - /** - * Our environment. - */ - struct GNUNET_TRANSPORT_PluginEnvironment *env; - - /** - * Linked list of open sessions. - */ - - struct Session *head; - - struct Session *tail; - - /** - * NAT handle & address management - */ - struct GNUNET_NAT_Handle *nat; - - /** - * List of own addresses - */ - - /** - * IPv4 addresses DLL head - */ - struct IPv4HttpAddressWrapper *ipv4_addr_head; - - /** - * IPv4 addresses DLL tail - */ - struct IPv4HttpAddressWrapper *ipv4_addr_tail; - - /** - * IPv6 addresses DLL head - */ - struct IPv6HttpAddressWrapper *ipv6_addr_head; - - /** - * IPv6 addresses DLL tail - */ - struct IPv6HttpAddressWrapper *ipv6_addr_tail; - - /** - * Plugin configuration - * -------------------- - */ - - /** - * Plugin name - * Equals configuration section: transport-http, transport-https - */ - char *name; - - /** - * Plugin protocol - * http, https - */ - char *protocol; - - /** - * Use IPv4? - * GNUNET_YES or GNUNET_NO - */ - int ipv4; - - /** - * Use IPv6? - * GNUNET_YES or GNUNET_NO - */ - int ipv6; - - /** - * Does plugin just use outbound connections and not accept inbound? - */ - - int client_only; - - /** - * Port used - */ - uint16_t port; - - /** - * Maximum number of sockets the plugin can use - * Each http inbound /outbound connections are two connections - */ - int max_connections; - - /** - * Number of outbound sessions - */ - unsigned int outbound_sessions; - - /** - * Number of inbound sessions - */ - unsigned int inbound_sessions; - - /** - * Plugin HTTPS SSL/TLS options - * ---------------------------- - */ - - /** - * libCurl TLS crypto init string, can be set to enhance performance - * - * Example: - * - * Use RC4-128 instead of AES: - * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL - * - */ - char *crypto_init; - - /** - * TLS key - */ - char *key; - - /** - * TLS certificate - */ - char *cert; - - /** - * Plugin values - * ------------- - */ - - /** - * Current number of establishes connections - */ - int cur_connections; - - /** - * Last used unique HTTP connection tag - */ - uint32_t last_tag; - - /** - * Server handles - * -------------- - */ - - /** - * MHD IPv4 daemon - */ - struct MHD_Daemon *server_v4; - - /** - * MHD IPv4 task - */ - GNUNET_SCHEDULER_TaskIdentifier server_v4_task; - - /** - * The IPv4 server is scheduled to run asap - */ - int server_v4_immediately; - - /** - * MHD IPv6 daemon - */ - struct MHD_Daemon *server_v6; - - /** - * MHD IPv4 task - */ - GNUNET_SCHEDULER_TaskIdentifier server_v6_task; - - /** - * The IPv6 server is scheduled to run asap - */ - - int server_v6_immediately; - - /** - * IPv4 server socket to bind to - */ - struct sockaddr_in *server_addr_v4; - - /** - * IPv6 server socket to bind to - */ - struct sockaddr_in6 *server_addr_v6; - - /** - * Server semi connections - * A full session consists of 2 semi-connections: send and receive - * If not both directions are established the server keeps this sessions here - */ - struct Session *server_semi_head; - - struct Session *server_semi_tail; - - /* - * Client handles - */ - - /** - * cURL Multihandle - */ - CURLM *client_mh; - - /** - * curl perform task - */ - GNUNET_SCHEDULER_TaskIdentifier client_perform_task; - -}; - -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * IPv4 addresses - */ -struct IPv4HttpAddress -{ - /** - * IPv4 address, in network byte order. - */ - uint32_t ipv4_addr GNUNET_PACKED; - - /** - * Port number, in network byte order. - */ - uint16_t u4_port GNUNET_PACKED; -}; - -/** - * IPv4 addresses - */ -struct IPv6HttpAddress -{ - /** - * IPv6 address. - */ - struct in6_addr ipv6_addr GNUNET_PACKED; - - /** - * Port number, in network byte order. - */ - uint16_t u6_port GNUNET_PACKED; -}; -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. - */ -struct Session -{ - - /** - * Stored in a linked list. - */ - struct Session *next; - - /** - * Stored in a linked list. - */ - struct Session *prev; - - /** - * Pointer to the global plugin struct. - */ - struct Plugin *plugin; - - /** - * Address - */ - void *addr; - - /** - * Address length - */ - size_t addrlen; - - /** - * ATS network type in NBO - */ - uint32_t ats_address_network_type; - - /** - * To whom are we talking to - */ - struct GNUNET_PeerIdentity target; - - /** - * next pointer for double linked list - */ - struct HTTP_Message *msg_head; - - /** - * previous pointer for double linked list - */ - struct HTTP_Message *msg_tail; - - - /** - * Message stream tokenizer for incoming data - */ - struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk; - - /** - * Absolute time when to receive data again - * Used for receive throttling - */ - struct GNUNET_TIME_Absolute next_receive; - - /** - * Inbound or outbound connection - * Outbound: GNUNET_NO (client is used to send and receive) - * Inbound : GNUNET_YES (server is used to send and receive) - */ - int inbound; - - /** - * Unique HTTP/S connection tag for this connection - */ - uint32_t tag; - - /** - * Client handles - */ - - /** - * Client send handle - */ - void *client_put; - - /** - * Client receive handle - */ - void *client_get; - - /** - * Task to wake up client receive handle when receiving is allowed again - */ - 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 - */ - int client_put_paused; - - /** - * Server handles - */ - - /** - * Client send handle - */ - struct ServerConnection *server_recv; - - /** - * Client send handle - */ - struct ServerConnection *server_send; -}; - -/** - * Message to send using http - */ -struct HTTP_Message -{ - /** - * next pointer for double linked list - */ - struct HTTP_Message *next; - - /** - * previous pointer for double linked list - */ - struct HTTP_Message *prev; - - /** - * buffer containing data to send - */ - char *buf; - - /** - * amount of data already sent - */ - size_t pos; - - /** - * buffer length - */ - size_t size; - - /** - * Continuation function to call once the transmission buffer - * has again space available. NULL if there is no - * continuation to call. - */ - GNUNET_TRANSPORT_TransmitContinuation transmit_cont; - - /** - * Closure for transmit_cont. - */ - 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); - -int -exist_session (struct Plugin *plugin, struct Session *s); - -struct GNUNET_TIME_Relative -http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message, - struct Session *session, const char *sender_address, - uint16_t sender_address_len); - -const char * -http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen); - -int -client_disconnect (struct Session *s); - -int -client_connect (struct Session *s); - -int -client_send (struct Session *s, struct HTTP_Message *msg); - -int -client_start (struct Plugin *plugin); - -void -client_stop (struct Plugin *plugin); - -int -server_disconnect (struct Session *s); - -int -server_send (struct Session *s, struct HTTP_Message *msg); - -int -server_start (struct Plugin *plugin); - -void -server_stop (struct Plugin *plugin); - -void -notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, - struct Session *s); - -/* end of plugin_transport_http.h */ diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index f55311f..e7bf704 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--2012 Christian Grothoff (and other contributing authors) + (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 @@ -20,31 +20,418 @@ /** * @file transport/plugin_transport_http_client.c - * @brief http transport service plugin + * @brief HTTP/S client transport plugin * @author Matthias Wachs */ -#include "plugin_transport_http.h" +#if BUILD_HTTPS +#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_client_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_client_done +#else +#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_client_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_client_done +#endif + +#define VERBOSE_CURL GNUNET_YES + +#define PUT_DISCONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) + +#define ENABLE_PUT GNUNET_YES +#define ENABLE_GET GNUNET_YES + +#include "platform.h" +#include "gnunet_protocols.h" +#include "gnunet_common.h" +#include "gnunet_server_lib.h" +#include "gnunet_transport_plugin.h" +#include "plugin_transport_http_common.h" +#include <curl/curl.h> + + + +/** + * Encapsulation of all of the state of the plugin. + */ +struct HTTP_Client_Plugin; + + +/** + * Message to send using http + */ +struct HTTP_Message +{ + /** + * next pointer for double linked list + */ + struct HTTP_Message *next; + + /** + * previous pointer for double linked list + */ + struct HTTP_Message *prev; + + /** + * buffer containing data to send + */ + char *buf; + + /** + * amount of data already sent + */ + size_t pos; + + /** + * buffer length + */ + size_t size; + + /** + * Continuation function to call once the transmission buffer + * has again space available. NULL if there is no + * continuation to call. + */ + GNUNET_TRANSPORT_TransmitContinuation transmit_cont; + + /** + * Closure for transmit_cont. + */ + void *transmit_cont_cls; +}; + + +/** + * Session handle for connections. + */ +struct Session; + +/** + * A connection handle + * + */ +struct ConnectionHandle +{ + /** + * The curl easy handle + */ + CURL *easyhandle; + + /** + * The related session + */ + struct Session *s; +}; + + + +/** + * Session handle for connections. + */ +struct Session +{ + /** + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) + */ + struct GNUNET_PeerIdentity target; + + /** + * Stored in a linked list. + */ + struct Session *next; + + /** + * Stored in a linked list. + */ + struct Session *prev; + + /** + * The URL to connect to + */ + char *url; + + /** + * Address + */ + void *addr; + + /** + * Address length + */ + size_t addrlen; + + /** + * ATS network type in NBO + */ + uint32_t ats_address_network_type; + + /** + * Pointer to the global plugin struct. + */ + struct HTTP_Client_Plugin *plugin; + + /** + * Client send handle + */ + void *client_put; + + struct ConnectionHandle put; + struct ConnectionHandle get; + + /** + * Is the client PUT handle currently paused + */ + int put_paused; + + /** + * Is the client PUT handle disconnect in progress? + */ + int put_tmp_disconnecting; + + /** + * Is the client PUT handle temporarily disconnected? + */ + int put_tmp_disconnected; + + /** + * We received data to send while disconnecting, reconnect immediately + */ + int put_reconnect_required; + + /** + * Client receive handle + */ + void *client_get; + + /** + * Outbound overhead due to HTTP connection + * Add to next message of this session when calling callback + */ + size_t overhead; + + /** + * next pointer for double linked list + */ + struct HTTP_Message *msg_head; + + /** + * previous pointer for double linked list + */ + struct HTTP_Message *msg_tail; + + /** + * Message stream tokenizer for incoming data + */ + struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk; + + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier put_disconnect_task; + + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + /** + * Task to wake up client receive handle when receiving is allowed again + */ + GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task; + + /** + * Absolute time when to receive data again + * Used for receive throttling + */ + struct GNUNET_TIME_Absolute next_receive; +}; -static struct Plugin * p; -#if VERBOSE_CURL /** - * Function to log curl debug messages with GNUNET_log - * @param curl handle - * @param type curl_infotype - * @param data data - * @param size size - * @param cls closure - * @return 0 + * Encapsulation of all of the state of the plugin. + */ +struct HTTP_Client_Plugin +{ + /** + * Our environment. + */ + struct GNUNET_TRANSPORT_PluginEnvironment *env; + + /** + * Linked list head of open sessions. + */ + struct Session *head; + + /** + * Linked list tail of open sessions. + */ + struct Session *tail; + + /** + * Plugin name + */ + char *name; + + /** + * Protocol + */ + char *protocol; + + /** + * Maximum number of sockets the plugin can use + * Each http inbound /outbound connections are two connections + */ + unsigned int max_connections; + + /** + * Current number of sockets the plugin can use + * Each http inbound /outbound connections are two connections + */ + unsigned int cur_connections; + + /** + * Last used unique HTTP connection tag + */ + uint32_t last_tag; + + /** + * use IPv6 + */ + uint16_t use_ipv6; + + /** + * use IPv4 + */ + uint16_t use_ipv4; + + /** + * cURL Multihandle + */ + CURLM *curl_multi_handle; + + /** + * curl perform task + */ + GNUNET_SCHEDULER_TaskIdentifier client_perform_task; +}; + + +/** + * Encapsulation of all of the state of the plugin. + */ +struct HTTP_Client_Plugin *p; + + +/** + * Start session timeout for a session + * @param s the session + */ +static void +client_start_session_timeout (struct Session *s); + + +/** + * Increment session timeout due to activity for a session + * @param s the session + */ +static void +client_reschedule_session_timeout (struct Session *s); + + +/** + * Cancel timeout for a session + * @param s the session + */ +static void +client_stop_session_timeout (struct Session *s); + + +/** + * Function setting up file descriptors and scheduling task to run + * + * @param plugin plugin as closure + * @param now schedule task in 1ms, regardless of what curl may say + * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok + */ +static int +client_schedule (struct HTTP_Client_Plugin *plugin, int now); + + +/** + * Connect a HTTP put connection + * + * @param s the session to connect + * @return GNUNET_SYSERR for hard failure, GNUNET_OK for success */ static int -client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) +client_connect_put (struct Session *s); + + +/** + * Does a session s exists? + * + * @param plugin the plugin + * @param s desired session + * @return GNUNET_YES or GNUNET_NO + */ +static int +client_exist_session (struct HTTP_Client_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; +} + + +/** + * Loggging function + * + * @param curl the curl easy handle + * @param type message type + * @param data data to log, NOT a 0-terminated string + * @param size data length + * @param cls the closure + * @return always 0 + */ +static int +client_log (CURL *curl, curl_infotype type, + const char *data, size_t size, void *cls) { - if (type == CURLINFO_TEXT) + struct ConnectionHandle *ch = cls; + const char *ttype = "UNSPECIFIED"; + + if ((type == CURLINFO_TEXT) || (type == CURLINFO_HEADER_IN) || (type == CURLINFO_HEADER_OUT)) { char text[size + 2]; + switch (type) { + case CURLINFO_TEXT: + ttype = "TEXT"; + break; + case CURLINFO_HEADER_IN: + ttype = "HEADER_IN"; + break; + case CURLINFO_HEADER_OUT: + ttype = "HEADER_OUT"; + /* Overhead*/ + + GNUNET_assert (NULL != ch); + GNUNET_assert (NULL != ch->easyhandle); + GNUNET_assert (NULL != ch->s); + ch->s->overhead += size; + break; + default: + ttype = "UNSPECIFIED"; + break; + } + memcpy (text, data, size); if (text[size - 1] == '\n') text[size] = '\0'; @@ -54,210 +441,192 @@ client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) text[size + 1] = '\0'; } #if BUILD_HTTPS - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https", - "Client: %p - %s", cls, text); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https_client", + "Connection %p %s: %s", ch->easyhandle, ttype, text); #else - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http", - "Client: %p - %s", cls, text); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http_client", + "Connection %p %s: %s", ch->easyhandle, ttype, text); #endif } return 0; } -#endif - -/** - * Task performing curl operations - * @param cls plugin as closure - * @param tc gnunet scheduler task context - */ -static void -client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** - * Function setting up file descriptors and scheduling task to run + * Function that can be used by the transport service to transmit + * a message using the plugin. Note that in the case of a + * peer disconnecting, the continuation MUST be called + * prior to the disconnect notification itself. This function + * will be called with this peer's HELLO message to initiate + * a fresh connection to another peer. * - * @param plugin plugin as closure - * @param now schedule task in 1ms, regardless of what curl may say - * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok + * @param cls closure + * @param s which session must be used + * @param msgbuf the message to transmit + * @param msgbuf_size number of bytes in 'msgbuf' + * @param priority how important is the message (most plugins will + * ignore message priority and just FIFO) + * @param to how long to wait at most for the transmission (does not + * require plugins to discard the message after the timeout, + * just advisory for the desired delay; most plugins will ignore + * this as well) + * @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 + * @return number of bytes used (on the physical network, with overheads); + * -1 on hard errors (i.e. address invalid); 0 is a legal value + * and does NOT mean that the message was not transmitted (DV) */ -static int -client_schedule (struct Plugin *plugin, int now) +static ssize_t +http_client_plugin_send (void *cls, + struct Session *s, + const char *msgbuf, size_t msgbuf_size, + unsigned int priority, + struct GNUNET_TIME_Relative to, + GNUNET_TRANSPORT_TransmitContinuation cont, + void *cont_cls) { - fd_set rs; - fd_set ws; - fd_set es; - int max; - struct GNUNET_NETWORK_FDSet *grs; - struct GNUNET_NETWORK_FDSet *gws; - long to; - CURLMcode mret; - struct GNUNET_TIME_Relative timeout; + struct HTTP_Client_Plugin *plugin = cls; + struct HTTP_Message *msg; + char *stat_txt; - /* Cancel previous scheduled task */ - if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (plugin->client_perform_task); - plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; - } - max = -1; - FD_ZERO (&rs); - FD_ZERO (&ws); - FD_ZERO (&es); - mret = curl_multi_fdset (plugin->client_mh, &rs, &ws, &es, &max); - if (mret != CURLM_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), - "curl_multi_fdset", __FILE__, __LINE__, - curl_multi_strerror (mret)); - return GNUNET_SYSERR; - } - mret = curl_multi_timeout (plugin->client_mh, &to); - if (to == -1) - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); - else - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); - if (now == GNUNET_YES) - timeout = GNUNET_TIME_UNIT_MILLISECONDS; + GNUNET_assert (plugin != NULL); + GNUNET_assert (s != NULL); - if (mret != CURLM_OK) + /* lookup if session is really existing */ + if (GNUNET_YES != client_exist_session (plugin, s)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), - "curl_multi_timeout", __FILE__, __LINE__, - curl_multi_strerror (mret)); + GNUNET_break (0); return GNUNET_SYSERR; } - grs = GNUNET_NETWORK_fdset_create (); - gws = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); - GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p/connection %p: Sending message with %u to peer `%s' \n", + s, s->client_put, + msgbuf_size, GNUNET_i2s (&s->target)); + + /* create new message and schedule */ + msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); + msg->next = NULL; + msg->size = msgbuf_size; + msg->pos = 0; + msg->buf = (char *) &msg[1]; + msg->transmit_cont = cont; + msg->transmit_cont_cls = cont_cls; + memcpy (msg->buf, msgbuf, msgbuf_size); + GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); - plugin->client_perform_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - timeout, grs, gws, - &client_run, plugin); - GNUNET_NETWORK_fdset_destroy (gws); - GNUNET_NETWORK_fdset_destroy (grs); - return GNUNET_OK; -} + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_client buffers", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, msgbuf_size, GNUNET_NO); + GNUNET_free (stat_txt); -int -client_send (struct Session *s, struct HTTP_Message *msg) -{ - GNUNET_assert (s != NULL); - GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); - - if (GNUNET_YES != exist_session(p, s)) + if (GNUNET_YES == s->put_tmp_disconnecting) { - GNUNET_break (0); - return GNUNET_SYSERR; + /* PUT connection is currently getting disconnected */ + s->put_reconnect_required = GNUNET_YES; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p/connection %jp: currently disconnecting, reconnecting immediately\n", + s, s->client_put); + return msgbuf_size; } - if (s->client_put_paused == GNUNET_YES) + else if (GNUNET_YES == s->put_paused) { + /* PUT connection was paused, unpause */ + GNUNET_assert (s->put_disconnect_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_SCHEDULER_cancel (s->put_disconnect_task); + s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, - "Client: %p was suspended, unpausing\n", s->client_put); - s->client_put_paused = GNUNET_NO; + "Session %p/connection %p: unpausing connection\n", + s, s->client_put); + s->put_paused = GNUNET_NO; curl_easy_pause (s->client_put, CURLPAUSE_CONT); } - client_schedule (s->plugin, GNUNET_YES); + else if (GNUNET_YES == s->put_tmp_disconnected) + { + /* PUT connection was disconnected, reconnect */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p: Reconnecting PUT connection\n", + s); + s->put_tmp_disconnected = GNUNET_NO; + GNUNET_break (s->client_put == NULL); + if (GNUNET_SYSERR == client_connect_put (s)) + { + return GNUNET_SYSERR; + } + } - return GNUNET_OK; + client_schedule (s->plugin, GNUNET_YES); + client_reschedule_session_timeout (s); + return msgbuf_size; } /** - * Task performing curl operations + * Delete session s * - * @param cls plugin as closure - * @param tc gnunet scheduler task context + * @param s the session to delete */ static void -client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +client_delete_session (struct Session *s) { - struct Plugin *plugin = cls; - int running; - CURLMcode mret; + struct HTTP_Client_Plugin *plugin = s->plugin; + struct HTTP_Message *pos; + struct HTTP_Message *next; - GNUNET_assert (cls != NULL); + client_stop_session_timeout (s); - plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; - - do + if (GNUNET_SCHEDULER_NO_TASK != s->put_disconnect_task) { - running = 0; - mret = curl_multi_perform (plugin->client_mh, &running); - - CURLMsg *msg; - int msgs_left; - - while ((msg = curl_multi_info_read (plugin->client_mh, &msgs_left))) - { - CURL *easy_h = msg->easy_handle; - struct Session *s = NULL; - char *d = (char *) s; - - - //GNUNET_assert (easy_h != NULL); - if (easy_h == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: connection to ended with reason %i: `%s', %i handles running\n", - msg->data.result, - curl_easy_strerror (msg->data.result), running); - continue; - } - - GNUNET_assert (CURLE_OK == - curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); - s = (struct Session *) d; + GNUNET_SCHEDULER_cancel (s->put_disconnect_task); + s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; + } - if (GNUNET_YES != exist_session(plugin, s)) - { - GNUNET_break (0); - return; - } + GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); - GNUNET_assert (s != NULL); + next = s->msg_head; + while (NULL != (pos = next)) + { + next = pos->next; + GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, pos); + if (pos->transmit_cont != NULL) + pos->transmit_cont (pos->transmit_cont_cls, &s->target, GNUNET_SYSERR, + pos->size, pos->pos + s->overhead); + s->overhead = 0; + GNUNET_free (pos); + } - if (msg->msg == CURLMSG_DONE) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "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), - msg->data.result, - 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)); - notify_session_end (plugin, &s->target, s); - } - } + if (s->msg_tk != NULL) + { + GNUNET_SERVER_mst_destroy (s->msg_tk); + s->msg_tk = NULL; } - while (mret == CURLM_CALL_MULTI_PERFORM); - client_schedule (plugin, GNUNET_NO); + GNUNET_free (s->addr); + GNUNET_free (s->url); + GNUNET_free (s); } -int + +/** + * Disconnect a session + * + * @param s session + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +static int client_disconnect (struct Session *s) { - int res = GNUNET_OK; - CURLMcode mret; - struct Plugin *plugin = s->plugin; + struct HTTP_Client_Plugin *plugin = s->plugin; struct HTTP_Message *msg; struct HTTP_Message *t; + int res = GNUNET_OK; + CURLMcode mret; - if (GNUNET_YES != exist_session(plugin, s)) + if (GNUNET_YES != client_exist_session (plugin, s)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -266,13 +635,14 @@ client_disconnect (struct Session *s) if (s->client_put != NULL) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %p Deleting outbound PUT session to peer `%s'\n", - s->client_put, GNUNET_i2s (&s->target)); + "Session %p/connection %p: disconnecting PUT connection to peer `%s'\n", + s, s->client_put, GNUNET_i2s (&s->target)); - mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); + /* remove curl handle from multi handle */ + mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_put); if (mret != CURLM_OK) { - curl_easy_cleanup (s->client_put); + /* clean up easy handle, handle is now invalid and free'd */ res = GNUNET_SYSERR; GNUNET_break (0); } @@ -289,14 +659,15 @@ client_disconnect (struct Session *s) if (s->client_get != NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %p Deleting outbound GET session to peer `%s'\n", - s->client_get, GNUNET_i2s (&s->target)); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: disconnecting GET connection to peer `%s'\n", + s, s->client_get, GNUNET_i2s (&s->target)); - mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); + /* remove curl handle from multi handle */ + mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); if (mret != CURLM_OK) { - curl_easy_cleanup (s->client_get); + /* clean up easy handle, handle is now invalid and free'd */ res = GNUNET_SYSERR; GNUNET_break (0); } @@ -309,69 +680,200 @@ client_disconnect (struct Session *s) { t = msg->next; if (NULL != msg->transmit_cont) - msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); + msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR, + msg->size, msg->pos + s->overhead); + s->overhead = 0; GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); GNUNET_free (msg); msg = t; } + GNUNET_assert (plugin->cur_connections >= 2); 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, + "# HTTP client sessions", + plugin->cur_connections, GNUNET_NO); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p: notifying transport about ending session\n",s); + + plugin->env->session_end (plugin->env->cls, &s->target, s); + client_delete_session (s); + /* Re-schedule since handles have changed */ if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->client_perform_task); plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; } - client_schedule (plugin, GNUNET_YES); return res; } -static int -client_receive_mst_cb (void *cls, void *client, - const struct GNUNET_MessageHeader *message) + +/** + * Function that can be used to force the plugin to disconnect + * from the given peer and cancel all previous transmissions + * (and their continuationc). + * + * @param cls closure + * @param target peer from which to disconnect + */ +static void +http_client_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) +{ + struct HTTP_Client_Plugin *plugin = cls; + struct Session *next = NULL; + struct Session *pos = NULL; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Transport tells me to disconnect `%s'\n", + GNUNET_i2s (target)); + + next = plugin->head; + while (NULL != (pos = next)) + { + next = pos->next; + if (0 == memcmp (target, &pos->target, sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Disconnecting session %p to `%pos'\n", + pos, GNUNET_i2s (target)); + GNUNET_assert (GNUNET_OK == client_disconnect (pos)); + } + } + +} + +/** + * Check if a sessions exists for an specific address + * + * @param plugin the plugin + * @param address the address + * @return the session or NULL + */ +static struct Session * +client_lookup_session (struct HTTP_Client_Plugin *plugin, + const struct GNUNET_HELLO_Address *address) +{ + struct Session *pos; + + for (pos = plugin->head; NULL != pos; pos = pos->next) + if ((0 == memcmp (&address->peer, &pos->target, sizeof (struct GNUNET_PeerIdentity))) && + (address->address_length == pos->addrlen) && + (0 == memcmp (address->address, pos->addr, pos->addrlen))) + return pos; + return NULL; +} + +static void +client_put_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Session *s = cls; - struct GNUNET_TIME_Relative delay; + s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p/connection %p: will be disconnected due to no activity\n", + s, s->client_put); + s->put_paused = GNUNET_NO; + s->put_tmp_disconnecting = GNUNET_YES; + curl_easy_pause (s->client_put, CURLPAUSE_CONT); + client_schedule (s->plugin, GNUNET_YES); +} - if (GNUNET_YES != exist_session(p, s)) + + +/** + * 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 + * @param cls source pointer, passed to the libcurl handle + * @return bytes written to stream, returning 0 will terminate connection! + */ +static size_t +client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) +{ + struct Session *s = cls; + struct HTTP_Client_Plugin *plugin = s->plugin; + struct HTTP_Message *msg = s->msg_head; + size_t len; + char *stat_txt; + + if (GNUNET_YES != client_exist_session (plugin, s)) { GNUNET_break (0); - return GNUNET_OK; + return 0; } + if (GNUNET_YES == s->put_tmp_disconnecting) + { - 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); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p/connection %p: disconnect due to inactivity\n", + s, s->client_put); + return 0; + } - if (GNUNET_TIME_absolute_get ().abs_value < s->next_receive.abs_value) + if (NULL == msg) { - 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); + "Session %p/connection %p: nothing to send, suspending\n", + s, s->client_put); + s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT, &client_put_disconnect, s); + s->put_paused = GNUNET_YES; + return CURL_READFUNC_PAUSE; } - return GNUNET_OK; + /* data to send */ + 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) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: sent message with %u bytes sent, removing message from queue\n", + s, s->client_put, msg->size, msg->pos); + /* 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, + msg->size, msg->size + s->overhead); + s->overhead = 0; + GNUNET_free (msg); + } + + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_client buffers", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, -len, GNUNET_NO); + GNUNET_free (stat_txt); + + GNUNET_asprintf (&stat_txt, "# bytes transmitted via %s_client", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, len, GNUNET_NO); + GNUNET_free (stat_txt); + + client_reschedule_session_timeout (s); + return len; } +/** + * Wake up a curl handle which was suspended + * + * @param cls the session + * @param tc task context + */ static void client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Session *s = cls; - if (GNUNET_YES != exist_session(p, s)) + if (GNUNET_YES != client_exist_session(p, s)) { GNUNET_break (0); return; @@ -380,15 +882,87 @@ client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, - "Client: %p Waking up receive handle\n", s->client_get); + "Session %p/connection %p: Waking up GET handle\n", s, 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 + * Callback for message stream tokenizer + * + * @param cls the session + * @param client not used + * @param message the message received + * @return always GNUNET_OK + */ +static int +client_receive_mst_cb (void *cls, void *client, + const struct GNUNET_MessageHeader *message) +{ + struct Session *s = cls; + struct HTTP_Client_Plugin *plugin; + struct GNUNET_TIME_Relative delay; + struct GNUNET_ATS_Information atsi[2]; + char *stat_txt; + if (GNUNET_YES != client_exist_session(p, s)) + { + GNUNET_break (0); + return GNUNET_OK; + } + plugin = s->plugin; + + atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + atsi[0].value = htonl (1); + atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); + atsi[1].value = s->ats_address_network_type; + GNUNET_break (s->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED)); + + delay = s->plugin->env->receive (plugin->env->cls, &s->target, message, + (const struct GNUNET_ATS_Information *) &atsi, 2, + s, s->addr, s->addrlen); + + GNUNET_asprintf (&stat_txt, "# bytes received via %s_client", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, ntohs(message->size), GNUNET_NO); + GNUNET_free (stat_txt); + + s->next_receive = + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); + + if (GNUNET_TIME_absolute_get ().abs_value < s->next_receive.abs_value) + { + + 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); + } + client_reschedule_session_timeout (s); + return GNUNET_OK; +} + + +/** + * Callback method used with libcurl when data for a PUT connection are + * received. We do not expect data here, so we just dismiss it + * + * @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_put (void *stream, size_t size, size_t nmemb, void *cls) +{ + return size * nmemb; +} + + +/** + * Callback method used with libcurl when data for a GET connection are + * received. Forward to MST * * @param stream pointer where to write data * @param size size of an individual element @@ -402,20 +976,20 @@ 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; - 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)); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p / connection %p: Received %u bytes from peer `%s'\n", + s, s->client_get, + len, GNUNET_i2s (&s->target)); 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); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n", - s->client_get, delta.rel_value); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p / connection %p: No inbound bandwidth available! Next read was delayed for %llu ms\n", + s, s->client_get, delta.rel_value); if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); @@ -423,7 +997,7 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) } s->recv_wakeup_task = GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); - return CURLPAUSE_ALL; + return CURL_WRITEFUNC_PAUSE; } if (NULL == s->msg_tk) s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); @@ -433,167 +1007,383 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) /** - * Callback method used with libcurl - * Method is called when libcurl needs to read data during sending + * Task performing curl operations * - * @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 source pointer, passed to the libcurl handle - * @return bytes written to stream, returning 0 will terminate connection! + * @param cls plugin as closure + * @param tc gnunet scheduler task context */ -static size_t -client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) +static void +client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Function setting up file descriptors and scheduling task to run + * + * @param plugin the plugin as closure + * @param now schedule task in 1ms, regardless of what curl may say + * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok + */ +static int +client_schedule (struct HTTP_Client_Plugin *plugin, int now) { - struct Session *s = cls; - struct Plugin *plugin = s->plugin; - struct HTTP_Message *msg = s->msg_head; - size_t len; + fd_set rs; + fd_set ws; + fd_set es; + int max; + struct GNUNET_NETWORK_FDSet *grs; + struct GNUNET_NETWORK_FDSet *gws; + long to; + CURLMcode mret; + struct GNUNET_TIME_Relative timeout; - if (GNUNET_YES != exist_session(plugin, s)) + /* Cancel previous scheduled task */ + if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_break (0); - return 0; + GNUNET_SCHEDULER_cancel (plugin->client_perform_task); + plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; } - if (NULL == msg) + max = -1; + FD_ZERO (&rs); + FD_ZERO (&ws); + FD_ZERO (&es); + mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); + if (mret != CURLM_OK) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %p Nothing to send! Suspending PUT handle!\n", - s->client_put); - s->client_put_paused = GNUNET_YES; - return CURL_READFUNC_PAUSE; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_fdset", __FILE__, __LINE__, + curl_multi_strerror (mret)); + return GNUNET_SYSERR; } - /* data to send */ - 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) + mret = curl_multi_timeout (plugin->curl_multi_handle, &to); + if (to == -1) + timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); + else + timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); + if (now == GNUNET_YES) + timeout = GNUNET_TIME_UNIT_MILLISECONDS; + + if (mret != CURLM_OK) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %p Message with %u bytes sent, removing message from queue\n", - s->client_put, msg->size, msg->pos); - /* 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_free (msg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_timeout", __FILE__, __LINE__, + curl_multi_strerror (mret)); + return GNUNET_SYSERR; } - return len; + + grs = GNUNET_NETWORK_fdset_create (); + gws = GNUNET_NETWORK_fdset_create (); + GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); + + plugin->client_perform_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + timeout, grs, gws, + &client_run, plugin); + GNUNET_NETWORK_fdset_destroy (gws); + GNUNET_NETWORK_fdset_destroy (grs); + return GNUNET_OK; } -int -client_connect (struct Session *s) +/** + * Task performing curl operations + * + * @param cls plugin as closure + * @param tc gnunet scheduler task context + */ +static void +client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct Plugin *plugin = s->plugin; - int res = GNUNET_OK; - char *url; + struct HTTP_Client_Plugin *plugin = cls; + int running; + long http_statuscode; CURLMcode mret; - 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", - http_plugin_address_to_string (plugin, s->addr, s->addrlen), - GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey), - plugin->last_tag); -#if 0 - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "URL `%s'\n", url); -#endif + GNUNET_assert (cls != NULL); + + plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + do + { + running = 0; + mret = curl_multi_perform (plugin->curl_multi_handle, &running); + + CURLMsg *msg; + int msgs_left; + + while ((msg = curl_multi_info_read (plugin->curl_multi_handle, &msgs_left))) + { + CURL *easy_h = msg->easy_handle; + struct Session *s = NULL; + char *d = (char *) s; + + if (easy_h == NULL) + { + GNUNET_break (0); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Client: connection to ended with reason %i: `%s', %i handles running\n", + msg->data.result, + curl_easy_strerror (msg->data.result), running); + continue; + } + + GNUNET_assert (CURLE_OK == + curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); + s = (struct Session *) d; + + if (GNUNET_YES != client_exist_session(plugin, s)) + { + GNUNET_break (0); + return; + } + + GNUNET_assert (s != NULL); + if (msg->msg == CURLMSG_DONE) + { + curl_easy_getinfo (easy_h, CURLINFO_RESPONSE_CODE, &http_statuscode); + if (easy_h == s->client_put) + { + if ((0 != msg->data.result) || (http_statuscode != 200)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: PUT connection to `%s' ended with status %i reason %i: `%s'\n", + s, msg->easy_handle, GNUNET_i2s (&s->target), + http_statuscode, + msg->data.result, + curl_easy_strerror (msg->data.result)); + } + else + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: PUT connection to `%s' ended normal\n", + s, msg->easy_handle, GNUNET_i2s (&s->target)); + if (s->client_get == NULL) + { + /* Disconnect other transmission direction and tell transport */ + } + curl_multi_remove_handle (plugin->curl_multi_handle, easy_h); + curl_easy_cleanup (easy_h); + s->put_tmp_disconnecting = GNUNET_NO; + s->put_tmp_disconnected = GNUNET_YES; + s->client_put = NULL; + s->put.easyhandle = NULL; + s->put.s = NULL; + + /* + * Handling a rare case: + * plugin_send was called during temporary put disconnect, + * reconnect required after connection was disconnected + */ + if (GNUNET_YES == s->put_reconnect_required) + { + s->put_reconnect_required = GNUNET_NO; + if (GNUNET_SYSERR == client_connect_put(s)) + { + GNUNET_break (s->client_put == NULL); + GNUNET_break (s->put_tmp_disconnected == GNUNET_NO); + } + } + } + if (easy_h == s->client_get) + { + if ((0 != msg->data.result) || (http_statuscode != 200)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: GET connection to `%s' ended with status %i reason %i: `%s'\n", + s, msg->easy_handle, GNUNET_i2s (&s->target), + http_statuscode, + msg->data.result, + curl_easy_strerror (msg->data.result)); + + } + else + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p/connection %p: GET connection to `%s' ended normal\n", + s, msg->easy_handle, GNUNET_i2s (&s->target)); + /* Disconnect other transmission direction and tell transport */ + s->get.easyhandle = NULL; + s->get.s = NULL; + client_disconnect (s); + } + } + } + } + while (mret == CURLM_CALL_MULTI_PERFORM); + client_schedule (plugin, GNUNET_NO); +} + + +/** + * Connect GET connection for a session + * + * @param s the session to connect + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +static int +client_connect_get (struct Session *s) +{ + CURLMcode mret; /* create get connection */ s->client_get = curl_easy_init (); + s->get.s = s; + s->get.easyhandle = s->client_get; #if VERBOSE_CURL curl_easy_setopt (s->client_get, CURLOPT_VERBOSE, 1L); curl_easy_setopt (s->client_get, CURLOPT_DEBUGFUNCTION, &client_log); - curl_easy_setopt (s->client_get, CURLOPT_DEBUGDATA, s->client_get); + curl_easy_setopt (s->client_get, CURLOPT_DEBUGDATA, &s->get); #endif #if BUILD_HTTPS curl_easy_setopt (s->client_get, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYHOST, 0); #endif - curl_easy_setopt (s->client_get, CURLOPT_URL, url); + curl_easy_setopt (s->client_get, CURLOPT_URL, s->url); //curl_easy_setopt (s->client_get, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); //curl_easy_setopt (s->client_get, CURLOPT_WRITEHEADER, ps); curl_easy_setopt (s->client_get, CURLOPT_READFUNCTION, client_send_cb); curl_easy_setopt (s->client_get, CURLOPT_READDATA, s); curl_easy_setopt (s->client_get, CURLOPT_WRITEFUNCTION, client_receive); curl_easy_setopt (s->client_get, CURLOPT_WRITEDATA, s); - curl_easy_setopt (s->client_get, CURLOPT_TIMEOUT_MS, - (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + /* No timeout by default, timeout done with session timeout */ + curl_easy_setopt (s->client_get, CURLOPT_TIMEOUT, 0); curl_easy_setopt (s->client_get, CURLOPT_PRIVATE, s); curl_easy_setopt (s->client_get, CURLOPT_CONNECTTIMEOUT_MS, - (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); + (long) HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value); curl_easy_setopt (s->client_get, CURLOPT_BUFFERSIZE, 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); #if CURL_TCP_NODELAY curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); #endif + mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_get); + if (mret != CURLM_OK) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, s->plugin->name, + "Session %p : Failed to add GET handle to multihandle: `%s'\n", + s, curl_multi_strerror (mret)); + curl_easy_cleanup (s->client_get); + s->client_get = NULL; + s->get.s = NULL; + s->get.easyhandle = NULL; + GNUNET_break (0); + return GNUNET_SYSERR; + } + + return GNUNET_OK; +} +/** + * Connect a HTTP put connection + * + * @param s the session to connect + * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok + */ +static int +client_connect_put (struct Session *s) +{ + CURLMcode mret; /* create put connection */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Session %p : Init PUT handle \n", s); s->client_put = curl_easy_init (); + s->put.s = s; + s->put.easyhandle = s->client_put; #if VERBOSE_CURL curl_easy_setopt (s->client_put, CURLOPT_VERBOSE, 1L); curl_easy_setopt (s->client_put, CURLOPT_DEBUGFUNCTION, &client_log); - curl_easy_setopt (s->client_put, CURLOPT_DEBUGDATA, s->client_put); + curl_easy_setopt (s->client_put, CURLOPT_DEBUGDATA, &s->put); #endif #if BUILD_HTTPS curl_easy_setopt (s->client_put, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYHOST, 0); #endif - curl_easy_setopt (s->client_put, CURLOPT_URL, url); - curl_easy_setopt (s->client_put, CURLOPT_PUT, 1L); - //curl_easy_setopt (s->client_put, CURLOPT_HEADERFUNCTION, &curl_put_header_cb); + curl_easy_setopt (s->client_put, CURLOPT_URL, s->url); + curl_easy_setopt (s->client_put, CURLOPT_UPLOAD, 1L); + //curl_easy_setopt (s->client_put, CURLOPT_HEADERFUNCTION, &client_curl_header); //curl_easy_setopt (s->client_put, CURLOPT_WRITEHEADER, ps); curl_easy_setopt (s->client_put, CURLOPT_READFUNCTION, client_send_cb); curl_easy_setopt (s->client_put, CURLOPT_READDATA, s); - curl_easy_setopt (s->client_put, CURLOPT_WRITEFUNCTION, client_receive); + curl_easy_setopt (s->client_put, CURLOPT_WRITEFUNCTION, client_receive_put); curl_easy_setopt (s->client_put, CURLOPT_WRITEDATA, s); - curl_easy_setopt (s->client_put, CURLOPT_TIMEOUT_MS, - (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + /* No timeout by default, timeout done with session timeout */ + curl_easy_setopt (s->client_put, CURLOPT_TIMEOUT, 0); curl_easy_setopt (s->client_put, CURLOPT_PRIVATE, s); curl_easy_setopt (s->client_put, CURLOPT_CONNECTTIMEOUT_MS, - (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); + (long) HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value); curl_easy_setopt (s->client_put, CURLOPT_BUFFERSIZE, 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); #if CURL_TCP_NODELAY curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); #endif + mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_put); + if (mret != CURLM_OK) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, s->plugin->name, + "Session %p : Failed to add PUT handle to multihandle: `%s'\n", + s, curl_multi_strerror (mret)); + curl_easy_cleanup (s->client_put); + s->client_put = NULL; + s->put.easyhandle = NULL; + s->put.s = NULL; + s->put_tmp_disconnected = GNUNET_YES; + return GNUNET_SYSERR; + } + s->put_tmp_disconnected = GNUNET_NO; + return GNUNET_OK; +} - GNUNET_free (url); - mret = curl_multi_add_handle (plugin->client_mh, s->client_get); - if (mret != CURLM_OK) +/** + * Connect both PUT and GET connection for a session + * + * @param s the session to connect + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +static int +client_connect (struct Session *s) +{ + + struct HTTP_Client_Plugin *plugin = s->plugin; + int res = GNUNET_OK; + + + /* create url */ + if (NULL == http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)) { - curl_easy_cleanup (s->client_get); - res = GNUNET_SYSERR; - GNUNET_break (0); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Invalid address peer `%s'\n", + GNUNET_i2s (&s->target)); + return GNUNET_SYSERR; } - mret = curl_multi_add_handle (plugin->client_mh, s->client_put); - if (mret != CURLM_OK) + GNUNET_asprintf (&s->url, "%s/%s;%u", + http_common_plugin_address_to_string (plugin, s->addr, s->addrlen), + GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey), + plugin->last_tag); + + plugin->last_tag++; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Initiating outbound session peer `%s' using address `%s'\n", + GNUNET_i2s (&s->target), s->url); + + if ((GNUNET_SYSERR == client_connect_get (s)) || + (GNUNET_SYSERR == client_connect_put (s))) { - curl_multi_remove_handle (plugin->client_mh, s->client_get); - curl_easy_cleanup (s->client_get); - curl_easy_cleanup (s->client_put); - res = GNUNET_SYSERR; - GNUNET_break (0); + GNUNET_break (0); + return GNUNET_SYSERR; } + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p: connected with connections GET %p and PUT %p\n", + s, s->client_get, s->client_put); + /* Perform connect */ plugin->cur_connections += 2; - - plugin->outbound_sessions ++; GNUNET_STATISTICS_set (plugin->env->stats, - "# HTTP outbound sessions", - plugin->outbound_sessions, + "# HTTP client connections", + plugin->cur_connections, GNUNET_NO); /* Re-schedule since handles have changed */ @@ -603,46 +1393,373 @@ client_connect (struct Session *s) plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; } plugin->client_perform_task = GNUNET_SCHEDULER_add_now (client_run, plugin); - return res; } -int -client_start (struct Plugin *plugin) +/** + * Creates a new outbound session the transport service will use to send data to the + * peer + * + * @param cls the plugin + * @param address the address + * @return the session or NULL of max connections exceeded + */ +static struct Session * +http_client_plugin_get_session (void *cls, + const struct GNUNET_HELLO_Address *address) { - int res = GNUNET_OK; - p = plugin; + struct HTTP_Client_Plugin *plugin = cls; + struct Session * s = NULL; + struct sockaddr *sa; + struct GNUNET_ATS_Information ats; + size_t salen = 0; + int res; + + GNUNET_assert (plugin != NULL); + GNUNET_assert (address != NULL); + GNUNET_assert (address->address != NULL); + + /* find existing session */ + s = client_lookup_session (plugin, address); + if (s != NULL) + return s; + + if (plugin->max_connections <= plugin->cur_connections) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, + "Maximum number of connections (%u) reached: " + "cannot connect to peer `%s'\n", + plugin->max_connections, + GNUNET_i2s (&address->peer)); + return NULL; + } + + ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); + ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED); + sa = http_common_socket_from_address (address->address, address->address_length, &res); + if (GNUNET_SYSERR == res) + { + return NULL; + } + else if (GNUNET_YES == res) + { + GNUNET_assert (NULL != sa); + if (AF_INET == sa->sa_family) + { + salen = sizeof (struct sockaddr_in); + } + else if (AF_INET6 == sa->sa_family) + { + salen = sizeof (struct sockaddr_in6); + } + ats = plugin->env->get_address_type (plugin->env->cls, sa, salen); + //fprintf (stderr, "Address %s is in %s\n", GNUNET_a2s (sa,salen), GNUNET_ATS_print_network_type(ntohl(ats.value))); + GNUNET_free (sa); + } + else if (GNUNET_NO == res) + { + ats.value = htonl (GNUNET_ATS_COST_WAN); + } + + if (GNUNET_ATS_NET_UNSPECIFIED == ntohl(ats.value)) + { + GNUNET_break (0); + return NULL; + } + + 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 = address->address_length; + s->ats_address_network_type = ats.value; + s->put_paused = GNUNET_NO; + s->put_tmp_disconnecting = GNUNET_NO; + s->put_tmp_disconnected = GNUNET_NO; + client_start_session_timeout (s); + + /* add new session */ + GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); + + /* initiate new connection */ + if (GNUNET_SYSERR == client_connect (s)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + "Cannot connect to peer `%s' address `%s''\n", + http_common_plugin_address_to_string (NULL, s->addr, s->addrlen), + GNUNET_i2s (&s->target)); + client_delete_session (s); + return NULL; + } + return s; +} + + +/** + * Setup http_client plugin + * + * @param plugin the plugin handle + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +static int +client_start (struct HTTP_Client_Plugin *plugin) +{ curl_global_init (CURL_GLOBAL_ALL); - plugin->client_mh = curl_multi_init (); + plugin->curl_multi_handle = curl_multi_init (); - if (NULL == plugin->client_mh) + if (NULL == plugin->curl_multi_handle) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("Could not initialize curl multi handle, failed to start %s plugin!\n"), - plugin->name); - res = GNUNET_SYSERR; + _("Could not initialize curl multi handle, failed to start %s plugin!\n"), + plugin->name); + return GNUNET_SYSERR; } - return res; + return GNUNET_OK; } +/** + * Session was idle, so disconnect it + */ +static void +client_session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; -void -client_stop (struct Plugin *plugin) + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (TIMEOUT_LOG, + "Session %p was idle for %llu ms, disconnecting\n", + s, (unsigned long long) CLIENT_SESSION_TIMEOUT.rel_value); + + /* call session destroy function */ + GNUNET_assert (GNUNET_OK == client_disconnect (s)); +} + + +/** + * Start session timeout for session s + * + * @param s the session + */ +static void +client_start_session_timeout (struct Session *s) { - p = NULL; - if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) + + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (CLIENT_SESSION_TIMEOUT, + &client_session_timeout, + s); + GNUNET_log (TIMEOUT_LOG, + "Timeout for session %p set to %llu ms\n", + s, (unsigned long long) CLIENT_SESSION_TIMEOUT.rel_value); +} + + +/** + * Increment session timeout due to activity for session s + * + * param s the session + */ +static void +client_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 (CLIENT_SESSION_TIMEOUT, + &client_session_timeout, + s); + GNUNET_log (TIMEOUT_LOG, + "Timeout rescheduled for session %p set to %llu ms\n", + s, (unsigned long long) CLIENT_SESSION_TIMEOUT.rel_value); +} + + +/** + * Cancel timeout due to activity for session s + * + * param s the session + */ +static void +client_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 (TIMEOUT_LOG, "Timeout stopped for session %p\n", s); + } +} + + +/** + * 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 int +http_client_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) +{ + /* struct Plugin *plugin = cls; */ + + /* A HTTP/S client does not have any valid address so:*/ + return GNUNET_NO; +} + + +/** + * Exit point from the plugin. + * + * @param cls api as closure + * @return NULL + */ +void * +LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + struct HTTP_Client_Plugin *plugin = api->cls; + struct Session *pos; + struct Session *next; + + if (NULL == api->cls) { - GNUNET_SCHEDULER_cancel (plugin->client_perform_task); - plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; + /* Stub shutdown */ + GNUNET_free (api); + return NULL; } - curl_multi_cleanup (plugin->client_mh); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Shutting down plugin `%s'\n"), + plugin->name); + + + next = plugin->head; + while (NULL != (pos = next)) + { + next = pos->next; + client_disconnect (pos); + } + if (GNUNET_SCHEDULER_NO_TASK != plugin->client_perform_task) + { + GNUNET_SCHEDULER_cancel (plugin->client_perform_task); + plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; + } + + + if (NULL != plugin->curl_multi_handle) + { + curl_multi_cleanup (plugin->curl_multi_handle); + plugin->curl_multi_handle = NULL; + } curl_global_cleanup (); + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Shutdown for plugin `%s' complete\n"), + plugin->name); + + GNUNET_free (plugin); + GNUNET_free (api); + return NULL; } +/** + * Configure plugin + * + * @param plugin the plugin handle + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +client_configure_plugin (struct HTTP_Client_Plugin *plugin) +{ + unsigned long long max_connections; + + /* Optional parameters */ + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, + plugin->name, + "MAX_CONNECTIONS", &max_connections)) + max_connections = 128; + plugin->max_connections = max_connections; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Maximum number of connections is %u\n"), + plugin->max_connections); + return GNUNET_OK; +} + +/** + * Entry point for the plugin. + */ +void * +LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) +{ + struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; + struct GNUNET_TRANSPORT_PluginFunctions *api; + struct HTTP_Client_Plugin *plugin; + + 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_to_string = &http_common_plugin_address_to_string; + api->string_to_address = &http_common_plugin_string_to_address; + api->address_pretty_printer = &http_common_plugin_address_pretty_printer; + return api; + } + + plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin)); + p = plugin; + plugin->env = env; + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = plugin; + api->send = &http_client_plugin_send; + api->disconnect = &http_client_plugin_disconnect; + api->check_address = &http_client_plugin_address_suggested; + api->get_session = &http_client_plugin_get_session; + api->address_to_string = &http_common_plugin_address_to_string; + api->string_to_address = &http_common_plugin_string_to_address; + api->address_pretty_printer = &http_common_plugin_address_pretty_printer; + + +#if BUILD_HTTPS + plugin->name = "transport-https_client"; + plugin->protocol = "https"; +#else + plugin->name = "transport-http_client"; + plugin->protocol = "http"; +#endif + plugin->last_tag = 1; + + if (GNUNET_SYSERR == client_configure_plugin (plugin)) + { + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); + return NULL; + } + + /* Start client */ + if (GNUNET_SYSERR == client_start (plugin)) + { + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); + return NULL; + } + return api; +} /* end of plugin_transport_http_client.c */ diff --git a/src/transport/plugin_transport_http_common.c b/src/transport/plugin_transport_http_common.c new file mode 100644 index 0000000..bf98330 --- /dev/null +++ b/src/transport/plugin_transport_http_common.c @@ -0,0 +1,408 @@ +/* + This file is part of GNUnet + (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 transport/plugin_transport_http_common.c + * @brief functionality shared by http client and server transport service plugin + * @author Matthias Wachs + */ + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_transport_plugin.h" +#include "plugin_transport_http_common.h" + +struct SplittedHTTPAddress +{ + char *protocol; + char *host; + char *path; + int port; +}; + +static void +http_clean_splitted (struct SplittedHTTPAddress *spa) +{ + if (NULL != spa) + { + GNUNET_free_non_null (spa->protocol); + GNUNET_free_non_null (spa->host); + GNUNET_free_non_null (spa->path); + GNUNET_free_non_null (spa); + } +} + +struct SplittedHTTPAddress * +http_split_address (const char * addr) +{ + struct SplittedHTTPAddress *sp; + char *src = GNUNET_strdup (addr); + char *protocol_start = NULL; + char *host_start = NULL; + char *v6_end = NULL; + char *port_start = NULL; + char *path_start = NULL; + protocol_start = src; + sp = GNUNET_malloc (sizeof (struct SplittedHTTPAddress)); + + /* Address string consists of protocol://host[:port]path*/ + + host_start = strstr (src, "://"); + if (NULL == host_start) + { + GNUNET_free (src); + GNUNET_free (sp); + return NULL; + } + + host_start[0] = '\0'; + sp->protocol = GNUNET_strdup (protocol_start); + + host_start += strlen ("://"); + if (strlen (host_start) == 0) + { + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp); + return NULL; + } + + /* Find path start */ + path_start = strchr (host_start, '/'); + if (NULL != path_start) + { + sp->path = GNUNET_strdup (path_start); + path_start[0] = '\0'; + } + else + sp->path = GNUNET_strdup (""); + + if (strlen(host_start) < 1) + { + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp->path); + GNUNET_free (sp); + return NULL; + } + + if (NULL != (port_start = strrchr (host_start, ':'))) + { + /* *We COULD have a port, but also an IPv6 address! */ + if (NULL != (v6_end = strchr(host_start, ']'))) + { + if (v6_end < port_start) + { + /* IPv6 address + port */ + port_start[0] = '\0'; + port_start ++; + sp->port = atoi (port_start); + if ((0 == sp->port) || (65535 < sp->port)) + { + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp->path); + GNUNET_free (sp); + return NULL; + } + } + else + { + /* IPv6 address + no port */ + if (0 == strcmp(sp->protocol, "https")) + sp->port = HTTPS_DEFAULT_PORT; + else if (0 == strcmp(sp->protocol, "http")) + sp->port = HTTP_DEFAULT_PORT; + } + } + else + { + /* No IPv6 address */ + port_start[0] = '\0'; + port_start ++; + sp->port = atoi (port_start); + if ((0 == sp->port) || (65535 < sp->port)) + { + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp->path); + GNUNET_free (sp); + return NULL; + } + } + } + else + { + /* No ':' as port separator, default port for protocol */ + if (0 == strcmp(sp->protocol, "https")) + sp->port = HTTPS_DEFAULT_PORT; + else if (0 == strcmp(sp->protocol, "http")) + sp->port = HTTP_DEFAULT_PORT; + else + { + GNUNET_break (0); + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp->path); + GNUNET_free (sp); + return NULL; + } + } + if (strlen (host_start) > 0) + sp->host = GNUNET_strdup (host_start); + else + { + GNUNET_break (0); + GNUNET_free (src); + GNUNET_free (sp->protocol); + GNUNET_free (sp->path); + GNUNET_free (sp); + return NULL; + } + GNUNET_free (src); + return sp; +} + +/** + * 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 + */ +void +http_common_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) +{ + const char *saddr = (const char *) addr; + + if ( (NULL == saddr) || + (0 >= addrlen) || + ('\0' != saddr[addrlen-1]) ) + { + asc (asc_cls, NULL); + return; + } + asc (asc_cls, saddr); + asc (asc_cls, 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 + */ +const char * +http_common_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) +{ + const char *saddr = (const char *) addr; + if (NULL == saddr) + return NULL; + if (0 >= addrlen) + return NULL; + if (saddr[addrlen-1] != '\0') + return NULL; + return saddr; +} + +/** + * 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_common_plugin_string_to_address (void *cls, + const char *addr, + uint16_t addrlen, + void **buf, + size_t *added) +{ + if (NULL == addr) + return GNUNET_SYSERR; + if (0 >= addrlen) + return GNUNET_SYSERR; + if (addr[addrlen-1] != '\0') + return GNUNET_SYSERR; + + (*buf) = strdup (addr); + (*added) = strlen (addr) + 1; + return GNUNET_OK; +} + +/** + * Create a HTTP address from a socketaddr + * + * @param protocol protocol + * @param addr sockaddr * address + * @param addrlen length of the address + * @return the string + */ +char * +http_common_address_from_socket (const char *protocol, const struct sockaddr *addr, socklen_t addrlen) +{ + char *res; + GNUNET_asprintf(&res, "%s://%s", protocol, GNUNET_a2s (addr, addrlen)); + return res; +} + +/** + * Create a socketaddr from a HTTP address + * + * @param addr sockaddr * address + * @param addrlen length of the address + * @param res the result: + * GNUNET_SYSERR, invalid input, + * GNUNET_YES: could convert to ip, + * GNUNET_NO: valid input but could not convert to ip (hostname?) + * @return the string + */ +struct sockaddr * +http_common_socket_from_address (const void *addr, size_t addrlen, int *res) +{ + struct SplittedHTTPAddress * spa; + struct sockaddr_storage *s; + (*res) = GNUNET_SYSERR; + char * to_conv; + + if (NULL == addr) + { + GNUNET_break (0); + return NULL; + } + if (0 >= addrlen) + { + GNUNET_break (0); + return NULL; + } + if (((char *) addr)[addrlen-1] != '\0') + { + GNUNET_break (0); + return NULL; + } + + spa = http_split_address (addr); + if (NULL == spa) + { + (*res) = GNUNET_SYSERR; + return NULL; + } + + s = GNUNET_malloc (sizeof (struct sockaddr_storage)); + GNUNET_asprintf (&to_conv, "%s:%u", spa->host, spa->port); + if (GNUNET_SYSERR == GNUNET_STRINGS_to_address_ip (to_conv, strlen(to_conv), s)) + { + /* could be a hostname */ + GNUNET_free (s); + (*res) = GNUNET_NO; + s = NULL; + } + else if ((AF_INET != s->ss_family) && (AF_INET6 != s->ss_family)) + { + + GNUNET_free (s); + (*res) = GNUNET_SYSERR; + s = NULL; + } + else + { + (*res) = GNUNET_YES; + } + http_clean_splitted (spa); + GNUNET_free (to_conv); + return (struct sockaddr *) s; +} + +/** + * Get the length of an address + * + * @param addr address + * @return the size + */ +size_t +http_common_address_get_size (const void *addr) +{ + return strlen (addr) + 1; +} + +/** + * Compare addr1 to addr2 + * + * @param addr1 address1 + * @param addrlen1 address 1 length + * @param addr2 address2 + * @param addrlen2 address 2 length + * @return GNUNET_YES if equal, GNUNET_NO if not, GNUNET_SYSERR on error + */ +size_t +http_common_cmp_addresses (const void *addr1, size_t addrlen1, const void *addr2, size_t addrlen2) +{ + const char *a1 = (const char *) addr1; + const char *a2 = (const char *) addr2; + + if (NULL == a1) + return GNUNET_SYSERR; + if (0 >= addrlen1) + return GNUNET_SYSERR; + if (a1[addrlen1-1] != '\0') + return GNUNET_SYSERR; + + if (NULL == a2) + return GNUNET_SYSERR; + if (0 >= addrlen2) + return GNUNET_SYSERR; + if (a2[addrlen2-1] != '\0') + return GNUNET_SYSERR; + + if (addrlen1 != addrlen2) + return GNUNET_NO; + + if (0 == strcmp (addr1, addr2)) + return GNUNET_YES; + return GNUNET_NO; +} + + + +/* end of plugin_transport_http_common.c */ diff --git a/src/transport/plugin_transport_http_common.h b/src/transport/plugin_transport_http_common.h new file mode 100644 index 0000000..31676c2 --- /dev/null +++ b/src/transport/plugin_transport_http_common.h @@ -0,0 +1,168 @@ +/* + This file is part of GNUnet + (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 transport/plugin_transport_http_common.c + * @brief functionality shared by http client and server transport service plugin + * @author Matthias Wachs + */ + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_transport_plugin.h" +/** + * Timeout values for testing + */ +#define TESTING GNUNET_NO + +#if TESTING + +#define HTTP_SERVER_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) +#define HTTP_CLIENT_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) +#define CLIENT_SESSION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 7) +#define SERVER_SESSION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 7) +#define TIMEOUT_LOG GNUNET_ERROR_TYPE_DEBUG + +#else + +#define HTTP_SERVER_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) +#define HTTP_CLIENT_NOT_VALIDATED_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) +#define CLIENT_SESSION_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT +#define SERVER_SESSION_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT +#define TIMEOUT_LOG GNUNET_ERROR_TYPE_DEBUG + +#endif + +#define HTTP_DEFAULT_PORT 80 +#define HTTPS_DEFAULT_PORT 443 + + +struct SplittedHTTPAddress; + +struct SplittedHTTPAddress * +http_split_address (const char * addr); + +/** + * 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 + */ +void +http_common_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); + +/** + * 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 + */ +const char * +http_common_plugin_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 + * 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_common_plugin_string_to_address (void *cls, + const char *addr, + uint16_t addrlen, + void **buf, + size_t *added); + + +/** + * Create a HTTP address from a socketaddr + * + * @param protocol protocol + * @param addr sockaddr * address + * @param addrlen length of the address + * @return the string + */ +char * +http_common_address_from_socket (const char *protocol, + const struct sockaddr *addr, + socklen_t addrlen); + +/** + * Create a socketaddr from a HTTP address + * + * @param addr sockaddr * address + * @param addrlen length of the address + * @param res the result: + * GNUNET_SYSERR, invalid input, + * GNUNET_YES: could convert to ip, + * GNUNET_NO: valid input but could not convert to ip (hostname?) + * @return the string + */ +struct sockaddr * +http_common_socket_from_address (const void *addr, size_t addrlen, int *res); + +/** + * Get the length of an address + * + * @param addr address + * @return the size + */ +size_t +http_common_address_get_size (const void *addr); + + +/** + * Compare addr1 to addr2 + * + * @param addr1 address1 + * @param addrlen1 address 1 length + * @param addr2 address2 + * @param addrlen2 address 2 length + * @return GNUNET_YES if equal, GNUNET_NO else + */ +size_t +http_common_cmp_addresses (const void *addr1, size_t addrlen1, const void *addr2, size_t addrlen2); +/* end of plugin_transport_http_common.c */ diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 4b4f504..97a28b6 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -19,206 +19,747 @@ */ /** - * @file transport/plugin_transport_http.c - * @brief http transport service plugin + * @file transport/plugin_transport_http_server.c + * @brief HTTP/S server transport plugin * @author Matthias Wachs */ -#include "plugin_transport_http.h" +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_server_lib.h" +#include "gnunet_statistics_service.h" +#include "gnunet_transport_plugin.h" +#include "gnunet_nat_lib.h" +#include "plugin_transport_http_common.h" +#include "microhttpd.h" + +#if BUILD_HTTPS +#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_server_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_server_done +#else +#define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_server_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_server_done +#endif #define HTTP_ERROR_RESPONSE "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"><HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>Not Found</H1>The requested URL was not found on this server.<P><HR><ADDRESS></ADDRESS></BODY></HTML>" #define _RECEIVE 0 #define _SEND 1 -static struct Plugin * p; + +/* Enable output for debbuging URL's of incoming requests */ +#define DEBUG_URL_PARSE GNUNET_NO + /** - * Function that queries MHD's select sets and - * starts the task waiting for them. - * @param plugin plugin - * @param daemon_handle the MHD daemon handle - * @param now schedule now or with MHD delay - * @return gnunet task identifier + * Encapsulation of all of the state of the plugin. */ -static GNUNET_SCHEDULER_TaskIdentifier -server_schedule (struct Plugin *plugin, - struct MHD_Daemon *daemon_handle, - int now); +struct Plugin; -static void -server_log (void *arg, const char *fmt, va_list ap) + +/** + * Session handle for connections. + */ +struct Session { - char text[1024]; + /** + * Stored in a linked list. + */ + struct Session *next; + + /** + * Stored in a linked list. + */ + struct Session *prev; + + /** + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) + */ + struct GNUNET_PeerIdentity target; + + /** + * Pointer to the global plugin struct. + */ + struct HTTP_Server_Plugin *plugin; + + /** + * next pointer for double linked list + */ + struct HTTP_Message *msg_head; + + /** + * previous pointer for double linked list + */ + struct HTTP_Message *msg_tail; + + /** + * Message stream tokenizer for incoming data + */ + struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk; + + /** + * Client send handle + */ + struct ServerConnection *server_recv; + + /** + * Client send handle + */ + struct ServerConnection *server_send; + + /** + * Address + */ + void *addr; + + /** + * Address length + */ + size_t addrlen; + + /** + * Unique HTTP/S connection tag for this connection + */ + uint32_t tag; + + /** + * ATS network type in NBO + */ + uint32_t ats_address_network_type; + + /** + * Was session given to transport service? + */ + int session_passed; + + /** + * Did we immediately end the session in disconnect_cb + */ + int session_ended; + + /** + * Are incoming connection established at the moment + */ + int connect_in_progress; + + /** + * Absolute time when to receive data again + * Used for receive throttling + */ + struct GNUNET_TIME_Absolute next_receive; + + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; +}; + + +struct ServerConnection +{ + /* _RECV or _SEND */ + int direction; + + /* Should this connection get disconnected? GNUNET_YES/NO */ + int disconnect; + + /* For PUT connections: Is this the first or last callback with size 0 */ + int connected; + + /* The session this server connection belongs to */ + struct Session *session; + + /* The MHD connection */ + struct MHD_Connection *mhd_conn; + + /* The MHD daemon */ + struct MHD_Daemon *mhd_daemon; +}; - vsnprintf (text, sizeof (text), fmt, ap); - va_end (ap); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server: %s\n", text); -} /** - * Check if incoming connection is accepted. - * NOTE: Here every connection is accepted - * @param cls plugin as closure - * @param addr address of incoming connection - * @param addr_len address length of incoming connection - * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected + * Encapsulation of all of the state of the plugin. + */ +struct HTTP_Server_Plugin +{ + /** + * Our environment. + */ + struct GNUNET_TRANSPORT_PluginEnvironment *env; + + /** + * Linked list head of open sessions. + */ + + struct Session *head; + + /** + * Linked list tail of open sessions. + */ + struct Session *tail; + + /** + * Plugin name + */ + char *name; + + /** + * Protocol + */ + char *protocol; + + /** + * External address + */ + char *external_hostname; + + /** + * Maximum number of sockets the plugin can use + * Each http inbound /outbound connections are two connections + */ + unsigned int max_connections; + + /** + * Current number of sockets the plugin can use + * Each http inbound /outbound connections are two connections + */ + unsigned int cur_connections; + + /** + * Did we immediately end the session in disconnect_cb + */ + int in_shutdown; + + /** + * Length of peer id + */ + int peer_id_length; + + /** + * External hostname the plugin can be connected to, can be different to + * the host's FQDN, used e.g. for reverse proxying + */ + char *ext_addr; + + /** + * Notify transport only about external address + */ + unsigned int external_only; + + /** + * External address length + */ + size_t ext_addr_len; + + /** + * use IPv6 + */ + uint16_t use_ipv6; + + /** + * use IPv4 + */ + uint16_t use_ipv4; + + /** + * Port used + */ + uint16_t port; + + /** + * Task calling transport service about external address + */ + GNUNET_SCHEDULER_TaskIdentifier notify_ext_task; + + /** + * NAT handle & address management + */ + struct GNUNET_NAT_Handle *nat; + + /** + * List of own addresses + */ + + /** + * IPv4 addresses DLL head + */ + struct HttpAddressWrapper *addr_head; + + /** + * IPv4 addresses DLL tail + */ + struct HttpAddressWrapper *addr_tail; + + /** + * IPv4 server socket to bind to + */ + struct sockaddr_in *server_addr_v4; + + /** + * IPv6 server socket to bind to + */ + struct sockaddr_in6 *server_addr_v6; + + /** + * MHD IPv4 task + */ + GNUNET_SCHEDULER_TaskIdentifier server_v4_task; + + /** + * MHD IPv6 task + */ + GNUNET_SCHEDULER_TaskIdentifier server_v6_task; + + /** + * The IPv4 server is scheduled to run asap + */ + int server_v4_immediately; + + /** + * The IPv6 server is scheduled to run asap + */ + int server_v6_immediately; + + /** + * MHD IPv4 daemon + */ + struct MHD_Daemon *server_v4; + + /** + * MHD IPv4 daemon + */ + struct MHD_Daemon *server_v6; + +#if BUILD_HTTPS + /** + * Crypto related + * + * Example: + * + * Use RC4-128 instead of AES: + * NONE:+VERS-TLS1.0:+ARCFOUR-128:+SHA1:+RSA:+COMP-NULL + * + */ + char *crypto_init; + + /** + * TLS key + */ + char *key; + + /** + * TLS certificate + */ + char *cert; +#endif + +}; + + +/** + * Wrapper to manage addresses + */ +struct HttpAddressWrapper +{ + /** + * Linked list next + */ + struct HttpAddressWrapper *next; + + /** + * Linked list previous + */ + struct HttpAddressWrapper *prev; + + void *addr; + + size_t addrlen; +}; + + +/** + * Message to send using http + */ +struct HTTP_Message +{ + /** + * next pointer for double linked list + */ + struct HTTP_Message *next; + + /** + * previous pointer for double linked list + */ + struct HTTP_Message *prev; + + /** + * buffer containing data to send + */ + char *buf; + + /** + * amount of data already sent + */ + size_t pos; + + /** + * buffer length + */ + size_t size; + + /** + * HTTP/S specific overhead + */ + size_t overhead; + + /** + * Continuation function to call once the transmission buffer + * has again space available. NULL if there is no + * continuation to call. + */ + GNUNET_TRANSPORT_TransmitContinuation transmit_cont; + + /** + * Closure for transmit_cont. + */ + void *transmit_cont_cls; +}; + + +/** + * The http_server plugin handle + */ +static struct HTTP_Server_Plugin * p; + + +/** + * Start session timeout for session s + * @param s the session + */ +static void +server_start_session_timeout (struct Session *s); + + +/** + * Increment session timeout due to activity for session s + * @param s the session + */ +static void +server_reschedule_session_timeout (struct Session *s); + + +/** + * Cancel timeout for session s + * @param s the session + */ +static void +server_stop_session_timeout (struct Session *s); + + +/** + * Disconnect a session s + * @param s the session + */ +static int +server_disconnect (struct Session *s); + + +/** + * Does session s exist? * + * @param plugin the plugin handle + * @param s the session + * @return GNUNET_YES on success, GNUNET_NO on error */ static int -server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) +server_exist_session (struct HTTP_Server_Plugin *plugin, struct Session *s); + + +/** + * Reschedule the execution of both IPv4 and IPv6 server + * @param plugin the plugin + * @param server which server to schedule v4 or v6? + * @param now GNUNET_YES to schedule execution immediately, GNUNET_NO to wait + * until timeout + */ +static void +server_reschedule (struct HTTP_Server_Plugin *plugin, struct MHD_Daemon *server, + int now); + + +/** + * Function that can be used by the transport service to transmit + * a message using the plugin. Note that in the case of a + * peer disconnecting, the continuation MUST be called + * prior to the disconnect notification itself. This function + * will be called with this peer's HELLO message to initiate + * a fresh connection to another peer. + * + * @param cls closure + * @param session which session must be used + * @param msgbuf the message to transmit + * @param msgbuf_size number of bytes in 'msgbuf' + * @param priority how important is the message (most plugins will + * ignore message priority and just FIFO) + * @param to how long to wait at most for the transmission (does not + * require plugins to discard the message after the timeout, + * just advisory for the desired delay; most plugins will ignore + * this as well) + * @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 + * @return number of bytes used (on the physical network, with overheads); + * -1 on hard errors (i.e. address invalid); 0 is a legal value + * and does NOT mean that the message was not transmitted (DV) + */ +static ssize_t +http_server_plugin_send (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 Plugin *plugin = cls; + struct HTTP_Server_Plugin *plugin = cls; + struct HTTP_Message *msg; + int bytes_sent = 0; + char *stat_txt; - if (plugin->cur_connections <= plugin->max_connections) - return MHD_YES; + GNUNET_assert (plugin != NULL); + GNUNET_assert (session != NULL); + + if (GNUNET_NO == server_exist_session (plugin, session)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (NULL == session->server_send) + { + if (GNUNET_NO == session->connect_in_progress) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, session->plugin->name, + "Session %p/connection %p: Sending message with %u bytes to peer `%s' with FAILED\n", + session, session->server_send, + msgbuf_size, GNUNET_i2s (&session->target)); + GNUNET_break (0); + return GNUNET_SYSERR; + } + } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Server: Cannot accept new connections\n"); - return MHD_NO; + if (GNUNET_YES == session->server_send->disconnect) + return GNUNET_SYSERR; } -} -#if BUILD_HTTPS -static char * -server_load_file (const char *file) -{ - struct GNUNET_DISK_FileHandle *gn_file; - uint64_t fsize; - char *text = NULL; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, + "Session %p/connection %p: Sending message with %u to peer `%s' with \n", + session, session->server_send, + msgbuf_size, GNUNET_i2s (&session->target)); - if (GNUNET_OK != GNUNET_DISK_file_size (file, - &fsize, GNUNET_NO, GNUNET_YES)) - return NULL; - text = GNUNET_malloc (fsize + 1); - gn_file = - GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ, - GNUNET_DISK_PERM_USER_READ); - if (gn_file == NULL) + /* create new message and schedule */ + bytes_sent = sizeof (struct HTTP_Message) + msgbuf_size; + msg = GNUNET_malloc (bytes_sent); + msg->next = NULL; + msg->size = msgbuf_size; + msg->pos = 0; + msg->buf = (char *) &msg[1]; + msg->transmit_cont = cont; + msg->transmit_cont_cls = cont_cls; + memcpy (msg->buf, msgbuf, msgbuf_size); + + GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, session->msg_tail, msg); + + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, msgbuf_size, GNUNET_NO); + GNUNET_free (stat_txt); + + if (NULL != session->server_send) { - GNUNET_free (text); - return NULL; + server_reschedule (session->plugin, + session->server_send->mhd_daemon, + GNUNET_YES); + server_reschedule_session_timeout (session); } - if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fsize)) + return bytes_sent; +} + + + +/** + * Function that can be used to force the plugin to disconnect + * from the given peer and cancel all previous transmissions + * (and their continuationc). + * + * @param cls closure + * @param target peer from which to disconnect + */ +static void +http_server_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) +{ + struct HTTP_Server_Plugin *plugin = cls; + struct Session *next = NULL; + struct Session *pos = NULL; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Transport tells me to disconnect `%s'\n", + GNUNET_i2s (target)); + + next = plugin->head; + while (NULL != (pos = next)) { - GNUNET_free (text); - GNUNET_DISK_file_close (gn_file); - return NULL; + next = pos->next; + if (0 == memcmp (target, &pos->target, sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Disconnecting session %p to `%s'\n", + pos, GNUNET_i2s (target)); + server_disconnect (pos); + } } - text[fsize] = '\0'; - GNUNET_DISK_file_close (gn_file); - return text; + } -#endif -#if BUILD_HTTPS - +/** + * 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 int -server_load_certificate (struct Plugin *plugin) +http_server_plugin_address_suggested (void *cls, const void *addr, + size_t addrlen) { - int res = GNUNET_OK; + struct HTTP_Server_Plugin *plugin = cls; + struct HttpAddressWrapper *next; + struct HttpAddressWrapper *pos; - char *key_file; - char *cert_file; - /* Get crypto init string from config - * If not present just use default values */ - - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - plugin->name, - "CRYPTO_INIT", - &plugin->crypto_init)); + if ((NULL != plugin->ext_addr) && + GNUNET_YES == (http_common_cmp_addresses (addr, addrlen, + plugin->ext_addr, plugin->ext_addr_len))) + return GNUNET_OK; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, - "KEY_FILE", &key_file)) + next = plugin->addr_head; + while (NULL != (pos = next)) { - key_file = GNUNET_strdup ("https_key.key"); - } + next = pos->next; + if (GNUNET_YES == (http_common_cmp_addresses(addr, + addrlen, + pos->addr, + pos->addrlen))) + return GNUNET_OK; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, - "CERT_FILE", &cert_file)) - { - GNUNET_asprintf (&cert_file, "%s", "https_cert.crt"); } - /* read key & certificates from file */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Loading TLS certificate from key-file `%s' cert-file`%s'\n", - key_file, cert_file); + return GNUNET_NO; +} - plugin->key = server_load_file (key_file); - plugin->cert = server_load_file (cert_file); - if ((plugin->key == NULL) || (plugin->cert == NULL)) - { - struct GNUNET_OS_Process *cert_creation; +/** + * Creates a new outbound session the transport + * service will use to send data to the peer + * + * Since HTTP/S server cannot create sessions, always return NULL + * + * @param cls the plugin + * @param address the address + * @return always NULL + */ +static struct Session * +http_server_plugin_get_session (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + return NULL; +} - GNUNET_free_non_null (plugin->key); - plugin->key = NULL; - GNUNET_free_non_null (plugin->cert); - plugin->cert = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No usable TLS certificate found, creating certificate\n"); - errno = 0; - cert_creation = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, - "gnunet-transport-certificate-creation", - "gnunet-transport-certificate-creation", - key_file, cert_file, NULL); - if (cert_creation == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("Could not create a new TLS certificate, program `gnunet-transport-certificate-creation' could not be started!\n")); - GNUNET_free (key_file); - GNUNET_free (cert_file); +/** + * Deleting the session + * Must not be used afterwards + * + * @param s the session to delete + */ +static void +server_delete_session (struct Session *s) +{ + struct HTTP_Server_Plugin *plugin = s->plugin; + server_stop_session_timeout(s); - GNUNET_free_non_null (plugin->key); - plugin->key = NULL; - GNUNET_free_non_null (plugin->cert); - plugin->cert = NULL; - GNUNET_free_non_null (plugin->crypto_init); - plugin->crypto_init = NULL; + GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); + struct HTTP_Message *msg = s->msg_head; + struct HTTP_Message *tmp = NULL; - return GNUNET_SYSERR; - } - GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (cert_creation)); - GNUNET_OS_process_destroy (cert_creation); + while (msg != NULL) + { + tmp = msg->next; - plugin->key = server_load_file (key_file); - plugin->cert = server_load_file (cert_file); + GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); + if (msg->transmit_cont != NULL) + { + msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR, + msg->size, msg->pos + msg->overhead); + } + GNUNET_free (msg); + msg = tmp; } - if ((plugin->key == NULL) || (plugin->cert == NULL)) + if (s->msg_tk != NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - _ - ("No usable TLS certificate found and creating one failed!\n"), - "transport-https"); - GNUNET_free (key_file); - GNUNET_free (cert_file); + GNUNET_SERVER_mst_destroy (s->msg_tk); + s->msg_tk = NULL; + } + GNUNET_free (s->addr); + GNUNET_free_non_null (s->server_recv); + GNUNET_free_non_null (s->server_send); + GNUNET_free (s); - GNUNET_free_non_null (plugin->key); - plugin->key = NULL; - GNUNET_free_non_null (plugin->cert); - plugin->cert = NULL; - GNUNET_free_non_null (plugin->crypto_init); - plugin->crypto_init = NULL; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p destroyed\n", s); +} - return GNUNET_SYSERR; - } - GNUNET_free (key_file); - GNUNET_free (cert_file); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n"); - return res; + +/** +* Cancel timeout for session s +* +* @param s the session +*/ +static void +server_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 (TIMEOUT_LOG, "Timeout stopped for session %p\n", s); + } } -#endif + + +/** + * Function that queries MHD's select sets and + * starts the task waiting for them. + * @param plugin plugin + * @param daemon_handle the MHD daemon handle + * @param now schedule immediately + * @return gnunet task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier +server_schedule (struct HTTP_Server_Plugin *plugin, + struct MHD_Daemon *daemon_handle, + int now); /** @@ -229,7 +770,8 @@ server_load_certificate (struct Plugin *plugin) * until timeout */ static void -server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now) +server_reschedule (struct HTTP_Server_Plugin *plugin, struct MHD_Daemon *server, + int now) { if ((server == plugin->server_v4) && (plugin->server_v4 != NULL)) { @@ -264,334 +806,524 @@ server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now) } } + /** - * Callback called by MessageStreamTokenizer when a message has arrived - * @param cls current session as closure - * @param client clien - * @param message the message to be forwarded to transport service + * Disconnect session s + * + * @param s the session + * @return GNUNET_OK on success */ static int -server_receive_mst_cb (void *cls, void *client, - const struct GNUNET_MessageHeader *message) +server_disconnect (struct Session *s) { - struct Session *s = cls; - - GNUNET_assert (NULL != p); - if (GNUNET_NO == exist_session(p, s)) - return GNUNET_OK; + struct ServerConnection * send = NULL; + struct ServerConnection * recv = NULL; - struct Plugin *plugin = s->plugin; - struct GNUNET_TIME_Relative delay; + if (GNUNET_NO == server_exist_session (p, s)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } - delay = http_plugin_receive (s, &s->target, message, s, s->addr, s->addrlen); + send = (struct ServerConnection *) s->server_send; + if (s->server_send != NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Server: %p / %p Terminating inbound PUT session to peer `%s'\n", + s, s->server_send, GNUNET_i2s (&s->target)); - s->next_receive = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); + send->disconnect = GNUNET_YES; +#if MHD_VERSION >= 0x00090E00 + MHD_set_connection_option (send->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + 1); +#endif + server_reschedule (s->plugin, send->mhd_daemon, GNUNET_YES); + } - if (delay.rel_value > 0) + recv = (struct ServerConnection *) s->server_recv; + if (recv != NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: peer `%s' address `%s' next read delayed for %llu ms\n", - GNUNET_i2s (&s->target), - http_plugin_address_to_string (NULL, s->addr, s->addrlen), - delay); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Server: %p / %p Terminating inbound GET session to peer `%s'\n", + s, s->server_recv, GNUNET_i2s (&s->target)); + + recv->disconnect = GNUNET_YES; +#if MHD_VERSION >= 0x00090E00 + MHD_set_connection_option (recv->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + 1); +#endif + server_reschedule (s->plugin, recv->mhd_daemon, GNUNET_YES); } return GNUNET_OK; } +static void +server_mhd_connection_timeout (struct HTTP_Server_Plugin *plugin, struct Session *s, int to) +{ +#if MHD_VERSION >= 0x00090E00 + /* Setting timeouts for other connections */ + if (s->server_recv != NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Setting timeout for %p to %u sec.\n", s->server_recv, to); + MHD_set_connection_option (s->server_recv->mhd_conn, + MHD_CONNECTION_OPTION_TIMEOUT, + to); + server_reschedule (plugin, s->server_recv->mhd_daemon, GNUNET_NO); + } + if (s->server_send != NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Setting timeout for %p to %u sec.\n", s->server_send, to); + MHD_set_connection_option (s->server_send->mhd_conn, + MHD_CONNECTION_OPTION_TIMEOUT, + to); + server_reschedule (plugin, s->server_send->mhd_daemon, GNUNET_NO); + } +#endif +} /** - * Callback called by MHD when it needs data to send - * @param cls current session - * @param pos position in buffer - * @param buf the buffer to write data to - * @param max max number of bytes available in buffer - * @return bytes written to buffer + * Parse incoming URL for tag and target + * + * @param plugin plugin + * @param url incoming url + * @param target where to store the target + * @param tag where to store the tag + * @return GNUNET_OK on success, GNUNET_SYSERR on error */ -static ssize_t -server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) + +static int +server_parse_url (struct HTTP_Server_Plugin *plugin, const char * url, struct GNUNET_PeerIdentity * target, uint32_t *tag) { - struct Session *s = cls; - ssize_t bytes_read = 0; - struct HTTP_Message *msg; + char * tag_start = NULL; + char * tag_end = NULL; + char * target_start = NULL; + char * separator = NULL; + char hash[plugin->peer_id_length+1]; + int hash_length; + unsigned long int ctag; + + /* URL parsing + * URL is valid if it is in the form [prefix with (multiple) '/'][peerid[103];tag]*/ + + if (NULL == url) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + /* convert tag */ - GNUNET_assert (NULL != p); - if (GNUNET_NO == exist_session(p, s)) - return 0; - msg = s->msg_head; - if (NULL != msg) + /* find separator */ + separator = strrchr (url, ';'); + + if (NULL == separator) { - /* sending */ - bytes_read = GNUNET_MIN (msg->size - msg->pos, - max); - memcpy (buf, &msg->buf[msg->pos], bytes_read); - msg->pos += bytes_read; + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + tag_start = separator + 1; - /* 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_free (msg); - } + if (strlen (tag_start) == 0) + { + /* No tag after separator */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, - "Server: %p: sent %u bytes\n", s, bytes_read); - return bytes_read; -} + ctag = strtoul (tag_start, &tag_end, 10); + if (ctag == 0) + { + /* tag == 0 , invalid */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + if ((ctag == ULONG_MAX) && (ERANGE == errno)) + { + /* out of range: > ULONG_MAX */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (ctag > UINT32_MAX) + { + /* out of range: > UINT32_MAX */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + (*tag) = (uint32_t) ctag; + if (NULL == tag_end) + { + /* no char after tag */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (url[strlen(url)] != tag_end[0]) + { + /* there are more not converted chars after tag */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (DEBUG_URL_PARSE) + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Found tag `%u' in url\n", (*tag)); + /* convert peer id */ + target_start = strrchr (url, '/'); + if (NULL == target_start) + { + /* no leading '/' */ + target_start = (char *) url; + } + target_start++; + hash_length = separator - target_start; + if (hash_length != plugin->peer_id_length) + { + /* no char after tag */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } + memcpy (hash, target_start, hash_length); + hash[hash_length] = '\0'; -static struct Session * -server_lookup_session (struct Plugin *plugin, - struct ServerConnection * sc) -{ - struct Session *s; + if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target->hashPubKey))) + { + /* hash conversion failed */ + if (DEBUG_URL_PARSE) GNUNET_break (0); + return GNUNET_SYSERR; + } - 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; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Found target `%s' in url\n", GNUNET_h2s_full(&target->hashPubKey)); + return GNUNET_OK; } +/** + * Lookup a mhd connection and create one if none is found + * + * @param plugin the plugin handle + * @param mhd_connection the incoming mhd_connection + * @param url incoming requested URL + * @param method PUT or GET + * @return the server connecetion + */ static struct ServerConnection * -server_lookup_serverconnection (struct Plugin *plugin, +server_lookup_connection (struct HTTP_Server_Plugin *plugin, struct MHD_Connection *mhd_connection, const char *url, const char *method) { struct Session *s = NULL; - struct Session *t; struct ServerConnection *sc = NULL; const union MHD_ConnectionInfo *conn_info; struct GNUNET_ATS_Information ats; - struct IPv4HttpAddress a4; - struct IPv6HttpAddress a6; - struct sockaddr_in *s4; - struct sockaddr_in6 *s6; - void *a; - size_t a_len; + + char *addr; + size_t addr_len; + struct GNUNET_PeerIdentity target; - int check = GNUNET_NO; uint32_t tag = 0; int direction = GNUNET_SYSERR; + int to; conn_info = MHD_get_connection_info (mhd_connection, - MHD_CONNECTION_INFO_CLIENT_ADDRESS); + MHD_CONNECTION_INFO_CLIENT_ADDRESS); if ((conn_info->client_addr->sa_family != AF_INET) && (conn_info->client_addr->sa_family != AF_INET6)) return NULL; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "New %s connection from %s\n", method, url); - if ((strlen (&url[1]) >= 105) && (url[104] == ';')) + if (GNUNET_SYSERR == server_parse_url (plugin, url, &target, &tag)) { - char hash[104]; - char *tagc = (char *) &url[105]; - - memcpy (&hash, &url[1], 103); - hash[103] = '\0'; - if (GNUNET_OK == - GNUNET_CRYPTO_hash_from_string ((const char *) &hash, - &(target.hashPubKey))) - { - tag = strtoul (tagc, NULL, 10); - if (tagc > 0) - check = GNUNET_YES; - } + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Invalid url %s\n", url); + return NULL; } - if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) direction = _RECEIVE; else if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) direction = _SEND; else { - GNUNET_break_op (0); - goto error; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Invalid method %s connection from %s\n", method, url); + return NULL; } - - if (check == GNUNET_NO) - goto error; - plugin->cur_connections++; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: New %s connection from %s with tag %u\n", + "New %s connection from %s with tag %u (%u of %u)\n", method, - GNUNET_i2s (&target), tag); - + GNUNET_i2s (&target), tag, + plugin->cur_connections, plugin->max_connections); /* find duplicate session */ - t = plugin->head; - while (t != NULL) - { - if ((t->inbound) && - (0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) - && - /* FIXME add source address comparison */ - (t->tag == tag)) + s = plugin->head; + while (s != NULL) + { + if ((0 == memcmp (&s->target, &target, sizeof (struct GNUNET_PeerIdentity))) && + (s->tag == tag)) break; - t = t->next; + s = s->next; } - if (t != NULL) + if (s != NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Duplicate session, dismissing new connection from peer `%s'\n", - GNUNET_i2s (&target)); - goto error; - } - - /* find semi-session */ - t = plugin->server_semi_head; + if ((_RECEIVE == direction) && (NULL != s->server_recv)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", + GNUNET_i2s (&target), + tag); + return NULL; - while (t != NULL) + } + if ((_SEND == direction) && (NULL != s->server_send)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Duplicate GET connection from `%s' tag %u, dismissing new connection\n", + GNUNET_i2s (&target), + tag); + return NULL; + } + } + else { - /* FIXME add source address comparison */ - if ((0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) - && (t->tag == tag)) + /* create new session */ + switch (conn_info->client_addr->sa_family) { + case (AF_INET): + addr = http_common_address_from_socket (plugin->protocol, conn_info->client_addr, sizeof (struct sockaddr_in)); + addr_len = http_common_address_get_size (addr); + ats = plugin->env->get_address_type (plugin->env->cls, conn_info->client_addr, sizeof (struct sockaddr_in)); break; + case (AF_INET6): + addr = http_common_address_from_socket (plugin->protocol, conn_info->client_addr, sizeof (struct sockaddr_in6)); + addr_len = http_common_address_get_size (addr); + ats = plugin->env->get_address_type (plugin->env->cls, conn_info->client_addr, sizeof (struct sockaddr_in6)); + break; + default: + GNUNET_break (0); + return NULL; } - t = t->next; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Creating new session for peer `%s' connecting from `%s'\n", + GNUNET_i2s (&target), + http_common_plugin_address_to_string (NULL, addr, addr_len)); + + s = GNUNET_malloc (sizeof (struct Session)); + memcpy (&s->target, &target, sizeof (struct GNUNET_PeerIdentity)); + s->plugin = plugin; + s->addr = addr; + s->addrlen = addr_len; + s->ats_address_network_type = ats.value; + s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; + s->tag = tag; + s->server_recv = NULL; + s->server_send = NULL; + s->session_passed = GNUNET_NO; + s->session_ended = GNUNET_NO; + s->connect_in_progress = GNUNET_YES; + server_start_session_timeout(s); + GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); } + sc = GNUNET_malloc (sizeof (struct ServerConnection)); + if (conn_info->client_addr->sa_family == AF_INET) + sc->mhd_daemon = plugin->server_v4; + if (conn_info->client_addr->sa_family == AF_INET6) + sc->mhd_daemon = plugin->server_v6; + sc->mhd_conn = mhd_connection; + sc->direction = direction; + sc->connected = GNUNET_NO; + sc->session = s; + if (direction == _SEND) + s->server_send = sc; + if (direction == _RECEIVE) + s->server_recv = sc; - if (t == NULL) - goto create; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Found existing semi-session for `%s'\n", - GNUNET_i2s (&target)); + if ((NULL != s->server_send) && (NULL != s->server_recv)) + s->connect_in_progress = GNUNET_NO; /* PUT and GET are connected */ - if ((direction == _SEND) && (t->server_send != NULL)) +#if MHD_VERSION >= 0x00090E00 + if ((NULL == s->server_recv) || (NULL == s->server_send)) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Duplicate GET session, dismissing new connection from peer `%s'\n", - GNUNET_i2s (&target)); - goto error; + to = (HTTP_SERVER_NOT_VALIDATED_TIMEOUT.rel_value / 1000); + MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); + server_reschedule (plugin, sc->mhd_daemon, GNUNET_NO); } else { - s = t; - GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head, - plugin->server_semi_tail, s); - GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Found matching semi-session, merging session for peer `%s'\n", - GNUNET_i2s (&target)); + "Session %p for peer `%s' fully connected\n", + s, GNUNET_i2s (&target)); + to = (SERVER_SESSION_TIMEOUT.rel_value / 1000); + server_mhd_connection_timeout (plugin, s, to); + } - plugin->inbound_sessions ++; - GNUNET_STATISTICS_set (plugin->env->stats, - "# HTTP inbound sessions", - plugin->inbound_sessions, - GNUNET_NO); - GNUNET_assert (NULL != s); - goto found; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Setting timeout for %p to %u sec.\n", sc, to); +#endif + return sc; +} + + +/** + * Lookup a session for a server connection + * + * @param plugin the plugin + * @param sc the server connection + * @return the session found or NULL + */ +static struct Session * +server_lookup_session (struct HTTP_Server_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; + return NULL; +} + +int +server_exist_session (struct HTTP_Server_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; } - if ((direction == _RECEIVE) && (t->server_recv != NULL)) + return GNUNET_NO; +} + + +/** + * Callback called by MHD when it needs data to send + * + * @param cls current session + * @param pos position in buffer + * @param buf the buffer to write data to + * @param max max number of bytes available in buffer + * @return bytes written to buffer + */ +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; + char *stat_txt; + + GNUNET_assert (NULL != p); + if (GNUNET_NO == server_exist_session (p, s)) + return 0; + msg = s->msg_head; + if (NULL != msg) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Duplicate PUT session, dismissing new connection from peer `%s'\n", - GNUNET_i2s (&target)); - goto error; + /* sending */ + 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, + msg->size, msg->size + msg->overhead); + GNUNET_free (msg); + } } - else + if (0 < bytes_read) { - s = t; - GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head, - plugin->server_semi_tail, s); - GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); - 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; - } - -create: -/* create new session */ - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Creating new session for peer `%s' \n", - GNUNET_i2s (&target)); - switch (conn_info->client_addr->sa_family) - { - case (AF_INET): - s4 = ((struct sockaddr_in *) conn_info->client_addr); - a4.u4_port = s4->sin_port; - memcpy (&a4.ipv4_addr, &s4->sin_addr, sizeof (struct in_addr)); - a = &a4; - a_len = sizeof (struct IPv4HttpAddress); - ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) s4, sizeof (struct sockaddr_in)); - break; - case (AF_INET6): - s6 = ((struct sockaddr_in6 *) conn_info->client_addr); - a6.u6_port = s6->sin6_port; - memcpy (&a6.ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr)); - a = &a6; - a_len = sizeof (struct IPv6HttpAddress); - ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) s6, sizeof (struct sockaddr_in6)); - break; - default: - GNUNET_break (0); - goto error; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Sent %u bytes to peer `%s' with session %p \n", bytes_read, GNUNET_i2s (&s->target), s); + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", p->protocol); + GNUNET_STATISTICS_update (p->env->stats, + stat_txt, -bytes_read, GNUNET_NO); + GNUNET_free (stat_txt); + GNUNET_asprintf (&stat_txt, "# bytes transmitted via %s_server", p->protocol); + GNUNET_STATISTICS_update (p->env->stats, + stat_txt, bytes_read, GNUNET_NO); + GNUNET_free (stat_txt); } - 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_UNIT_ZERO_ABS; - s->tag = tag; - s->server_recv = NULL; - s->server_send = NULL; - - GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, - plugin->server_semi_tail, s); - goto found; - -error: - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Invalid connection request\n"); - return NULL; + return bytes_read; +} -found: - sc = GNUNET_malloc (sizeof (struct ServerConnection)); - sc->mhd_conn = mhd_connection; - sc->direction = direction; - sc->session = s; - if (direction == _SEND) - s->server_send = sc; - if (direction == _RECEIVE) - s->server_recv = sc; -#if MHD_VERSION >= 0x00090E00 - int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); +/** + * Callback called by MessageStreamTokenizer when a message has arrived + * + * @param cls current session as closure + * @param client client + * @param message the message to be forwarded to transport service + * @return GNUNET_OK + */ +static int +server_receive_mst_cb (void *cls, void *client, + const struct GNUNET_MessageHeader *message) +{ + struct Session *s = cls; + struct GNUNET_ATS_Information atsi[2]; + struct GNUNET_TIME_Relative delay; + char *stat_txt; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %p to %u sec.\n", sc, to); - MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); + GNUNET_assert (NULL != p); + if (GNUNET_NO == server_exist_session(p, s)) + return GNUNET_OK; - struct MHD_Daemon *d = NULL; + struct HTTP_Server_Plugin *plugin = s->plugin; - if (s->addrlen == sizeof (struct IPv6HttpAddress)) - d = plugin->server_v6; - if (s->addrlen == sizeof (struct IPv4HttpAddress)) - d = plugin->server_v4; + atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + atsi[0].value = htonl (1); + atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); + atsi[1].value = s->ats_address_network_type; + GNUNET_break (s->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED)); - server_reschedule (plugin, d, GNUNET_NO); -#endif - return sc; + + delay = plugin->env->receive (plugin->env->cls, + &s->target, + message, + (const struct GNUNET_ATS_Information *) &atsi, 2, + s, s->addr, s->addrlen); + + GNUNET_asprintf (&stat_txt, "# bytes received via %s_server", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, ntohs (message->size), GNUNET_NO); + GNUNET_free (stat_txt); + + s->session_passed = GNUNET_YES; + s->next_receive = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); + if (delay.rel_value > 0) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Peer `%s' address `%s' next read delayed for %llu ms\n", + GNUNET_i2s (&s->target), + http_common_plugin_address_to_string (NULL, s->addr, s->addrlen), + delay); + } + server_reschedule_session_timeout (s); + return GNUNET_OK; } + /** - * Process GET or PUT request received via MHD. For - * GET, queue response that will send back our pending - * messages. For PUT, process incoming data and send - * to GNUnet core. In either case, check if a session - * already exists and create a new one if not. + * MHD callback for a new incoming connection + * + * @param cls the plugin handle + * @param mhd_connection the mhd connection + * @param url the requested URL + * @param method GET or PUT + * @param version HTTP version + * @param upload_data upload data + * @param upload_data_size sizeof upload data + * @param httpSessionCache the session cache to remember the connection + * @return MHD_YES if connection is accepted, MHD_NO on reject */ static int server_access_cb (void *cls, struct MHD_Connection *mhd_connection, @@ -599,24 +1331,34 @@ 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 HTTP_Server_Plugin *plugin = cls; + int res = MHD_YES; + struct ServerConnection *sc = *httpSessionCache; struct Session *s; struct MHD_Response *response; - int res = MHD_YES; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %u\n"), + sc, + plugin->cur_connections, plugin->max_connections, + method, version, url, (*upload_data_size)); GNUNET_assert (cls != NULL); if (sc == NULL) { /* new connection */ - sc = server_lookup_serverconnection (plugin, mhd_connection, url, method); + sc = server_lookup_connection (plugin, mhd_connection, url, method); if (sc != NULL) + { (*httpSessionCache) = sc; + } else { - response = - MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE), - HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); + response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE), HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); + MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + "text/html"); res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); MHD_destroy_response (response); return res; @@ -635,65 +1377,81 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, /* existing connection */ sc = (*httpSessionCache); s = sc->session; - GNUNET_assert (NULL != s); - /* connection is to be disconnected */ if (sc->disconnect == GNUNET_YES) { - /* Sent HTTP/1.1: 200 OK as PUT Response\ */ - response = - MHD_create_response_from_data (strlen ("Thank you!"), "Thank you!", + /* Sent HTTP/1.1: 200 OK as response */ + response = MHD_create_response_from_data (strlen ("Thank you!"), + "Thank you!", MHD_NO, MHD_NO); res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); MHD_destroy_response (response); return MHD_YES; } - GNUNET_assert (s != NULL); - /* Check if both directions are connected */ - if ((sc->session->server_recv == NULL) || (sc->session->server_send == NULL)) - { - /* Delayed read from since not both semi-connections are connected */ - return MHD_YES; - } if (sc->direction == _SEND) { - response = - MHD_create_response_from_callback (-1, 32 * 1024, &server_send_callback, - s, NULL); + response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, + 32 * 1024, + &server_send_callback, s, + NULL); MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); MHD_destroy_response (response); return MHD_YES; } if (sc->direction == _RECEIVE) { - if (*upload_data_size == 0) + if ((*upload_data_size == 0) && (sc->connected == GNUNET_NO)) { + /* (*upload_data_size == 0) first callback when header are passed */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Peer `%s' PUT on address `%s' connected\n", + "Session %p / Connection %p: Peer `%s' PUT on address `%s' connected\n", + s, sc, GNUNET_i2s (&s->target), - http_plugin_address_to_string (NULL, s->addr, - s->addrlen)); + http_common_plugin_address_to_string (NULL, + s->addr, + s->addrlen)); + sc->connected = GNUNET_YES; return MHD_YES; } - - /* Receiving data */ - if ((*upload_data_size > 0)) + else if ((*upload_data_size == 0) && (sc->connected == GNUNET_YES)) + { + /* (*upload_data_size == 0) when upload is complete */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p / Connection %p: Peer `%s' PUT on address `%s' finished upload\n", + s, sc, + GNUNET_i2s (&s->target), + http_common_plugin_address_to_string (NULL, + s->addr, + s->addrlen)); + sc->connected = GNUNET_NO; + /* Sent HTTP/1.1: 200 OK as PUT Response\ */ + response = MHD_create_response_from_data (strlen ("Thank you!"), + "Thank you!", + MHD_NO, MHD_NO); + res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + return MHD_YES; + } + else if ((*upload_data_size > 0) && (sc->connected == GNUNET_YES)) { + /* (*upload_data_size > 0) for every segment received */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: peer `%s' PUT on address `%s' received %u bytes\n", + "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %u bytes\n", + s, sc, GNUNET_i2s (&s->target), - http_plugin_address_to_string (NULL, s->addr, - s->addrlen), + http_common_plugin_address_to_string (NULL, + s->addr, + s->addrlen), *upload_data_size); struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); if ((s->next_receive.abs_value <= now.abs_value)) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: %p: PUT with %u bytes forwarded to MST\n", s, + "PUT with %u bytes forwarded to MST\n", *upload_data_size); if (s->msg_tk == NULL) { @@ -701,65 +1459,47 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, } GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, *upload_data_size, GNUNET_NO, GNUNET_NO); - #if MHD_VERSION >= 0x00090E00 - int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); - struct ServerConnection *t = NULL; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Received %u bytes\n", *upload_data_size); - /* Setting timeouts for other connections */ - if (s->server_recv != NULL) - { - t = s->server_recv; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %p to %u sec.\n", t, - to); - MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, - to); - } - if (s->server_send != NULL) - { - t = s->server_send; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %p to %u sec.\n", t, - to); - MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, - to); - } - struct MHD_Daemon *d = NULL; - - if (s->addrlen == sizeof (struct IPv6HttpAddress)) - d = plugin->server_v6; - if (s->addrlen == sizeof (struct IPv4HttpAddress)) - d = plugin->server_v4; - server_reschedule (plugin, d, GNUNET_NO); + server_mhd_connection_timeout (plugin, s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); #endif (*upload_data_size) = 0; } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Server: %p no inbound bandwidth available! Next read was delayed by %llu ms\n", - s, now.abs_value - s->next_receive.abs_value); + "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %llu ms\n", + s, sc, now.abs_value - s->next_receive.abs_value); } return MHD_YES; } else + { + GNUNET_break (0); return MHD_NO; + } } return res; } + +/** + * Callback from MHD when a connection disconnects + * + * @param cls closure + * @param connection the disconnected MHD connection + * @param httpSessionCache the pointer to distinguish + */ static void server_disconnect_cb (void *cls, struct MHD_Connection *connection, void **httpSessionCache) { struct ServerConnection *sc = *httpSessionCache; - struct ServerConnection *tc = NULL; struct Session *s = NULL; struct Session *t = NULL; - struct Plugin *plugin = NULL; + struct HTTP_Server_Plugin *plugin = NULL; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, p->name, + "Disconnect for connection %p \n", sc); if (sc == NULL) return; @@ -768,7 +1508,12 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, return; GNUNET_assert (NULL != p); - if (GNUNET_NO == exist_session(p, s)) + for (t = p->head; t != NULL; t = t->next) + { + if (t == s) + break; + } + if (NULL == t) return; plugin = s->plugin; @@ -776,36 +1521,39 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "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)); + "Peer `%s' connection %p, GET on address `%s' disconnected\n", + GNUNET_i2s (&s->target), s->server_send, + http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); s->server_send = NULL; - if (NULL != (tc = s->server_recv)) + if (NULL != (s->server_recv)) { - tc->disconnect = GNUNET_YES; - GNUNET_assert (NULL != tc->mhd_conn); + s->server_recv->disconnect = GNUNET_YES; + GNUNET_assert (NULL != s->server_recv->mhd_conn); #if MHD_VERSION >= 0x00090E00 - MHD_set_connection_option (tc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + MHD_set_connection_option (s->server_recv->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, 1); #endif + server_reschedule (plugin, s->server_recv->mhd_daemon, GNUNET_NO); } } if (sc->direction == _RECEIVE) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "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)); + "Peer `%s' connection %p PUT on address `%s' disconnected\n", + GNUNET_i2s (&s->target), s->server_recv, + http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); s->server_recv = NULL; - if (NULL != (tc = s->server_send)) + /* Do not terminate session when PUT disconnects + if (NULL != (s->server_send)) { - tc->disconnect = GNUNET_YES; - GNUNET_assert (NULL != tc->mhd_conn); + s->server_send->disconnect = GNUNET_YES; + GNUNET_assert (NULL != s->server_send->mhd_conn); #if MHD_VERSION >= 0x00090E00 - MHD_set_connection_option (tc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + MHD_set_connection_option (s->server_send->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, 1); #endif - } + server_reschedule (plugin, s->server_send->mhd_daemon, GNUNET_NO); + }*/ if (s->msg_tk != NULL) { GNUNET_SERVER_mst_destroy (s->msg_tk); @@ -814,84 +1562,67 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, } GNUNET_free (sc); - - t = plugin->server_semi_head; - while (t != NULL) - { - if (t == s) - { - GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head, - plugin->server_semi_tail, s); - GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); - break; - } - t = t->next; - } plugin->cur_connections--; - struct MHD_Daemon *d = NULL; - - if (s->addrlen == sizeof (struct IPv6HttpAddress)) - d = plugin->server_v6; - if (s->addrlen == sizeof (struct IPv4HttpAddress)) - d = plugin->server_v4; - server_reschedule (plugin, d, GNUNET_NO); - if ((s->server_send == NULL) && (s->server_recv == NULL)) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: peer `%s' on address `%s' disconnected\n", + "Peer `%s' on address `%s' disconnected\n", GNUNET_i2s (&s->target), - http_plugin_address_to_string (NULL, s->addr, s->addrlen)); - if (s->msg_tk != NULL) + http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); + + if ((GNUNET_YES == s->session_passed) && (GNUNET_NO == s->session_ended)) { - GNUNET_SERVER_mst_destroy (s->msg_tk); - s->msg_tk = NULL; + /* Notify transport immediately that this session is invalid */ + s->session_ended = GNUNET_YES; + plugin->env->session_end (plugin->env->cls, &s->target, s); } - - 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); + server_delete_session (s); } + } -int -server_disconnect (struct Session *s) -{ - if (s->server_send != NULL) - { - ((struct ServerConnection *) s->server_send)->disconnect = GNUNET_YES; - } - if (s->server_recv != NULL) - { - ((struct ServerConnection *) s->server_recv)->disconnect = GNUNET_YES; - } - return GNUNET_OK; -} +/** + * Check if incoming connection is accepted. -int -server_send (struct Session *s, struct HTTP_Message *msg) + * @param cls plugin as closure + * @param addr address of incoming connection + * @param addr_len address length of incoming connection + * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected + * + */ +static int +server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) { - GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); + struct HTTP_Server_Plugin *plugin = cls; - if (s->addrlen == sizeof (struct IPv4HttpAddress)) + if (plugin->cur_connections <= plugin->max_connections) { - server_reschedule (s->plugin, s->plugin->server_v4, GNUNET_YES); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Accepting connection (%u of %u) from `%s'\n"), + plugin->cur_connections, plugin->max_connections, + GNUNET_a2s (addr, addr_len)); + return MHD_YES; } - else if (s->addrlen == sizeof (struct IPv6HttpAddress)) + else { - server_reschedule (s->plugin, s->plugin->server_v6, GNUNET_YES); + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, + _("Server reached maximum number connections (%u), rejecting new connection\n"), + plugin->max_connections); + return MHD_NO; } - else - return GNUNET_SYSERR; - return GNUNET_OK; } +static void +server_log (void *arg, const char *fmt, va_list ap) +{ + char text[1024]; + + vsnprintf (text, sizeof (text), fmt, ap); + va_end (ap); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server: %s\n", text); +} /** @@ -903,7 +1634,7 @@ server_send (struct Session *s, struct HTTP_Message *msg) static void server_v4_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct Plugin *plugin = cls; + struct HTTP_Server_Plugin *plugin = cls; GNUNET_assert (cls != NULL); @@ -929,7 +1660,7 @@ server_v4_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void server_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct Plugin *plugin = cls; + struct HTTP_Server_Plugin *plugin = cls; GNUNET_assert (cls != NULL); plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; @@ -944,15 +1675,20 @@ server_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) server_reschedule (plugin, plugin->server_v6, GNUNET_NO); } + +#define UNSIGNED_MHD_LONG_LONG unsigned MHD_LONG_LONG + /** * Function that queries MHD's select sets and * starts the task waiting for them. + * * @param plugin plugin * @param daemon_handle the MHD daemon handle * @return gnunet task identifier */ static GNUNET_SCHEDULER_TaskIdentifier -server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, +server_schedule (struct HTTP_Server_Plugin *plugin, + struct MHD_Daemon *daemon_handle, int now) { GNUNET_SCHEDULER_TaskIdentifier ret; @@ -963,12 +1699,15 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, struct GNUNET_NETWORK_FDSet *wws; struct GNUNET_NETWORK_FDSet *wes; int max; - unsigned MHD_LONG_LONG timeout; + UNSIGNED_MHD_LONG_LONG timeout; static unsigned long long last_timeout = 0; int haveto; struct GNUNET_TIME_Relative tv; + if (GNUNET_YES == plugin->in_shutdown) + return GNUNET_SCHEDULER_NO_TASK; + ret = GNUNET_SCHEDULER_NO_TASK; FD_ZERO (&rs); FD_ZERO (&ws); @@ -983,14 +1722,16 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, { if (timeout != last_timeout) { -#if VERBOSE_SERVER + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "SELECT Timeout changed from %llu to %llu\n", last_timeout, timeout); -#endif last_timeout = timeout; } - tv.rel_value = (uint64_t) timeout; + if (timeout <= GNUNET_TIME_UNIT_SECONDS.rel_value) + tv.rel_value = (uint64_t) timeout; + else + tv = GNUNET_TIME_UNIT_SECONDS; } else tv = GNUNET_TIME_UNIT_SECONDS; @@ -1039,38 +1780,216 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, return ret; } -int -server_start (struct Plugin *plugin) + +#if BUILD_HTTPS +/** + * Load ssl certificate from file + * + * @param file filename + * @return content of the file + */ +static char * +server_load_file (const char *file) +{ + struct GNUNET_DISK_FileHandle *gn_file; + uint64_t fsize; + char *text = NULL; + + if (GNUNET_OK != GNUNET_DISK_file_size (file, + &fsize, GNUNET_NO, GNUNET_YES)) + return NULL; + text = GNUNET_malloc (fsize + 1); + gn_file = + GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_USER_READ); + if (gn_file == NULL) + { + GNUNET_free (text); + return NULL; + } + if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fsize)) + { + GNUNET_free (text); + GNUNET_DISK_file_close (gn_file); + return NULL; + } + text[fsize] = '\0'; + GNUNET_DISK_file_close (gn_file); + return text; +} +#endif + + +#if BUILD_HTTPS +/** + * Load ssl certificate + * + * @param plugin the plugin + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +server_load_certificate (struct HTTP_Server_Plugin *plugin) { int res = GNUNET_OK; + + char *sh; + char *key_file; + char *cert_file; + + /* Get crypto init string from config + * If not present just use default values */ + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, + "PATHS", + "SERVICEHOME", + &sh)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + "Failed to get servicehome!\n"); + return GNUNET_SYSERR; + } + + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, + plugin->name, + "CRYPTO_INIT", + &plugin->crypto_init)) + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Using crypto init string `%s'\n", + plugin->crypto_init); + else + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Using default crypto init string \n"); + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, + "KEY_FILE", &key_file)) + { + GNUNET_break (0); + GNUNET_asprintf (&key_file, "%s/%s", sh, "https_key.key"); + } + + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, + "CERT_FILE", &cert_file)) + { + GNUNET_break (0); + GNUNET_asprintf (&cert_file, "%s/%s", sh, "https_cert.crt"); + } + GNUNET_free (sh); + /* read key & certificates from file */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Trying to loading TLS certificate from key-file `%s' cert-file`%s'\n", + key_file, cert_file); + + plugin->key = server_load_file (key_file); + plugin->cert = server_load_file (cert_file); + + if ((plugin->key == NULL) || (plugin->cert == NULL)) + { + struct GNUNET_OS_Process *cert_creation; + + GNUNET_free_non_null (plugin->key); + plugin->key = NULL; + GNUNET_free_non_null (plugin->cert); + plugin->cert = NULL; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No usable TLS certificate found, creating certificate\n"); + errno = 0; + cert_creation = + GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, + "gnunet-transport-certificate-creation", + "gnunet-transport-certificate-creation", + key_file, cert_file, NULL); + if (cert_creation == NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _ + ("Could not create a new TLS certificate, program `gnunet-transport-certificate-creation' could not be started!\n")); + GNUNET_free (key_file); + GNUNET_free (cert_file); + + GNUNET_free_non_null (plugin->key); + plugin->key = NULL; + GNUNET_free_non_null (plugin->cert); + plugin->cert = NULL; + GNUNET_free_non_null (plugin->crypto_init); + plugin->crypto_init = NULL; + + return GNUNET_SYSERR; + } + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (cert_creation)); + GNUNET_OS_process_destroy (cert_creation); + + plugin->key = server_load_file (key_file); + plugin->cert = server_load_file (cert_file); + } + + if ((plugin->key == NULL) || (plugin->cert == NULL)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _ + ("No usable TLS certificate found and creating one failed!\n"), + "transport-https"); + GNUNET_free (key_file); + GNUNET_free (cert_file); + + GNUNET_free_non_null (plugin->key); + plugin->key = NULL; + GNUNET_free_non_null (plugin->cert); + plugin->cert = NULL; + GNUNET_free_non_null (plugin->crypto_init); + plugin->crypto_init = NULL; + + return GNUNET_SYSERR; + } + GNUNET_free (key_file); + GNUNET_free (cert_file); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n"); + return res; +} +#endif + + +/** + * Start the HTTP server + * + * @param plugin the plugin handle + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +server_start (struct HTTP_Server_Plugin *plugin) +{ unsigned int timeout; - p = plugin; GNUNET_assert (NULL != plugin); #if BUILD_HTTPS - res = server_load_certificate (plugin); - if (res == GNUNET_SYSERR) + if (GNUNET_SYSERR == server_load_certificate (plugin)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "Could not load or create server certificate! Loading plugin failed!\n"); - return res; + return GNUNET_SYSERR; } #endif #if MHD_VERSION >= 0x00090E00 - timeout = HTTP_NOT_VALIDATED_TIMEOUT.rel_value / 1000; + timeout = HTTP_SERVER_NOT_VALIDATED_TIMEOUT.rel_value / 1000; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "MHD can set timeout per connection! Default time out %u sec.\n", timeout); #else - timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000; + timeout = SERVER_SESSION_TIMEOUT.rel_value / 1000; GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, "MHD cannot set timeout per connection! Default time out %u sec.\n", timeout); #endif plugin->server_v4 = NULL; - if (plugin->ipv4 == GNUNET_YES) + if (plugin->use_ipv4 == GNUNET_YES) { plugin->server_v4 = MHD_start_daemon ( #if VERBOSE_SERVER @@ -1107,7 +2026,7 @@ server_start (struct Plugin *plugin) server_log, NULL, MHD_OPTION_END); } plugin->server_v6 = NULL; - if (plugin->ipv6 == GNUNET_YES) + if (plugin->use_ipv6 == GNUNET_YES) { plugin->server_v6 = MHD_start_daemon ( #if VERBOSE_SERVER @@ -1145,7 +2064,7 @@ server_start (struct Plugin *plugin) } - if ((plugin->ipv4 == GNUNET_YES) && (plugin->server_v4 == NULL)) + if ((plugin->use_ipv4 == GNUNET_YES) && (plugin->server_v4 == NULL)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "Failed to start %s IPv4 server component on port %u\n", @@ -1154,7 +2073,7 @@ server_start (struct Plugin *plugin) } server_reschedule (plugin, plugin->server_v4, GNUNET_NO); - if ((plugin->ipv6 == GNUNET_YES) && (plugin->server_v6 == NULL)) + if ((plugin->use_ipv6 == GNUNET_YES) && (plugin->server_v6 == NULL)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "Failed to start %s IPv6 server component on port %u\n", @@ -1165,21 +2084,24 @@ server_start (struct Plugin *plugin) GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "%s server component started on port %u\n", plugin->name, plugin->port); - return res; + return GNUNET_OK; } + void -server_stop (struct Plugin *plugin) +server_stop (struct HTTP_Server_Plugin *plugin) { - struct Session *s = NULL; - struct Session *t = NULL; - - struct MHD_Daemon *server_v4_tmp = plugin->server_v4; - - plugin->server_v4 = NULL; - struct MHD_Daemon *server_v6_tmp = plugin->server_v6; + if (plugin->server_v4 != NULL) + { + MHD_stop_daemon (plugin->server_v4); + plugin->server_v4 = NULL; + } + if ( plugin->server_v6 != NULL) + { + MHD_stop_daemon (plugin->server_v6); + plugin->server_v6 = NULL; + } - plugin->server_v6 = NULL; if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) { @@ -1192,57 +2114,896 @@ server_stop (struct Plugin *plugin) GNUNET_SCHEDULER_cancel (plugin->server_v6_task); plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; } + 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 + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "%s server component stopped\n", plugin->name); +} + + +/** + * Add an address to the server's set of addresses and notify transport + * + * @param cls the plugin handle + * @param add_remove GNUNET_YES on add, GNUNET_NO on remove + * @param addr the address + * @param addrlen address length + */ +static void +server_add_address (void *cls, int add_remove, const struct sockaddr *addr, + socklen_t addrlen) +{ + struct HTTP_Server_Plugin *plugin = cls; + struct HttpAddressWrapper *w = NULL; - if (server_v6_tmp != NULL) + w = GNUNET_malloc (sizeof (struct HttpAddressWrapper)); + w->addr = http_common_address_from_socket (plugin->protocol, addr, addrlen); + if (NULL == w->addr) { - MHD_stop_daemon (server_v4_tmp); + GNUNET_free (w); + return; } - if (server_v6_tmp != NULL) + w->addrlen = http_common_address_get_size (w->addr); + + GNUNET_CONTAINER_DLL_insert(plugin->addr_head, plugin->addr_tail, w); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Notifying transport to add address `%s'\n", + http_common_plugin_address_to_string(NULL, w->addr, w->addrlen)); +#if BUILD_HTTPS + plugin->env->notify_address (plugin->env->cls, add_remove, w->addr, w->addrlen, "https_client"); +#else + plugin->env->notify_address (plugin->env->cls, add_remove, w->addr, w->addrlen, "http_client"); +#endif +} + + +/** + * Remove an address from the server's set of addresses and notify transport + * + * @param cls the plugin handle + * @param add_remove GNUNET_YES on add, GNUNET_NO on remove + * @param addr the address + * @param addrlen address length + */ +static void +server_remove_address (void *cls, int add_remove, const struct sockaddr *addr, + socklen_t addrlen) +{ + struct HTTP_Server_Plugin *plugin = cls; + struct HttpAddressWrapper *w = plugin->addr_head; + size_t saddr_len; + void * saddr = http_common_address_from_socket (plugin->protocol, addr, addrlen); + if (NULL == saddr) + return; + saddr_len = http_common_address_get_size (saddr); + + while (NULL != w) { - MHD_stop_daemon (server_v6_tmp); + if (GNUNET_YES == http_common_cmp_addresses(w->addr, w->addrlen, saddr, saddr_len)) + break; + w = w->next; } + GNUNET_free (saddr); - /* cleaning up semi-sessions never propagated */ - s = plugin->server_semi_head; - while (s != NULL) + if (NULL == w) + return; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Notifying transport to remove address `%s'\n", + http_common_plugin_address_to_string (NULL, w->addr, w->addrlen)); + GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w); +#if BUILD_HTTPS + plugin->env->notify_address (plugin->env->cls, add_remove, w->addr, w->addrlen, "https_client"); +#else + plugin->env->notify_address (plugin->env->cls, add_remove, w->addr, w->addrlen, "http_client"); +#endif + GNUNET_free (w->addr); + GNUNET_free (w); +} + + + +/** + * Our external IP address/port mapping has changed. + * + * @param cls closure, the 'struct LocalAddrList' + * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean + * the previous (now invalid) one + * @param addr either the previous or the new public IP address + * @param addrlen actual lenght of the address + */ +static void +server_nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr, + socklen_t addrlen) +{ + GNUNET_assert (cls != NULL); + struct HTTP_Server_Plugin *plugin = cls; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "NAT called to %s address `%s'\n", + (add_remove == GNUNET_NO) ? "remove" : "add", + GNUNET_a2s (addr, addrlen)); + + if (AF_INET == addr->sa_family) + { + struct sockaddr_in *s4 = (struct sockaddr_in *) addr; + + if (GNUNET_NO == plugin->use_ipv4) + return; + + if ((NULL != plugin->server_addr_v4) && + (0 != memcmp (&plugin->server_addr_v4->sin_addr, + &s4->sin_addr, sizeof (struct in_addr)))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Skipping address `%s' (not bindto address)\n", + GNUNET_a2s (addr, addrlen)); + return; + } + } + + if (AF_INET6 == addr->sa_family) + { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) addr; + if (GNUNET_NO == plugin->use_ipv6) + return; + + if ((NULL != plugin->server_addr_v6) && + (0 != memcmp (&plugin->server_addr_v6->sin6_addr, + &s6->sin6_addr, sizeof (struct in6_addr)))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Skipping address `%s' (not bindto address)\n", + GNUNET_a2s (addr, addrlen)); + return; + } + } + + switch (add_remove) + { + case GNUNET_YES: + server_add_address (cls, add_remove, addr, addrlen); + break; + case GNUNET_NO: + server_remove_address (cls, add_remove, addr, addrlen); + break; + } +} + + +/** + * Get valid server addresses + * + * @param plugin the plugin handle + * @param serviceName the servicename + * @param cfg configuration handle + * @param addrs addresses + * @param addr_lens address length + * @return number of addresses + */ +static int +server_get_addresses (struct HTTP_Server_Plugin *plugin, + const char *serviceName, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct sockaddr ***addrs, socklen_t ** addr_lens) +{ + int disablev6; + unsigned long long port; + struct addrinfo hints; + struct addrinfo *res; + struct addrinfo *pos; + struct addrinfo *next; + unsigned int i; + int resi; + int ret; + struct sockaddr **saddrs; + socklen_t *saddrlens; + char *hostname; + + *addrs = NULL; + *addr_lens = NULL; + + disablev6 = !plugin->use_ipv6; + + port = 0; + if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT")) + { + GNUNET_break (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (cfg, serviceName, + "PORT", &port)); + if (port > 65535) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _ + ("Require valid port number for service in configuration!\n")); + return GNUNET_SYSERR; + } + } + if (0 == port) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, plugin->name, + "Starting in listen only mode\n"); + return -1; /* listen only */ + } + + + if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO")) + { + GNUNET_break (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, + "BINDTO", &hostname)); + } + else + hostname = NULL; + + if (hostname != NULL) { -#if VERBOSE_SERVER GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Deleting semi-sessions %p\n", s); + "Resolving `%s' since that is where `%s' will bind to.\n", + hostname, serviceName); + memset (&hints, 0, sizeof (struct addrinfo)); + if (disablev6) + hints.ai_family = AF_INET; + if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || + (res == NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"), + hostname, gai_strerror (ret)); + GNUNET_free (hostname); + return GNUNET_SYSERR; + } + next = res; + i = 0; + while (NULL != (pos = next)) + { + next = pos->ai_next; + if ((disablev6) && (pos->ai_family == AF_INET6)) + continue; + i++; + } + if (0 == i) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to find %saddress for `%s'.\n"), + disablev6 ? "IPv4 " : "", hostname); + freeaddrinfo (res); + GNUNET_free (hostname); + return GNUNET_SYSERR; + } + resi = i; + saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); + saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); + i = 0; + next = res; + while (NULL != (pos = next)) + { + next = pos->ai_next; + if ((disablev6) && (pos->ai_family == AF_INET6)) + continue; + if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0)) + continue; /* not TCP */ + if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0)) + continue; /* huh? */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Service will bind to `%s'\n", GNUNET_a2s (pos->ai_addr, + pos->ai_addrlen)); + if (pos->ai_family == AF_INET) + { + GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in)); + saddrlens[i] = pos->ai_addrlen; + saddrs[i] = GNUNET_malloc (saddrlens[i]); + memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); + ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); + } + else + { + GNUNET_assert (pos->ai_family == AF_INET6); + GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6)); + saddrlens[i] = pos->ai_addrlen; + saddrs[i] = GNUNET_malloc (saddrlens[i]); + memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); + ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); + } + i++; + } + GNUNET_free (hostname); + freeaddrinfo (res); + resi = i; + } + else + { + /* will bind against everything, just set port */ + if (disablev6) + { + /* V4-only */ + resi = 1; + i = 0; + saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); + saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); + + saddrlens[i] = sizeof (struct sockaddr_in); + saddrs[i] = GNUNET_malloc (saddrlens[i]); +#if HAVE_SOCKADDR_IN_SIN_LEN + ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; +#endif + ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; + ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); + } + else + { + /* dual stack */ + resi = 2; + saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); + saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); + i = 0; + saddrlens[i] = sizeof (struct sockaddr_in6); + saddrs[i] = GNUNET_malloc (saddrlens[i]); +#if HAVE_SOCKADDR_IN_SIN_LEN + ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; #endif - t = s->next; - struct HTTP_Message *msg = s->msg_head; - struct HTTP_Message *tmp = NULL; + ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; + ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); + i++; + saddrlens[i] = sizeof (struct sockaddr_in); + saddrs[i] = GNUNET_malloc (saddrlens[i]); +#if HAVE_SOCKADDR_IN_SIN_LEN + ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; +#endif + ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; + ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); + } + } + *addrs = saddrs; + *addr_lens = saddrlens; + return resi; +} + - while (msg != NULL) +/** + * Ask NAT for addresses + * + * @param plugin the plugin handle + */ +static void +server_start_report_addresses (struct HTTP_Server_Plugin *plugin) +{ + int res = GNUNET_OK; + struct sockaddr **addrs; + socklen_t *addrlens; + + res = server_get_addresses (plugin, + plugin->name, plugin->env->cfg, + &addrs, &addrlens); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Found %u addresses to report to NAT service\n"), res); + + if (GNUNET_SYSERR == res) + { + plugin->nat = NULL; + return; + } + + plugin->nat = + GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, plugin->port, + (unsigned int) res, + (const struct sockaddr **) addrs, addrlens, + &server_nat_port_map_callback, NULL, plugin); + while (res > 0) + { + res--; + GNUNET_assert (addrs[res] != NULL); + GNUNET_free (addrs[res]); + } + GNUNET_free_non_null (addrs); + GNUNET_free_non_null (addrlens); +} + + +/** + * Stop NAT for addresses + * + * @param plugin the plugin handle + */ +static void +server_stop_report_addresses (struct HTTP_Server_Plugin *plugin) +{ + /* Stop NAT handle */ + if (NULL != plugin->nat) + GNUNET_NAT_unregister (plugin->nat); + + /* Clean up addresses */ + struct HttpAddressWrapper *w; + + while (plugin->addr_head != NULL) + { + w = plugin->addr_head; + GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w); + GNUNET_free (w->addr); + GNUNET_free (w); + } +} + + +/** + * Check if IPv6 supported on this system + * + * @param plugin the plugin handle + * @return GNUNET_YES on success, else GNUNET_NO + */ +static int +server_check_ipv6_support (struct HTTP_Server_Plugin *plugin) +{ + struct GNUNET_NETWORK_Handle *desc = NULL; + int res = GNUNET_NO; + + /* Probe IPv6 support */ + desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); + if (NULL == desc) + { + if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || + (errno == EACCES)) { - tmp = msg->next; + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); + } + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, + _ + ("Disabling IPv6 since it is not supported on this system!\n")); + res = GNUNET_NO; + } + else + { + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); + desc = NULL; + res = GNUNET_YES; + } + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Testing IPv6 on this system: %s\n", + (res == GNUNET_YES) ? "successful" : "failed"); + return res; +} - GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); - if (msg->transmit_cont != NULL) + +/** + * Function called when the service shuts down. Unloads our plugins + * and cancels pending validations. + * + * @param cls closure, unused + * @param tc task context (unused) + */ +static void +server_notify_external_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct HTTP_Server_Plugin *plugin = cls; + + plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK; + + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + GNUNET_asprintf(&plugin->ext_addr, "%s://%s", plugin->protocol, plugin->external_hostname); + plugin->ext_addr_len = strlen (plugin->ext_addr) + 1; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Notifying transport about external hostname address `%s'\n", plugin->ext_addr); + +#if BUILD_HTTPS + plugin->env->notify_address (plugin->env->cls, GNUNET_YES, + plugin->ext_addr, plugin->ext_addr_len, + "https_client"); +#else + plugin->env->notify_address (plugin->env->cls, GNUNET_YES, + plugin->ext_addr, plugin->ext_addr_len, + "http_client"); +#endif +} + + +/** + * Configure the plugin + * + * @param plugin plugin handle + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +server_configure_plugin (struct HTTP_Server_Plugin *plugin) +{ + unsigned long long port; + unsigned long long max_connections; + char *bind4_address = NULL; + char *bind6_address = NULL; + + /* Use IPv4? */ + if (GNUNET_CONFIGURATION_have_value + (plugin->env->cfg, plugin->name, "USE_IPv4")) + { + plugin->use_ipv4 = + GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, + "USE_IPv4"); + } + else + plugin->use_ipv4 = GNUNET_YES; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("IPv4 support is %s\n"), + (plugin->use_ipv4 == GNUNET_YES) ? "enabled" : "disabled"); + + /* Use IPv6? */ + if (GNUNET_CONFIGURATION_have_value + (plugin->env->cfg, plugin->name, "USE_IPv6")) + { + plugin->use_ipv6 = + GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, + "USE_IPv6"); + } + else + plugin->use_ipv6 = GNUNET_YES; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("IPv6 support is %s\n"), + (plugin->use_ipv6 == GNUNET_YES) ? "enabled" : "disabled"); + + if ((plugin->use_ipv4 == GNUNET_NO) && (plugin->use_ipv6 == GNUNET_NO)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _ + ("Neither IPv4 nor IPv6 are enabled! Fix in configuration\n"), + plugin->name); + return GNUNET_SYSERR; + } + + /* Reading port number from config file */ + if ((GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, + "PORT", &port)) || (port > 65535)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _("Port is required! Fix in configuration\n"), + plugin->name); + return GNUNET_SYSERR; + } + plugin->port = port; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Using port %u\n"), plugin->port); + + if ((plugin->use_ipv4 == GNUNET_YES) && + (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, + plugin->name, "BINDTO", &bind4_address))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Binding %s plugin to specific IPv4 address: `%s'\n", + plugin->protocol, bind4_address); + plugin->server_addr_v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); + if (1 != inet_pton (AF_INET, bind4_address, + &plugin->server_addr_v4->sin_addr)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _ + ("Specific IPv4 address `%s' in configuration file is invalid!\n"), + bind4_address); + GNUNET_free (bind4_address); + GNUNET_free (plugin->server_addr_v4); + plugin->server_addr_v4 = NULL; + return GNUNET_SYSERR; + } + else + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Binding to IPv4 address %s\n"), bind4_address); + plugin->server_addr_v4->sin_family = AF_INET; + plugin->server_addr_v4->sin_port = htons (plugin->port); + } + GNUNET_free (bind4_address); + } + + if ((plugin->use_ipv6 == GNUNET_YES) && + (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, + "BINDTO6", &bind6_address))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Binding %s plugin to specific IPv6 address: `%s'\n", + plugin->protocol, bind6_address); + plugin->server_addr_v6 = GNUNET_malloc (sizeof (struct sockaddr_in6)); + if (1 != + inet_pton (AF_INET6, bind6_address, &plugin->server_addr_v6->sin6_addr)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + _ + ("Specific IPv6 address `%s' in configuration file is invalid!\n"), + bind6_address); + GNUNET_free (bind6_address); + GNUNET_free (plugin->server_addr_v6); + plugin->server_addr_v6 = NULL; + return GNUNET_SYSERR; + } + else + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Binding to IPv6 address %s\n"), bind6_address); + plugin->server_addr_v6->sin6_family = AF_INET6; + plugin->server_addr_v6->sin6_port = htons (plugin->port); + } + GNUNET_free (bind6_address); + } + + if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, + "EXTERNAL_HOSTNAME", &plugin->external_hostname)) + { + char * tmp = NULL; + if (NULL != strstr(plugin->external_hostname, "://")) { - msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); + tmp = strdup(&strstr(plugin->external_hostname, "://")[3]); + GNUNET_free (plugin->external_hostname); + plugin->external_hostname = tmp; + } - GNUNET_free (msg); - msg = tmp; - } + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Using external hostname `%s'\n"), plugin->external_hostname); + plugin->notify_ext_task = GNUNET_SCHEDULER_add_now (&server_notify_external_hostname, plugin); - delete_session (s); - s = t; + /* Use only configured external hostname */ + if (GNUNET_CONFIGURATION_have_value + (plugin->env->cfg, plugin->name, "EXTERNAL_HOSTNAME_ONLY")) + { + plugin->external_only = + GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, + "EXTERNAL_HOSTNAME_ONLY"); + } + else + plugin->external_only = GNUNET_NO; + + if (GNUNET_YES == plugin->external_only) + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Notifying transport only about hostname `%s'\n"), plugin->external_hostname); } + else + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "No external hostname configured\n"); - p = NULL; + /* Optional parameters */ + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, + plugin->name, + "MAX_CONNECTIONS", &max_connections)) + max_connections = 128; + plugin->max_connections = max_connections; + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Maximum number of connections is %u\n"), + plugin->max_connections); + + + plugin->peer_id_length = strlen (GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey)); + + return GNUNET_OK; +} + + +/** + * Session was idle, so disconnect it + * + * @param cls the session + * @param tc task context + */ +static void +server_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 (TIMEOUT_LOG, + "Session %p was idle for %llu ms, disconnecting\n", + s, (unsigned long long) SERVER_SESSION_TIMEOUT.rel_value); + + /* call session destroy function */ + GNUNET_assert (GNUNET_OK == server_disconnect (s)); +} + +/** +* Start session timeout for session s +* +* @param s the session +*/ +static void +server_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 (SERVER_SESSION_TIMEOUT, + &server_session_timeout, + s); + GNUNET_log (TIMEOUT_LOG, + "Timeout for session %p set to %llu ms\n", + s, (unsigned long long) SERVER_SESSION_TIMEOUT.rel_value); +} + + +/** +* Increment session timeout due to activity session s +* +* @param s the session +*/ +static void +server_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 (SERVER_SESSION_TIMEOUT, + &server_session_timeout, + s); + GNUNET_log (TIMEOUT_LOG, + "Timeout rescheduled for session %p set to %llu ms\n", + s, (unsigned long long) SERVER_SESSION_TIMEOUT.rel_value); +} + + +/** + * Exit point from the plugin. + * + * @param cls api + * @return NULL + */ +void * +LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) +{ + struct GNUNET_TRANSPORT_PluginFunctions *api = cls; + struct HTTP_Server_Plugin *plugin = api->cls; + struct Session *pos; + struct Session *next; + + if (NULL == api->cls) + { + /* Free for stub mode */ + GNUNET_free (api); + return NULL; + } + plugin->in_shutdown = GNUNET_YES; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + _("Shutting down plugin `%s'\n"), + plugin->name); + + if (GNUNET_SCHEDULER_NO_TASK != plugin->notify_ext_task) + { + GNUNET_SCHEDULER_cancel (plugin->notify_ext_task); + plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (NULL != plugin->ext_addr) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Notifying transport to remove address `%s'\n", + http_common_plugin_address_to_string (NULL, + plugin->ext_addr, + plugin->ext_addr_len)); #if BUILD_HTTPS - GNUNET_free_non_null (plugin->crypto_init); - GNUNET_free_non_null (plugin->cert); - GNUNET_free_non_null (plugin->key); + plugin->env->notify_address (plugin->env->cls, + GNUNET_NO, + plugin->ext_addr, + plugin->ext_addr_len, + "https_client"); +#else + plugin->env->notify_address (plugin->env->cls, + GNUNET_NO, + plugin->ext_addr, + plugin->ext_addr_len, + "http_client"); #endif + } + + /* Stop to report addresses to transport service */ + server_stop_report_addresses (plugin); + server_stop (plugin); + next = plugin->head; + while (NULL != (pos = next)) + { + next = pos->next; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Removing left over session %p\n", pos); + + if ((GNUNET_YES == pos->session_passed) && (GNUNET_NO == pos->session_ended)) + { + /* Notify transport immediately that this session is invalid */ + pos->session_ended = GNUNET_YES; + plugin->env->session_end (plugin->env->cls, &pos->target, pos); + } + + server_delete_session (pos); + } + + /* Clean up */ + GNUNET_free_non_null (plugin->external_hostname); + GNUNET_free_non_null (plugin->ext_addr); + GNUNET_free_non_null (plugin->server_addr_v4); + GNUNET_free_non_null (plugin->server_addr_v6); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "%s server component stopped\n", plugin->name); + _("Shutdown for plugin `%s' complete\n"), + plugin->name); + + GNUNET_free (plugin); + GNUNET_free (api); + return NULL; } +/** + * Entry point for the plugin. + * + * @param cls env + * @return api + */ +void * +LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) +{ + struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; + struct GNUNET_TRANSPORT_PluginFunctions *api; + struct HTTP_Server_Plugin *plugin; + + plugin = GNUNET_malloc (sizeof (struct HTTP_Server_Plugin)); + plugin->env = env; + p = plugin; + + 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_to_string = &http_common_plugin_address_to_string; + api->string_to_address = &http_common_plugin_string_to_address; + api->address_pretty_printer = &http_common_plugin_address_pretty_printer; + return api; + } + + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = plugin; + api->send = &http_server_plugin_send; + api->disconnect = &http_server_plugin_disconnect; + api->check_address = &http_server_plugin_address_suggested; + api->get_session = &http_server_plugin_get_session; + + api->address_to_string = &http_common_plugin_address_to_string; + api->string_to_address = &http_common_plugin_string_to_address; + api->address_pretty_printer = &http_common_plugin_address_pretty_printer; + +#if BUILD_HTTPS + plugin->name = "transport-https_server"; + plugin->protocol = "https"; +#else + plugin->name = "transport-http_server"; + plugin->protocol = "http"; +#endif + + /* Configure plugin */ + if (GNUNET_SYSERR == server_configure_plugin (plugin)) + { + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); + return NULL; + } + + /* Check IPv6 support */ + if (GNUNET_YES == plugin->use_ipv6) + plugin->use_ipv6 = server_check_ipv6_support (plugin); + + /* Report addresses to transport service */ + if (GNUNET_NO == plugin->external_only) + server_start_report_addresses (plugin); + + if (GNUNET_SYSERR == server_start (plugin)) + { + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); + return NULL; + } + + return api; +} -/* end of plugin_transport_http.c */ +/* end of plugin_transport_http_server.c */ diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index af5c715..07abc46 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -223,6 +223,11 @@ struct PendingMessage */ struct Session { + /** + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) + */ + struct GNUNET_PeerIdentity target; /** * API requirement. @@ -262,12 +267,6 @@ struct Session struct GNUNET_SERVER_TransmitHandle *transmit_handle; /** - * To whom are we talking to (set to our identity - * if we are still waiting for the welcome message) - */ - struct GNUNET_PeerIdentity target; - - /** * ID of task used to delay receiving more to throttle sender. */ GNUNET_SCHEDULER_TaskIdentifier receive_delay_task; @@ -386,6 +385,11 @@ struct Plugin unsigned long long max_connections; /** + * How many more TCP sessions do we have right now? + */ + unsigned long long cur_connections; + + /** * ID of task used to update our addresses when one expires. */ GNUNET_SCHEDULER_TaskIdentifier address_update_task; @@ -487,12 +491,12 @@ plugin_tcp_access_check (void *cls, const struct sockaddr *addr, socklen_t addrlen) { struct Plugin *plugin = cls; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Accepting new incoming TCP connection\n"); - if (0 == plugin->max_connections) + "Accepting new incoming TCP connection from `%s'\n", + GNUNET_a2s (addr, addrlen)); + if (plugin->cur_connections >= plugin->max_connections) return GNUNET_NO; - plugin->max_connections--; + plugin->cur_connections ++; return GNUNET_YES; } @@ -542,7 +546,7 @@ tcp_nat_port_map_callback (void *cls, int add_remove, return; } /* modify our published address list */ - plugin->env->notify_address (plugin->env->cls, add_remove, arg, args); + plugin->env->notify_address (plugin->env->cls, add_remove, arg, args, "tcp"); } @@ -684,7 +688,7 @@ struct SessionClientCtx static int session_lookup_by_client_it (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, void *value) { struct SessionClientCtx *sc_ctx = cls; @@ -734,7 +738,7 @@ static struct Session * create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, struct GNUNET_SERVER_Client *client, int is_nat) { - struct Session *ret; + struct Session *session; struct PendingMessage *pm; struct WelcomeMessage welcome; @@ -746,14 +750,14 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, 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; - ret->is_nat = is_nat; - ret->client = client; - ret->target = *target; - ret->expecting_welcome = GNUNET_YES; - ret->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); + session = GNUNET_malloc (sizeof (struct Session)); + session->last_activity = GNUNET_TIME_absolute_get (); + session->plugin = plugin; + session->is_nat = is_nat; + session->client = client; + session->target = *target; + session->expecting_welcome = GNUNET_YES; + session->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage)); pm->msg = (const char *) &pm[1]; @@ -766,17 +770,17 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# bytes currently in TCP buffers"), pm->message_size, GNUNET_NO); - GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head, - ret->pending_messages_tail, pm); + GNUNET_CONTAINER_DLL_insert (session->pending_messages_head, + session->pending_messages_tail, pm); if (GNUNET_YES != is_nat) { GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# TCP sessions active"), 1, GNUNET_NO); } - start_session_timeout (ret); + start_session_timeout (session); - return ret; + return session; } @@ -849,7 +853,7 @@ do_transmit (void *cls, size_t size, void *buf) { GNUNET_CONTAINER_DLL_remove (hd, tl, pos); if (pos->transmit_cont != NULL) - pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_SYSERR); + pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_SYSERR, pos->message_size, 0); GNUNET_free (pos); } GNUNET_STATISTICS_update (plugin->env->stats, @@ -895,7 +899,7 @@ do_transmit (void *cls, size_t size, void *buf) { GNUNET_CONTAINER_DLL_remove (hd, tl, pos); if (pos->transmit_cont != NULL) - pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_OK); + pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_OK, pos->message_size, pos->message_size); /* FIXME: include TCP overhead */ GNUNET_free (pos); } GNUNET_assert (hd == NULL); @@ -999,7 +1003,7 @@ disconnect_session (struct Session *session) session->pending_messages_tail, pm); if (NULL != pm->transmit_cont) pm->transmit_cont (pm->transmit_cont_cls, &session->target, - GNUNET_SYSERR); + GNUNET_SYSERR, pm->message_size, 0); GNUNET_free (pm); } if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) @@ -1020,6 +1024,48 @@ disconnect_session (struct Session *session) } +struct FindSessionContext +{ + struct Session *s; + int res; +}; + +int session_it (void *cls, + const struct GNUNET_HashCode * key, + void *value) +{ + struct FindSessionContext *res = cls; + if (res->s == value) + { + res->res = GNUNET_OK; + return GNUNET_NO; + } + else + return GNUNET_YES; +} + +int find_session (struct Plugin *plugin, struct Session *session) +{ + struct FindSessionContext session_map_res; + struct FindSessionContext nat_map_res; + + session_map_res.s = session; + session_map_res.res = GNUNET_SYSERR; + GNUNET_CONTAINER_multihashmap_iterate (plugin->sessionmap, &session_it, &session_map_res); + + nat_map_res.s = session; + nat_map_res.res = GNUNET_SYSERR; + GNUNET_CONTAINER_multihashmap_iterate (plugin->nat_wait_conns, &session_it, &nat_map_res); + + if ((session_map_res.res == GNUNET_SYSERR) && (nat_map_res.res == GNUNET_SYSERR)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + /** * Function that can be used by the transport service to transmit * a message using the plugin. Note that in the case of a @@ -1061,6 +1107,13 @@ tcp_plugin_send (void *cls, GNUNET_assert (NULL != plugin); GNUNET_assert (NULL != session); + if (GNUNET_SYSERR == find_session(plugin, session)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Trying to send with invalid session %p\n")); + return GNUNET_SYSERR; + } + /* create new message entry */ pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); pm->msg = (const char *) &pm[1]; @@ -1074,12 +1127,12 @@ tcp_plugin_send (void *cls, "Asked to transmit %u bytes to `%s', added message to list.\n", msgbuf_size, GNUNET_i2s (&session->target)); - reschedule_session_timeout (session); - - if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessionmap, &session->target.hashPubKey, session)) + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value (plugin->sessionmap, + &session->target.hashPubKey, + session)) { GNUNET_assert (session->client != NULL); - + reschedule_session_timeout (session); GNUNET_SERVER_client_set_timeout (session->client, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); GNUNET_STATISTICS_update (plugin->env->stats, @@ -1098,7 +1151,7 @@ tcp_plugin_send (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, "This NAT WAIT session for peer `%s' is not yet ready!\n", GNUNET_i2s (&session->target)); - + reschedule_session_timeout (session); GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# bytes currently in TCP buffers"), msgbuf_size, GNUNET_NO); @@ -1110,8 +1163,10 @@ tcp_plugin_send (void *cls, } else { + LOG (GNUNET_ERROR_TYPE_ERROR, + "Invalid session %p\n", session); if (NULL != cont) - cont (cont_cls, &session->target, GNUNET_SYSERR); + cont (cont_cls, &session->target, GNUNET_SYSERR, pm->message_size, 0); GNUNET_break (0); GNUNET_free (pm); return GNUNET_SYSERR; /* session does not exist here */ @@ -1129,7 +1184,7 @@ struct SessionItCtx static int session_lookup_it (void *cls, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, void *value) { struct SessionItCtx * si_ctx = cls; @@ -1180,6 +1235,7 @@ nat_connect_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Session *session = cls; + session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; 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)); @@ -1200,8 +1256,8 @@ static struct Session * tcp_plugin_get_session (void *cls, const struct GNUNET_HELLO_Address *address) { - struct Plugin * plugin = cls; - struct Session * session = NULL; + struct Plugin *plugin = cls; + struct Session *session = NULL; int af; const void *sb; size_t sbs; @@ -1224,7 +1280,8 @@ tcp_plugin_get_session (void *cls, /* look for existing session */ if (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, &address->peer.hashPubKey)) + GNUNET_CONTAINER_multihashmap_contains (plugin->sessionmap, + &address->peer.hashPubKey)) { struct SessionItCtx si_ctx; @@ -1233,7 +1290,9 @@ tcp_plugin_get_session (void *cls, si_ctx.result = NULL; - GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, &address->peer.hashPubKey, &session_lookup_it, &si_ctx); + GNUNET_CONTAINER_multihashmap_get_multiple (plugin->sessionmap, + &address->peer.hashPubKey, + &session_lookup_it, &si_ctx); if (si_ctx.result != NULL) { session = si_ctx.result; @@ -1300,7 +1359,7 @@ tcp_plugin_get_session (void *cls, return NULL; } - if (0 == plugin->max_connections) + if (plugin->cur_connections >= plugin->max_connections) { /* saturated */ return NULL; @@ -1326,13 +1385,15 @@ tcp_plugin_get_session (void *cls, 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); + 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); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put (plugin->nat_wait_conns, + &session->target.hashPubKey, + session, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Created NAT WAIT connection to `%4s' at `%s'\n", @@ -1351,16 +1412,18 @@ tcp_plugin_get_session (void *cls, } /* create new outbound session */ - GNUNET_assert (0 != plugin->max_connections); + GNUNET_assert (plugin->cur_connections <= plugin->max_connections); sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); if (sa == NULL) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to create connection to `%4s' at `%s'\n", - GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); + GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); return NULL; } - plugin->max_connections--; + plugin->cur_connections++; + if (plugin->cur_connections == plugin->max_connections) + GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", @@ -1375,9 +1438,11 @@ tcp_plugin_get_session (void *cls, session->addrlen = addrlen; session->ats_address_network_type = ats.value; - GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &address->peer.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_CONTAINER_multihashmap_put (plugin->sessionmap, + &session->target.hashPubKey, + session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); inc_sessions (plugin, session, __LINE__); - LOG (GNUNET_ERROR_TYPE_DEBUG, + 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), @@ -1391,7 +1456,7 @@ tcp_plugin_get_session (void *cls, static int session_disconnect_it (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, void *value) { struct Session *session = value; @@ -1661,7 +1726,7 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, const struct sockaddr_in *s4; const struct sockaddr_in6 *s6; - LOG (GNUNET_ERROR_TYPE_DEBUG, "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 @@ -1717,9 +1782,9 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, (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); + 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; LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -1816,6 +1881,11 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, else { GNUNET_SERVER_client_keep (client); + if (plugin->service != NULL) /* Otherwise value is incremented in tcp_access_check */ + plugin->cur_connections++; + if (plugin->cur_connections == plugin->max_connections) + GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */ + session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO); session->inbound = GNUNET_YES; if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) @@ -1850,7 +1920,10 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, 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); + GNUNET_CONTAINER_multihashmap_put (plugin->sessionmap, + &session->target.hashPubKey, + session, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); inc_sessions (plugin, session, __LINE__); } @@ -1988,7 +2061,7 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, &session->target, message, (const struct GNUNET_ATS_Information *) &distance, - 1, session, + 2, session, (GNUNET_YES == session->inbound) ? NULL : session->addr, (GNUNET_YES == session->inbound) ? 0 : session->addrlen); @@ -2026,11 +2099,10 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) if (client == NULL) return; - plugin->max_connections++; session = lookup_session_by_client (plugin, client); if (session == NULL) return; /* unknown, nothing to do */ - LOG (GNUNET_ERROR_TYPE_DEBUG, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying session of `%4s' with %s due to network-level disconnect.\n", GNUNET_i2s (&session->target), (session->addr != @@ -2038,6 +2110,15 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) session->addr, session->addrlen) : "*"); + + if (plugin->cur_connections == plugin->max_connections) + GNUNET_SERVER_resume (plugin->server); /* Resume server */ + + if (plugin->cur_connections < 1) + GNUNET_break (0); + else + plugin->cur_connections--; + GNUNET_STATISTICS_update (session->plugin->env->stats, gettext_noop ("# network-level TCP disconnect events"), 1, @@ -2143,8 +2224,8 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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); + "Session %p was idle for %llu ms, disconnecting\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); /* call session destroy function */ disconnect_session(s); } @@ -2161,10 +2242,9 @@ start_session_timeout (struct Session *s) 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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for session %p set to %llu ms\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } @@ -2175,21 +2255,15 @@ 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_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, - (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout rescheduled for session %p set to %llu ms\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } @@ -2200,19 +2274,14 @@ 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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout stopped for session %p canceled\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } } @@ -2259,6 +2328,8 @@ libgnunet_plugin_transport_tcp_init (void *cls) return api; } + GNUNET_assert (NULL != env->cfg); + GNUNET_assert (NULL != env->stats); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", "MAX_CONNECTIONS", @@ -2298,8 +2369,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) service = NULL; plugin = GNUNET_malloc (sizeof (struct Plugin)); - plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create(max_connections); + plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create (max_connections, GNUNET_YES); plugin->max_connections = max_connections; + plugin->cur_connections = 0; plugin->open_port = bport; plugin->adv_port = aport; plugin->env = env; @@ -2326,8 +2398,8 @@ libgnunet_plugin_transport_tcp_init (void *cls) } else { - plugin->nat = - GNUNET_NAT_register (env->cfg, GNUNET_YES, 0, 0, NULL, NULL, NULL, + plugin->nat = GNUNET_NAT_register (plugin->env->cfg, + GNUNET_YES, 0, 0, NULL, NULL, NULL, &try_connection_reversal, plugin); } api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); @@ -2351,9 +2423,8 @@ libgnunet_plugin_transport_tcp_init (void *cls) GNUNET_CONFIGURATION_get_value_time (env->cfg, "transport-tcp", "TIMEOUT", &idle_timeout)) { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Failed to find option %s in section %s!\n"), - "TIMEOUT", "transport-tcp"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "transport-tcp", "TIMEOUT"); if (plugin->nat != NULL) GNUNET_NAT_unregister (plugin->nat); GNUNET_free (plugin); @@ -2370,9 +2441,10 @@ libgnunet_plugin_transport_tcp_init (void *cls) i < sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler); i++) plugin->handlers[i].callback_cls = plugin; + GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin); - plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16); + plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); if (bport != 0) LOG (GNUNET_ERROR_TYPE_INFO, _("TCP transport listening on port %llu\n"), bport); diff --git a/src/transport/plugin_transport_template.c b/src/transport/plugin_transport_template.c index d307262..8c15f87 100644 --- a/src/transport/plugin_transport_template.c +++ b/src/transport/plugin_transport_template.c @@ -54,6 +54,11 @@ struct Plugin; */ struct Session { + /** + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) + */ + struct GNUNET_PeerIdentity sender; /** * Stored in a linked list. @@ -83,12 +88,6 @@ struct Session void *transmit_cont_cls; /** - * To whom are we talking to (set to our identity - * if we are still waiting for the welcome message) - */ - struct GNUNET_PeerIdentity sender; - - /** * At what time did we reset last_received last? */ struct GNUNET_TIME_Absolute last_quota_update; @@ -257,7 +256,43 @@ template_plugin_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 +template_plugin_string_to_address (void *cls, const char *addr, uint16_t addrlen, + void **buf, size_t *added) +{ + GNUNET_break (0); + return GNUNET_SYSERR; +} + +/** + * Create a new session to transmit data to the target + * This session will used to send data to this peer and the plugin will + * notify us by calling the env->session_end function + * + * @param cls closure + * @param address pointer to the GNUNET_HELLO_Address + * @return the session if the address is valid, NULL otherwise + */ +static struct Session * +template_plugin_get_session (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + GNUNET_break (0); + return NULL; +} /** * Entry point for the plugin. @@ -269,6 +304,18 @@ gnunet_plugin_transport_template_init (void *cls) struct GNUNET_TRANSPORT_PluginFunctions *api; struct Plugin *plugin; + 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_to_string = &template_plugin_address_to_string; + api->string_to_address = &template_plugin_string_to_address; + api->address_pretty_printer = &template_plugin_address_pretty_printer; + return api; + } + plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); @@ -278,6 +325,9 @@ gnunet_plugin_transport_template_init (void *cls) api->address_pretty_printer = &template_plugin_address_pretty_printer; api->check_address = &template_plugin_address_suggested; api->address_to_string = &template_plugin_address_to_string; + api->string_to_address = &template_plugin_string_to_address; + api->get_session = &template_plugin_get_session; + return api; } diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index c5a4c7b..c57ec98 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -63,6 +63,7 @@ #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128 +#define DEBUG_MALLOC GNUNET_NO /** * Closure for 'append_port'. @@ -86,6 +87,16 @@ struct PrettyPrinterContext }; +enum UDP_MessageType +{ + UNDEFINED = 0, + MSG_FRAGMENTED = 1, + MSG_FRAGMENTED_COMPLETE = 2, + MSG_UNFRAGMENTED = 3, + MSG_ACK = 4, + MSG_BEACON = 5 +}; + struct Session { /** @@ -93,7 +104,7 @@ struct Session */ struct GNUNET_PeerIdentity target; - struct FragmentationContext * frag_ctx; + struct UDP_FragmentationContext * frag_ctx; /** * Address of the other peer @@ -118,7 +129,12 @@ struct Session /** * expected delay for ACKs */ - struct GNUNET_TIME_Relative last_expected_delay; + struct GNUNET_TIME_Relative last_expected_ack_delay; + + /** + * desired delay between UDP messages + */ + struct GNUNET_TIME_Relative last_expected_msg_delay; struct GNUNET_ATS_Information ats; @@ -225,15 +241,33 @@ struct DefragContext /** - * Closure for 'process_inbound_tokenized_messages' + * Context to send fragmented messages */ -struct FragmentationContext +struct UDP_FragmentationContext { - struct FragmentationContext * next; - struct FragmentationContext * prev; + /** + * Next in linked list + */ + struct UDP_FragmentationContext * next; + /** + * Previous in linked list + */ + struct UDP_FragmentationContext * prev; + + /** + * The plugin + */ struct Plugin * plugin; + + /** + * Handle for GNUNET_FRAGMENT context + */ struct GNUNET_FRAGMENT_Context * frag; + + /** + * The session this fragmentation context belongs to + */ struct Session * session; /** @@ -246,34 +280,87 @@ struct FragmentationContext */ void *cont_cls; + /** + * Message timeout + */ struct GNUNET_TIME_Absolute timeout; - size_t bytes_to_send; + /** + * Payload size of original unfragmented message + */ + size_t payload_size; + + /** + * Bytes used to send all fragments on wire including UDP overhead + */ + size_t on_wire_size; + + unsigned int fragments_used; + }; -struct UDPMessageWrapper +struct UDP_MessageWrapper { + /** + * Session this message belongs to + */ struct Session *session; - struct UDPMessageWrapper *prev; - struct UDPMessageWrapper *next; - char *udp; /** - * Function to call upon completion of the transmission. + * DLL of messages + * previous element */ - GNUNET_TRANSPORT_TransmitContinuation cont; + struct UDP_MessageWrapper *prev; /** - * Closure for 'cont'. + * DLL of messages + * previous element */ - void *cont_cls; + struct UDP_MessageWrapper *next; + + /** + * Message type + * According to UDP_MessageType + */ + int msg_type; - struct FragmentationContext *frag_ctx; + /** + * Message with size msg_size including UDP specific overhead + */ + char *msg_buf; + /** + * Size of UDP message to send including UDP specific overhead + */ size_t msg_size; + /** + * Payload size of original message + */ + size_t payload_size; + + /** + * Message timeout + */ struct GNUNET_TIME_Absolute timeout; + + /** + * Function to call upon completion of the transmission. + */ + GNUNET_TRANSPORT_TransmitContinuation cont; + + /** + * Closure for 'cont'. + */ + void *cont_cls; + + /** + * Fragmentation context + * frag_ctx == NULL if transport <= MTU + * frag_ctx != NULL if transport > MTU + */ + struct UDP_FragmentationContext *frag_ctx; }; @@ -347,6 +434,226 @@ reschedule_session_timeout (struct Session *s); static void stop_session_timeout (struct Session *s); +#if DEBUG_MALLOC + +struct Allocator +{ + struct Allocator *prev; + struct Allocator *next; + + unsigned int bytes_alloced; + unsigned int max_alloced; + unsigned int diff; + unsigned int line; + + struct GNUNET_TIME_Absolute max_alloced_when; + struct GNUNET_TIME_Absolute last_alloced_when; + +}; + +struct Allocator *aehead; +struct Allocator *aetail; + +struct Allocation +{ + struct Allocation *prev; + struct Allocation *next; + + struct Allocator *alloc; + unsigned int bytes_alloced; + void *p; + unsigned int line; +}; + +struct Allocation *ahead; +struct Allocation *atail; + +static int bytes_alloced; + +static struct Allocator * +find_allocator (int line) +{ + struct Allocator *cur = aehead; + while (NULL != cur) + { + if (line == cur->line) + return cur; + cur = cur->next; + } + return cur; +} + +static void +print_allocators () +{ + static int start = GNUNET_YES; + static struct GNUNET_TIME_Absolute next; + static struct GNUNET_TIME_Relative rem; + struct Allocator *cur = aehead; + if (start) + { + next = GNUNET_TIME_UNIT_ZERO_ABS; + start = GNUNET_NO; + } + if (0 == (rem = GNUNET_TIME_absolute_get_remaining(next)).rel_value) + { + fprintf (stderr, "Allocated in `%s' total: %5u bytes\n", __FILE__, bytes_alloced); + while (NULL != cur) + { + char *last_alloc = GNUNET_strdup (GNUNET_STRINGS_absolute_time_to_string(cur->max_alloced_when)); + fprintf (stderr, "Allocated from line %4u :%5u bytes (diff %5i bytes, max alloc: %5u @ %s, last alloc %s)\n", + cur->line, cur->bytes_alloced, cur->diff, cur->max_alloced, + last_alloc, + GNUNET_STRINGS_absolute_time_to_string(cur->last_alloced_when)); + GNUNET_free (last_alloc); + cur->diff = 0; + cur = cur->next; + } + fprintf (stderr, "\n"); + next = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS); + } +} + +#endif + +static void +MEMDEBUG_add_alloc (void *p, size_t size, int line) +{ +#if DEBUG_MALLOC + struct Allocation *alloc = GNUNET_malloc (sizeof (struct Allocation)); + struct Allocator *allocator = find_allocator(line); + if (NULL == allocator) + { + allocator = GNUNET_malloc (sizeof (struct Allocator)); + allocator->line = line; + GNUNET_CONTAINER_DLL_insert (aehead, aetail, allocator); + } + alloc->alloc = allocator; + alloc->p = p; + alloc->line = line; + alloc->bytes_alloced = size; + allocator->bytes_alloced += size; + allocator->last_alloced_when = GNUNET_TIME_absolute_get(); + if (allocator->bytes_alloced >= allocator->max_alloced) + { + allocator->max_alloced = allocator->bytes_alloced; + allocator->max_alloced_when = allocator->last_alloced_when; + } + allocator->diff += size; + GNUNET_CONTAINER_DLL_insert (ahead, atail, alloc); + print_allocators (); + bytes_alloced += size; +#endif +} + + +static void * +MEMDEBUG_malloc (size_t size, int line) +{ + void * ret; + + ret = GNUNET_malloc (size); +#if DEBUG_MALLOC + if (NULL != ret) + MEMDEBUG_add_alloc (ret, size, line); +#endif + return ret; + +} + +static void +MEMDEBUG_free (void * alloc, int line) +{ +#if DEBUG_MALLOC + struct Allocation *cur; + struct Allocator *allocator; + cur = ahead; + while (NULL != cur) + { + if (alloc == cur->p) + break; + cur = cur->next; + } + if (NULL == cur) + { + fprintf (stderr, "Unmonitored free from line %4u\n", line); + GNUNET_break (0); + return; + } + allocator = cur->alloc; + if (NULL == allocator) + { + GNUNET_break (0); + } + GNUNET_CONTAINER_DLL_remove (ahead, atail, cur); + allocator->bytes_alloced -= cur->bytes_alloced; + allocator->diff -= cur->bytes_alloced; + GNUNET_assert (allocator->bytes_alloced >= 0); + bytes_alloced -= cur->bytes_alloced; + GNUNET_assert (bytes_alloced >= 0); + GNUNET_free (cur); +#endif + GNUNET_free (alloc); +} + +static void +MEMDEBUG_free_non_null (void * alloc, int line) +{ + if (alloc != NULL) + MEMDEBUG_free (alloc, line); +} + + +/** + * (re)schedule select tasks for this plugin. + * + * @param plugin plugin to reschedule + */ +static void +schedule_select (struct Plugin *plugin) +{ + struct GNUNET_TIME_Relative min_delay; + struct UDP_MessageWrapper *udpw; + + if (NULL != plugin->sockv4) + { + /* Find a message ready to send: + * Flow delay from other peer is expired or not set (0) */ + min_delay = GNUNET_TIME_UNIT_FOREVER_REL; + for (udpw = plugin->ipv4_queue_head; NULL != udpw; udpw = udpw->next) + min_delay = GNUNET_TIME_relative_min (min_delay, + GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer)); + + if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel(plugin->select_task); + + /* Schedule with: + * - write active set if message is ready + * - timeout minimum delay */ + plugin->select_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + (0 == min_delay.rel_value) ? GNUNET_TIME_UNIT_FOREVER_REL : min_delay, + plugin->rs_v4, + (0 == min_delay.rel_value) ? plugin->ws_v4 : NULL, + &udp_plugin_select, plugin); + } + if (NULL != plugin->sockv6) + { + min_delay = GNUNET_TIME_UNIT_FOREVER_REL; + for (udpw = plugin->ipv6_queue_head; NULL != udpw; udpw = udpw->next) + min_delay = GNUNET_TIME_relative_min (min_delay, + GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer)); + + if (GNUNET_SCHEDULER_NO_TASK != plugin->select_task_v6) + GNUNET_SCHEDULER_cancel(plugin->select_task_v6); + plugin->select_task_v6 = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + (0 == min_delay.rel_value) ? GNUNET_TIME_UNIT_FOREVER_REL : min_delay, + plugin->rs_v6, + (0 == min_delay.rel_value) ? plugin->ws_v6 : NULL, + &udp_plugin_select_v6, plugin); + } +} /** @@ -447,7 +754,7 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen, { struct IPv4UdpAddress *u4; struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; - u4 = GNUNET_malloc (sizeof (struct IPv4UdpAddress)); + u4 = MEMDEBUG_malloc (sizeof (struct IPv4UdpAddress), __LINE__ ); u4->ipv4_addr = in4->sin_addr.s_addr; u4->u4_port = in4->sin_port; *buf = u4; @@ -458,7 +765,7 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen, { struct IPv6UdpAddress *u6; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; - u6 = GNUNET_malloc (sizeof (struct IPv6UdpAddress)); + u6 = MEMDEBUG_malloc (sizeof (struct IPv6UdpAddress), __LINE__ ); u6->ipv6_addr = in6->sin6_addr; u6->u6_port = in6->sin6_port; *buf = u6; @@ -487,12 +794,13 @@ append_port (void *cls, const char *hostname) if (hostname == NULL) { ppc->asc (ppc->asc_cls, NULL); - GNUNET_free (ppc); + MEMDEBUG_free (ppc, __LINE__); return; } GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); + MEMDEBUG_add_alloc (ret, strlen (ret)+ 1, __LINE__); ppc->asc (ppc->asc_cls, ret); - GNUNET_free (ret); + MEMDEBUG_free (ret, __LINE__); } @@ -568,7 +876,7 @@ udp_plugin_address_pretty_printer (void *cls, const char *type, asc (asc_cls, NULL); return; } - ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); + ppc = MEMDEBUG_malloc (sizeof (struct PrettyPrinterContext), __LINE__ ); ppc->asc = asc; ppc->asc_cls = asc_cls; ppc->port = port; @@ -577,17 +885,171 @@ udp_plugin_address_pretty_printer (void *cls, const char *type, static void -call_continuation (struct UDPMessageWrapper *udpw, int result) +call_continuation (struct UDP_MessageWrapper *udpw, int result) { + size_t overhead; + 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), + udpw->payload_size, GNUNET_i2s (&udpw->session->target), (GNUNET_OK == result) ? "OK" : "SYSERR"); - if (NULL != udpw->cont) - { - udpw->cont (udpw->cont_cls, &udpw->session->target,result); - } + if (udpw->msg_size >= udpw->payload_size) + overhead = udpw->msg_size - udpw->payload_size; + else + overhead = udpw->msg_size; + + switch (result) { + case GNUNET_OK: + switch (udpw->msg_type) { + case MSG_UNFRAGMENTED: + if (NULL != udpw->cont) + { + /* Transport continuation */ + udpw->cont (udpw->cont_cls, &udpw->session->target, result, + udpw->payload_size, udpw->msg_size); + } + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, messages, sent, success", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes payload, sent, success", + udpw->payload_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes overhead, sent, success", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes overhead, sent", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes payload, sent", + udpw->payload_size, GNUNET_NO); + break; + case MSG_FRAGMENTED_COMPLETE: + GNUNET_assert (NULL != udpw->frag_ctx); + if (udpw->frag_ctx->cont != NULL) + udpw->frag_ctx->cont (udpw->frag_ctx->cont_cls, &udpw->session->target, GNUNET_OK, + udpw->frag_ctx->payload_size, udpw->frag_ctx->on_wire_size); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, sent, success", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes payload, sent, success", + udpw->payload_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes overhead, sent, success", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes overhead, sent", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes payload, sent", + udpw->payload_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, pending", + -1, GNUNET_NO); + break; + case MSG_FRAGMENTED: + /* Fragmented message: enqueue next fragment */ + if (NULL != udpw->cont) + udpw->cont (udpw->cont_cls, &udpw->session->target, result, + udpw->payload_size, udpw->msg_size); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, fragments, sent, success", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, fragments bytes, sent, success", + udpw->msg_size, GNUNET_NO); + break; + case MSG_ACK: + /* No continuation */ + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, ACK msgs, messages, sent, success", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, ACK msgs, bytes overhead, sent, success", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes overhead, sent", + overhead, GNUNET_NO); + break; + case MSG_BEACON: + GNUNET_break (0); + break; + default: + LOG (GNUNET_ERROR_TYPE_ERROR, + "ERROR: %u\n", udpw->msg_type); + GNUNET_break (0); + break; + } + break; + case GNUNET_SYSERR: + switch (udpw->msg_type) { + case MSG_UNFRAGMENTED: + /* Unfragmented message: failed to send */ + if (NULL != udpw->cont) + udpw->cont (udpw->cont_cls, &udpw->session->target, result, + udpw->payload_size, overhead); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, messages, sent, failure", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes payload, sent, failure", + udpw->payload_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes overhead, sent, failure", + overhead, GNUNET_NO); + break; + case MSG_FRAGMENTED_COMPLETE: + GNUNET_assert (NULL != udpw->frag_ctx); + if (udpw->frag_ctx->cont != NULL) + udpw->frag_ctx->cont (udpw->frag_ctx->cont_cls, &udpw->session->target, GNUNET_SYSERR, + udpw->frag_ctx->payload_size, udpw->frag_ctx->on_wire_size); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, sent, failure", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes payload, sent, failure", + udpw->payload_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes payload, sent, failure", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes payload, sent, failure", + overhead, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, pending", + -1, GNUNET_NO); + break; + case MSG_FRAGMENTED: + GNUNET_assert (NULL != udpw->frag_ctx); + /* Fragmented message: failed to send */ + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, fragments, sent, failure", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, fragments bytes, sent, failure", + udpw->msg_size, GNUNET_NO); + break; + case MSG_ACK: + /* ACK message: failed to send */ + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, ACK msgs, messages, sent, failure", + 1, GNUNET_NO); + break; + case MSG_BEACON: + /* Beacon message: failed to send */ + GNUNET_break (0); + break; + default: + GNUNET_break (0); + break; + } + break; + default: + GNUNET_break (0); + break; + } } @@ -675,16 +1137,101 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen) static void free_session (struct Session *s) { - if (s->frag_ctx != NULL) + if (NULL != s->frag_ctx) { - GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); - GNUNET_free (s->frag_ctx); + GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag, NULL, NULL); + MEMDEBUG_free (s->frag_ctx, __LINE__); s->frag_ctx = NULL; } - GNUNET_free (s); + MEMDEBUG_free (s, __LINE__); } +static void +dequeue (struct Plugin *plugin, struct UDP_MessageWrapper * udpw) +{ + if (plugin->bytes_in_buffer < udpw->msg_size) + GNUNET_break (0); + else + { + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes in buffers", + - (long long) udpw->msg_size, GNUNET_NO); + plugin->bytes_in_buffer -= udpw->msg_size; + } + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, msgs in buffers", + -1, GNUNET_NO); + if (udpw->session->addrlen == sizeof (struct sockaddr_in)) + GNUNET_CONTAINER_DLL_remove (plugin->ipv4_queue_head, + plugin->ipv4_queue_tail, udpw); + if (udpw->session->addrlen == sizeof (struct sockaddr_in6)) + GNUNET_CONTAINER_DLL_remove (plugin->ipv6_queue_head, + plugin->ipv6_queue_tail, udpw); +} + +static void +fragmented_message_done (struct UDP_FragmentationContext *fc, int result) +{ + struct UDP_MessageWrapper *udpw; + struct UDP_MessageWrapper *tmp; + struct UDP_MessageWrapper dummy; + struct Session *s = fc->session; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%p : Fragmented message removed with result %s\n", fc, (result == GNUNET_SYSERR) ? "FAIL" : "SUCCESS"); + + /* Call continuation for fragmented message */ + memset (&dummy, 0, sizeof (dummy)); + dummy.msg_type = MSG_FRAGMENTED_COMPLETE; + dummy.msg_size = s->frag_ctx->on_wire_size; + dummy.payload_size = s->frag_ctx->payload_size; + dummy.frag_ctx = s->frag_ctx; + dummy.cont = NULL; + dummy.cont_cls = NULL; + dummy.session = s; + + call_continuation (&dummy, result); + + /* Remove leftover fragments from queue */ + if (s->addrlen == sizeof (struct sockaddr_in6)) + { + udpw = plugin->ipv6_queue_head; + while (NULL != udpw) + { + tmp = udpw->next; + if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx)) + { + dequeue (plugin, udpw); + call_continuation (udpw, GNUNET_SYSERR); + MEMDEBUG_free (udpw, __LINE__); + } + udpw = tmp; + } + } + if (s->addrlen == sizeof (struct sockaddr_in)) + { + udpw = plugin->ipv4_queue_head; + while (udpw!= NULL) + { + tmp = udpw->next; + if ((NULL != udpw->frag_ctx) && (udpw->frag_ctx == s->frag_ctx)) + { + dequeue (plugin, udpw); + call_continuation (udpw, GNUNET_SYSERR); + MEMDEBUG_free (udpw, __LINE__); + } + udpw = tmp; + } + } + + /* Destroy fragmentation context */ + GNUNET_FRAGMENT_context_destroy (fc->frag, + &s->last_expected_msg_delay, + &s->last_expected_ack_delay); + s->frag_ctx = NULL; + MEMDEBUG_free (fc , __LINE__); +} + /** * Functions with this signature are called whenever we need * to close a session due to a disconnect or failure to @@ -695,8 +1242,8 @@ free_session (struct Session *s) static void disconnect_session (struct Session *s) { - struct UDPMessageWrapper *udpw; - struct UDPMessageWrapper *next; + struct UDP_MessageWrapper *udpw; + struct UDP_MessageWrapper *next; GNUNET_assert (GNUNET_YES != s->in_destroy); LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -704,16 +1251,23 @@ disconnect_session (struct Session *s) s, GNUNET_i2s (&s->target), GNUNET_a2s (s->sock_addr, s->addrlen)); - stop_session_timeout(s); + stop_session_timeout (s); + + if (NULL != s->frag_ctx) + { + /* Remove fragmented message due to disconnect */ + fragmented_message_done (s->frag_ctx, GNUNET_SYSERR); + } + 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); + dequeue (plugin, udpw); call_continuation(udpw, GNUNET_SYSERR); - GNUNET_free (udpw); + MEMDEBUG_free (udpw, __LINE__); } } next = plugin->ipv6_queue_head; @@ -722,9 +1276,9 @@ disconnect_session (struct Session *s) next = udpw->next; if (udpw->session == s) { - GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); + dequeue (plugin, udpw); call_continuation(udpw, GNUNET_SYSERR); - GNUNET_free (udpw); + MEMDEBUG_free (udpw, __LINE__); } udpw = next; } @@ -734,7 +1288,8 @@ disconnect_session (struct Session *s) { if (NULL != s->frag_ctx->cont) { - s->frag_ctx->cont (s->frag_ctx->cont_cls, &s->target, GNUNET_SYSERR); + s->frag_ctx->cont (s->frag_ctx->cont_cls, &s->target, GNUNET_SYSERR, + s->frag_ctx->payload_size, s->frag_ctx->on_wire_size); LOG (GNUNET_ERROR_TYPE_DEBUG, "Calling continuation for fragemented message to `%s' with result SYSERR\n", GNUNET_i2s (&s->target)); @@ -746,7 +1301,7 @@ disconnect_session (struct Session *s) &s->target.hashPubKey, s)); GNUNET_STATISTICS_set(plugin->env->stats, - "# UDP sessions active", + "# UDP, sessions active", GNUNET_CONTAINER_multihashmap_size(plugin->sessions), GNUNET_NO); if (s->rc > 0) @@ -764,7 +1319,7 @@ disconnect_session (struct Session *s) * @return GNUNET_OK (continue to iterate) */ static int -disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) +disconnect_and_free_it (void *cls, const struct GNUNET_HashCode * key, void *value) { disconnect_session(value); return GNUNET_OK; @@ -792,6 +1347,79 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) } +/** + * 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 ms, disconnecting\n", + s, (unsigned long long) 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 ms\n", + s, (unsigned long long) 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 ms\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 stopped for session %p canceled\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } +} + + static struct Session * create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, const void *addr, size_t addrlen, @@ -812,7 +1440,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, return NULL; } t4 = addr; - s = GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in)); + s = MEMDEBUG_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in), __LINE__ ); len = sizeof (struct sockaddr_in); v4 = (struct sockaddr_in *) &s[1]; v4->sin_family = AF_INET; @@ -830,7 +1458,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, } t6 = addr; s = - GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6)); + MEMDEBUG_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6), __LINE__ ); len = sizeof (struct sockaddr_in6); v6 = (struct sockaddr_in6 *) &s[1]; v6->sin6_family = AF_INET6; @@ -849,15 +1477,18 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, s->addrlen = len; s->target = *target; s->sock_addr = (const struct sockaddr *) &s[1]; - s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; - start_session_timeout(s); + s->last_expected_ack_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250); + s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS; + s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS; + s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO; + start_session_timeout (s); return s; } static int session_cmp_it (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, void *value) { struct SessionCompareContext * cctx = cls; @@ -978,27 +1609,38 @@ udp_plugin_get_session (void *cls, &s->target.hashPubKey, s, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); - GNUNET_STATISTICS_set(plugin->env->stats, - "# UDP sessions active", + "# UDP, sessions active", GNUNET_CONTAINER_multihashmap_size(plugin->sessions), GNUNET_NO); - return s; } - static void -enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) +enqueue (struct Plugin *plugin, struct UDP_MessageWrapper * udpw) { - + if (plugin->bytes_in_buffer + udpw->msg_size > INT64_MAX) + GNUNET_break (0); + else + { + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes in buffers", + udpw->msg_size, GNUNET_NO); + plugin->bytes_in_buffer += udpw->msg_size; + } + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, msgs in buffers", + 1, GNUNET_NO); if (udpw->session->addrlen == sizeof (struct sockaddr_in)) - GNUNET_CONTAINER_DLL_insert(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); + GNUNET_CONTAINER_DLL_insert (plugin->ipv4_queue_head, + plugin->ipv4_queue_tail, udpw); if (udpw->session->addrlen == sizeof (struct sockaddr_in6)) - GNUNET_CONTAINER_DLL_insert(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, 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. @@ -1006,14 +1648,15 @@ enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) * @param cls the 'struct UDPMessageWrapper' of the fragment * @param target destination peer (ignored) * @param result GNUNET_OK on success (ignored) + * @param payload bytes payload sent + * @param physical bytes physical sent */ static void send_next_fragment (void *cls, const struct GNUNET_PeerIdentity *target, - int result) + int result, size_t payload, size_t physical) { - struct UDPMessageWrapper *udpw = cls; - + struct UDP_MessageWrapper *udpw = cls; GNUNET_FRAGMENT_context_transmission_done (udpw->frag_ctx->frag); } @@ -1030,59 +1673,27 @@ send_next_fragment (void *cls, static void enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) { - struct FragmentationContext *frag_ctx = cls; + struct UDP_FragmentationContext *frag_ctx = cls; struct Plugin *plugin = frag_ctx->plugin; - struct UDPMessageWrapper * udpw; - struct Session *s; + struct UDP_MessageWrapper * udpw; size_t msg_len = ntohs (msg->size); - + 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); + "Enqueuing fragment with %u bytes\n", msg_len); + frag_ctx->fragments_used ++; + udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + msg_len, __LINE__ ); udpw->session = frag_ctx->session; - s = udpw->session; - udpw->udp = (char *) &udpw[1]; - + udpw->msg_buf = (char *) &udpw[1]; udpw->msg_size = msg_len; + udpw->payload_size = msg_len; /*FIXME: minus fragment overhead */ 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); + udpw->msg_type = MSG_FRAGMENTED; + memcpy (udpw->msg_buf, msg, msg_len); enqueue (plugin, udpw); - - if (s->addrlen == sizeof (struct sockaddr_in)) - { - if (plugin->with_v4_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_TIME_UNIT_FOREVER_REL, - plugin->rs_v4, - plugin->ws_v4, - &udp_plugin_select, plugin); - plugin->with_v4_ws = GNUNET_YES; - } - } - else if (s->addrlen == sizeof (struct sockaddr_in6)) - { - if (plugin->with_v6_ws == GNUNET_NO) - { - 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_TIME_UNIT_FOREVER_REL, - plugin->rs_v6, - plugin->ws_v6, - &udp_plugin_select_v6, plugin); - plugin->with_v6_ws = GNUNET_YES; - } - } + schedule_select (plugin); } @@ -1122,10 +1733,11 @@ udp_plugin_send (void *cls, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) { struct Plugin *plugin = cls; - size_t mlen = msgbuf_size + sizeof (struct UDPMessage); - struct UDPMessageWrapper * udpw; + size_t udpmlen = msgbuf_size + sizeof (struct UDPMessage); + struct UDP_FragmentationContext * frag_ctx; + struct UDP_MessageWrapper * udpw; struct UDPMessage *udp; - char mbuf[mlen]; + char mbuf[udpmlen]; GNUNET_assert (plugin != NULL); GNUNET_assert (s != NULL); @@ -1133,7 +1745,7 @@ udp_plugin_send (void *cls, return GNUNET_SYSERR; if ((s->addrlen == sizeof (struct sockaddr_in)) && (plugin->sockv4 == NULL)) return GNUNET_SYSERR; - if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) + if (udpmlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break (0); return GNUNET_SYSERR; @@ -1145,93 +1757,78 @@ udp_plugin_send (void *cls, } LOG (GNUNET_ERROR_TYPE_DEBUG, "UDP transmits %u-byte message to `%s' using address `%s'\n", - mlen, + udpmlen, GNUNET_i2s (&s->target), GNUNET_a2s(s->sock_addr, s->addrlen)); - + + /* Message */ udp = (struct UDPMessage *) mbuf; - udp->header.size = htons (mlen); + udp->header.size = htons (udpmlen); udp->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE); udp->reserved = htonl (0); udp->sender = *plugin->env->my_identity; reschedule_session_timeout(s); - if (mlen <= UDP_MTU) + if (udpmlen <= UDP_MTU) { - udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + mlen); + /* unfragmented message */ + udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + udpmlen, __LINE__ ); udpw->session = s; - udpw->udp = (char *) &udpw[1]; - udpw->msg_size = mlen; + udpw->msg_buf = (char *) &udpw[1]; + udpw->msg_size = udpmlen; /* message size with UDP overhead */ + udpw->payload_size = msgbuf_size; /* message size without UDP overhead */ udpw->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), to); 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); - + udpw->msg_type = MSG_UNFRAGMENTED; + memcpy (udpw->msg_buf, udp, sizeof (struct UDPMessage)); + memcpy (&udpw->msg_buf[sizeof (struct UDPMessage)], msgbuf, msgbuf_size); enqueue (plugin, udpw); + + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, messages, attempt", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes payload, attempt", + udpw->payload_size, GNUNET_NO); } else { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "UDP has to fragment message \n"); + /* fragmented message */ if (s->frag_ctx != NULL) return GNUNET_SYSERR; memcpy (&udp[1], msgbuf, msgbuf_size); - struct FragmentationContext * frag_ctx = GNUNET_malloc(sizeof (struct FragmentationContext)); - + frag_ctx = MEMDEBUG_malloc (sizeof (struct UDP_FragmentationContext), __LINE__ ); frag_ctx->plugin = plugin; frag_ctx->session = s; frag_ctx->cont = cont; frag_ctx->cont_cls = cont_cls; frag_ctx->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), to); - frag_ctx->bytes_to_send = mlen; + frag_ctx->payload_size = msgbuf_size; /* unfragmented message size without UDP overhead */ + frag_ctx->on_wire_size = 0; /* bytes with UDP and fragmentation overhead */ frag_ctx->frag = GNUNET_FRAGMENT_context_create (plugin->env->stats, - UDP_MTU, - &plugin->tracker, - s->last_expected_delay, - &udp->header, - &enqueue_fragment, - frag_ctx); - + UDP_MTU, + &plugin->tracker, + s->last_expected_msg_delay, + s->last_expected_ack_delay, + &udp->header, + &enqueue_fragment, + frag_ctx); s->frag_ctx = frag_ctx; - } - - if (s->addrlen == sizeof (struct sockaddr_in)) - { - if (plugin->with_v4_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_TIME_UNIT_FOREVER_REL, - plugin->rs_v4, - plugin->ws_v4, - &udp_plugin_select, plugin); - plugin->with_v4_ws = GNUNET_YES; - } - } - else if (s->addrlen == sizeof (struct sockaddr_in6)) - { - if (plugin->with_v6_ws == GNUNET_NO) - { - 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_TIME_UNIT_FOREVER_REL, - plugin->rs_v6, - plugin->ws_v6, - &udp_plugin_select_v6, plugin); - plugin->with_v6_ws = GNUNET_YES; - } - } - - return mlen; + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, pending", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, attempt", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes payload, attempt", + frag_ctx->payload_size, GNUNET_NO); + } + schedule_select (plugin); + return udpmlen; } @@ -1277,7 +1874,7 @@ udp_nat_port_map_callback (void *cls, int add_remove, return; } /* modify our published address list */ - plugin->env->notify_address (plugin->env->cls, add_remove, arg, args); + plugin->env->notify_address (plugin->env->cls, add_remove, arg, args, "udp"); } @@ -1311,7 +1908,7 @@ process_inbound_tokenized_messages (void *cls, void *client, &si->sender, hdr, (const struct GNUNET_ATS_Information *) &ats, 2, - NULL, + si->session, si->arg, si->args); si->session->flow_delay_for_other_peer = delay; @@ -1379,8 +1976,9 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg, GNUNET_a2s (sender_addr, sender_addr_len)); struct GNUNET_HELLO_Address * address = GNUNET_HELLO_address_allocate(&msg->sender, "udp", arg, args); + MEMDEBUG_add_alloc (address, GNUNET_HELLO_address_get_size(address), __LINE__); s = udp_plugin_get_session(plugin, address); - GNUNET_free (address); + MEMDEBUG_free (address, __LINE__); /* iterate over all embedded messages */ si.session = s; @@ -1461,7 +2059,7 @@ struct LookupContext static int -lookup_session_by_addr_it (void *cls, const GNUNET_HashCode * key, void *value) +lookup_session_by_addr_it (void *cls, const struct GNUNET_HashCode * key, void *value) { struct LookupContext *l_ctx = cls; struct Session * s = value; @@ -1490,10 +2088,10 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) size_t msize = sizeof (struct UDP_ACK_Message) + ntohs (msg->size); struct UDP_ACK_Message *udp_ack; uint32_t delay = 0; - struct UDPMessageWrapper *udpw; + struct UDP_MessageWrapper *udpw; struct Session *s; - struct LookupContext l_ctx; + l_ctx.addr = rc->src_addr; l_ctx.addrlen = rc->addr_len; l_ctx.res = NULL; @@ -1515,18 +2113,19 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)), delay); - udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msize); + udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + msize, __LINE__ ); udpw->msg_size = msize; + udpw->payload_size = 0; udpw->session = s; udpw->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; - udpw->udp = (char *)&udpw[1]; - udp_ack = (struct UDP_ACK_Message *) udpw->udp; + udpw->msg_buf = (char *)&udpw[1]; + udpw->msg_type = MSG_ACK; + udp_ack = (struct UDP_ACK_Message *) udpw->msg_buf; udp_ack->header.size = htons ((uint16_t) msize); udp_ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK); udp_ack->delay = htonl (delay); udp_ack->sender = *rc->plugin->env->my_identity; memcpy (&udp_ack[1], msg, ntohs (msg->size)); - enqueue (rc->plugin, udpw); } @@ -1570,15 +2169,18 @@ read_process_ack (struct Plugin *plugin, l_ctx.addrlen = fromlen; l_ctx.res = NULL; GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, - &lookup_session_by_addr_it, - &l_ctx); + &lookup_session_by_addr_it, + &l_ctx); s = l_ctx.res; - if ((s == NULL) || (s->frag_ctx == NULL)) + if ((NULL == s) || (NULL == s->frag_ctx)) + { return; + } flow_delay.rel_value = (uint64_t) ntohl (udp_ack->delay); - LOG (GNUNET_ERROR_TYPE_DEBUG, "We received a sending delay of %llu\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, + "We received a sending delay of %llu\n", flow_delay.rel_value); s->flow_delay_from_other_peer = GNUNET_TIME_relative_to_absolute (flow_delay); @@ -1591,62 +2193,25 @@ read_process_ack (struct Plugin *plugin, return; } + if (0 != memcmp (&l_ctx.res->target, &udp_ack->sender, sizeof (struct GNUNET_PeerIdentity))) + GNUNET_break (0); if (GNUNET_OK != GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag, ack)) { 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)); + /* Expect more ACKs to arrive */ return; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "FULL MESSAGE ACKed\n", + "Message full ACK'ed\n", (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); - s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag); - struct UDPMessageWrapper * udpw; - struct UDPMessageWrapper * tmp; - if (s->addrlen == sizeof (struct sockaddr_in6)) - { - udpw = plugin->ipv6_queue_head; - 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 = tmp; - } - } - if (s->addrlen == sizeof (struct sockaddr_in)) - { - 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 = tmp; - } - } - - if (s->frag_ctx->cont != NULL) - { - 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; + /* Remove fragmented message after successful sending */ + fragmented_message_done (s->frag_ctx, GNUNET_OK); } @@ -1677,7 +2242,7 @@ read_process_fragment (struct Plugin *plugin, if (d_ctx == NULL) { /* Create a new defragmentation context */ - d_ctx = GNUNET_malloc (sizeof (struct DefragContext) + fromlen); + d_ctx = MEMDEBUG_malloc (sizeof (struct DefragContext) + fromlen, __LINE__ ); memcpy (&d_ctx[1], addr, fromlen); d_ctx->src_addr = (const struct sockaddr *) &d_ctx[1]; d_ctx->addr_len = fromlen; @@ -1717,7 +2282,7 @@ read_process_fragment (struct Plugin *plugin, d_ctx = GNUNET_CONTAINER_heap_remove_root (plugin->defrag_ctxs); GNUNET_assert (NULL != d_ctx); GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag); - GNUNET_free (d_ctx); + MEMDEBUG_free (d_ctx, __LINE__); } } @@ -1741,9 +2306,34 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) memset (&addr, 0, sizeof (addr)); size = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf), (struct sockaddr *) &addr, &fromlen); - +#if MINGW + /* On SOCK_DGRAM UDP sockets recvfrom might fail with a + * WSAECONNRESET error to indicate that previous sendto() (yes, sendto!) + * on this socket has failed. + * Quote from MSDN: + * WSAECONNRESET - The virtual circuit was reset by the remote side + * executing a hard or abortive close. The application should close + * the socket; it is no longer usable. On a UDP-datagram socket this + * error indicates a previous send operation resulted in an ICMP Port + * Unreachable message. + */ + if ( (-1 == size) && (ECONNRESET == errno) ) + return; +#endif + if (-1 == size) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "UDP failed to receive data: %s\n", STRERROR (errno)); + /* Connection failure or something. Not a protocol violation. */ + return; + } if (size < sizeof (struct GNUNET_MessageHeader)) { + LOG (GNUNET_ERROR_TYPE_WARNING, + "UDP got %u bytes, which is not enough for a GNUnet message header\n", + (unsigned int) size); + /* _MAY_ be a connection failure (got partial message) */ + /* But it _MAY_ also be that the other side uses non-GNUnet protocol. */ GNUNET_break_op (0); return; } @@ -1759,6 +2349,10 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) return; } + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, received", + size, GNUNET_NO); + switch (ntohs (msg->type)) { case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: @@ -1783,143 +2377,222 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) } } - -static size_t -udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) +static struct UDP_MessageWrapper * +remove_timeout_messages_and_select (struct UDP_MessageWrapper *head, + struct GNUNET_NETWORK_Handle *sock) { - ssize_t sent; - size_t slen; - struct GNUNET_TIME_Absolute max; - struct UDPMessageWrapper *udpw = NULL; - - if (sock == plugin->sockv4) - { - udpw = plugin->ipv4_queue_head; - } - else if (sock == plugin->sockv6) - { - udpw = plugin->ipv6_queue_head; - } - else - { - GNUNET_break (0); - return 0; - } - - const struct sockaddr * sa = udpw->session->sock_addr; - slen = udpw->session->addrlen; - - max = GNUNET_TIME_absolute_max(udpw->timeout, GNUNET_TIME_absolute_get()); + struct UDP_MessageWrapper *udpw = NULL; + struct GNUNET_TIME_Relative remaining; + udpw = head; while (udpw != NULL) { - if (max.abs_value != udpw->timeout.abs_value) + /* Find messages with timeout */ + remaining = GNUNET_TIME_absolute_get_remaining (udpw->timeout); + if (GNUNET_TIME_UNIT_ZERO.rel_value == remaining.rel_value) { /* Message timed out */ - call_continuation(udpw, GNUNET_SYSERR); - if (udpw->frag_ctx != NULL) - { - 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 - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Message for peer `%s' with size %u timed out\n", - GNUNET_i2s(&udpw->session->target), udpw->msg_size); + switch (udpw->msg_type) { + case MSG_UNFRAGMENTED: + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, sent, timeout", + udpw->msg_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, messages, sent, timeout", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, messages, sent, timeout", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, unfragmented msgs, bytes, sent, timeout", + udpw->payload_size, GNUNET_NO); + /* Not fragmented message */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message for peer `%s' with size %u timed out\n", + GNUNET_i2s(&udpw->session->target), udpw->payload_size); + call_continuation (udpw, GNUNET_SYSERR); + /* Remove message */ + dequeue (plugin, udpw); + MEMDEBUG_free (udpw, __LINE__); + break; + case MSG_FRAGMENTED: + /* Fragmented message */ + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, sent, timeout", + udpw->frag_ctx->on_wire_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, messages, sent, timeout", + 1, GNUNET_NO); + call_continuation (udpw, GNUNET_SYSERR); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Fragment for message for peer `%s' with size %u timed out\n", + GNUNET_i2s(&udpw->session->target), udpw->frag_ctx->payload_size); + + + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, messages, sent, timeout", + 1, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, fragmented msgs, bytes, sent, timeout", + udpw->frag_ctx->payload_size, GNUNET_NO); + /* Remove fragmented message due to timeout */ + fragmented_message_done (udpw->frag_ctx, GNUNET_SYSERR); + break; + case MSG_ACK: + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, sent, timeout", + udpw->msg_size, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, messages, sent, timeout", + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "ACK Message for peer `%s' with size %u timed out\n", + GNUNET_i2s(&udpw->session->target), udpw->payload_size); + call_continuation (udpw, GNUNET_SYSERR); + dequeue (plugin, udpw); + MEMDEBUG_free (udpw, __LINE__); + break; + default: + break; } - if (sock == plugin->sockv4) - { - GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); - GNUNET_free (udpw); udpw = plugin->ipv4_queue_head; - } else if (sock == plugin->sockv6) - { - GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); - GNUNET_free (udpw); udpw = plugin->ipv6_queue_head; + else + { + GNUNET_break (0); /* should never happen */ + udpw = NULL; } + GNUNET_STATISTICS_update (plugin->env->stats, + "# messages dismissed due to timeout", + 1, GNUNET_NO); } else { - struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer); - if (delta.rel_value == 0) + /* Message did not time out, check flow delay */ + remaining = GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer); + if (GNUNET_TIME_UNIT_ZERO.rel_value == remaining.rel_value) { /* this message is not delayed */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Message for peer `%s' (%u bytes) is not delayed \n", - GNUNET_i2s(&udpw->session->target), udpw->msg_size); - break; + "Message for peer `%s' (%u bytes) is not delayed \n", + GNUNET_i2s(&udpw->session->target), udpw->payload_size); + break; /* Found message to send, break */ } else { - /* this message is delayed, try next */ + /* Message is delayed, try next */ 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); + "Message for peer `%s' (%u bytes) is delayed for %llu \n", + GNUNET_i2s(&udpw->session->target), udpw->payload_size, remaining.rel_value); udpw = udpw->next; } } } + return udpw; +} - if (udpw == NULL) - { - /* No message left */ - return 0; - } - sent = GNUNET_NETWORK_socket_sendto (sock, udpw->udp, udpw->msg_size, sa, slen); +static void +analyze_send_error (struct Plugin *plugin, + const struct sockaddr * sa, + socklen_t slen, + int error) +{ + static int network_down_error; + struct GNUNET_ATS_Information type; + + type = plugin->env->get_address_type (plugin->env->cls,sa, slen); + if (((GNUNET_ATS_NET_LAN == ntohl(type.value)) || (GNUNET_ATS_NET_WAN == ntohl(type.value))) && + ((ENETUNREACH == errno) || (ENETDOWN == errno))) + { + if ((network_down_error == GNUNET_NO) && (slen == sizeof (struct sockaddr_in))) + { + /* IPv4: "Network unreachable" or "Network down" + * + * This indicates we do not have connectivity + */ + LOG (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, + _("UDP could not transmit message to `%s': " + "Network seems down, please check your network configuration\n"), + GNUNET_a2s (sa, slen)); + } + if ((network_down_error == GNUNET_NO) && (slen == sizeof (struct sockaddr_in6))) + { + /* IPv6: "Network unreachable" or "Network down" + * + * This indicates that this system is IPv6 enabled, but does not + * have a valid global IPv6 address assigned or we do not have + * connectivity + */ + + LOG (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, + _("UDP could not transmit message to `%s': " + "Please check your network configuration and disable IPv6 if your " + "connection does not have a global IPv6 address\n"), + GNUNET_a2s (sa, slen)); + } + } + else + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "UDP could not transmit message to `%s': `%s'\n", + GNUNET_a2s (sa, slen), STRERROR (error)); + } +} + +static size_t +udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) +{ + const struct sockaddr * sa; + ssize_t sent; + socklen_t slen; + + struct UDP_MessageWrapper *udpw = NULL; + + /* Find message to send */ + udpw = remove_timeout_messages_and_select ((sock == plugin->sockv4) ? plugin->ipv4_queue_head : plugin->ipv6_queue_head, + sock); + if (NULL == udpw) + return 0; /* No message to send */ + + sa = udpw->session->sock_addr; + slen = udpw->session->addrlen; + + sent = GNUNET_NETWORK_socket_sendto (sock, udpw->msg_buf, udpw->msg_size, sa, slen); if (GNUNET_SYSERR == sent) { - const struct GNUNET_ATS_Information type = plugin->env->get_address_type - (plugin->env->cls,sa, slen); - - 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)); - } + /* Failure */ + analyze_send_error (plugin, sa, slen, errno); call_continuation(udpw, GNUNET_SYSERR); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, sent, failure", + sent, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, messages, sent, failure", + 1, GNUNET_NO); } else { + /* Success */ 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, + "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n", + (unsigned int) (udpw->msg_size), GNUNET_i2s(&udpw->session->target) ,GNUNET_a2s (sa, slen), (int) sent, (sent < 0) ? STRERROR (errno) : "ok"); - call_continuation(udpw, GNUNET_OK); - } - - if (sock == plugin->sockv4) - GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); - else if (sock == plugin->sockv6) - GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); - GNUNET_free (udpw); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, bytes, sent, success", + sent, GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + "# UDP, total, messages, sent, success", + 1, GNUNET_NO); + if (NULL != udpw->frag_ctx) + udpw->frag_ctx->on_wire_size += udpw->msg_size; + call_continuation (udpw, GNUNET_OK); + } + dequeue (plugin, udpw); + MEMDEBUG_free (udpw, __LINE__); udpw = NULL; return sent; @@ -1940,38 +2613,18 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct Plugin *plugin = cls; plugin->select_task = GNUNET_SCHEDULER_NO_TASK; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - plugin->with_v4_ws = GNUNET_NO; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) - { - if ((NULL != plugin->sockv4) && - (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4))) - udp_select_read (plugin, plugin->sockv4); - - } - - if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) - { - if ((NULL != plugin->sockv4) && (plugin->ipv4_queue_head != NULL) && - (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv4))) - { - udp_select_send (plugin, plugin->sockv4); - } - } - - 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_TIME_UNIT_FOREVER_REL, - plugin->rs_v4, - (plugin->ipv4_queue_head != NULL) ? plugin->ws_v4 : NULL, - &udp_plugin_select, plugin); - if (plugin->ipv4_queue_head != NULL) - plugin->with_v4_ws = GNUNET_YES; - else - plugin->with_v4_ws = GNUNET_NO; + if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) && + (NULL != plugin->sockv4) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)) ) + udp_select_read (plugin, plugin->sockv4); + if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && + (NULL != plugin->sockv4) && + (NULL != plugin->ipv4_queue_head) && + (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv4)) ) + udp_select_send (plugin, plugin->sockv4); + schedule_select (plugin); } @@ -1989,36 +2642,17 @@ udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct Plugin *plugin = cls; plugin->select_task_v6 = GNUNET_SCHEDULER_NO_TASK; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - - plugin->with_v6_ws = GNUNET_NO; - if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) - { - if ((NULL != plugin->sockv6) && - (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6))) - udp_select_read (plugin, plugin->sockv6); - } - - if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) - { - if ((NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) && - (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6))) - { - udp_select_send (plugin, plugin->sockv6); - } - } - 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_TIME_UNIT_FOREVER_REL, - plugin->rs_v6, - (plugin->ipv6_queue_head != NULL) ? plugin->ws_v6 : NULL, - &udp_plugin_select_v6, plugin); - if (plugin->ipv6_queue_head != NULL) - plugin->with_v6_ws = GNUNET_YES; - else - plugin->with_v6_ws = GNUNET_NO; + if ( ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) && + (NULL != plugin->sockv6) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)) ) + udp_select_read (plugin, plugin->sockv6); + if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && + (NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) && + (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6)) ) + udp_select_send (plugin, plugin->sockv6); + schedule_select (plugin); } @@ -2134,17 +2768,8 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4); } - if (sockets_created == 0) + if (0 == sockets_created) LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); - - plugin->select_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_TIME_UNIT_FOREVER_REL, - plugin->rs_v4, - NULL, - &udp_plugin_select, plugin); - plugin->with_v4_ws = GNUNET_NO; - if (plugin->enable_ipv6 == GNUNET_YES) { plugin->rs_v6 = GNUNET_NETWORK_fdset_create (); @@ -2156,16 +2781,8 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct GNUNET_NETWORK_fdset_set (plugin->rs_v6, plugin->sockv6); GNUNET_NETWORK_fdset_set (plugin->ws_v6, plugin->sockv6); } - - plugin->select_task_v6 = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_TIME_UNIT_FOREVER_REL, - plugin->rs_v6, - NULL, - &udp_plugin_select_v6, plugin); - plugin->with_v6_ws = GNUNET_NO; } - + schedule_select (plugin); plugin->nat = GNUNET_NAT_register (plugin->env->cfg, GNUNET_NO, plugin->port, sockets_created, @@ -2175,82 +2792,6 @@ 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 @@ -2272,6 +2813,7 @@ libgnunet_plugin_transport_udp_init (void *cls) unsigned long long enable_v6; char * bind4_address; char * bind6_address; + char * fancy_interval; struct GNUNET_TIME_Relative interval; struct sockaddr_in serverAddrv4; struct sockaddr_in6 serverAddrv6; @@ -2281,7 +2823,7 @@ libgnunet_plugin_transport_udp_init (void *cls) { /* 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 = MEMDEBUG_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions), __LINE__ ); api->cls = NULL; api->address_pretty_printer = &udp_plugin_address_pretty_printer; api->address_to_string = &udp_address_to_string; @@ -2331,7 +2873,7 @@ libgnunet_plugin_transport_udp_init (void *cls) bind4_address); if (1 != inet_pton (AF_INET, bind4_address, &serverAddrv4.sin_addr)) { - GNUNET_free (bind4_address); + MEMDEBUG_free (bind4_address, __LINE__); return NULL; } } @@ -2348,8 +2890,8 @@ libgnunet_plugin_transport_udp_init (void *cls) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid IPv6 address: `%s'\n"), bind6_address); - GNUNET_free_non_null (bind4_address); - GNUNET_free (bind6_address); + MEMDEBUG_free_non_null (bind4_address, __LINE__); + MEMDEBUG_free (bind6_address, __LINE__); return NULL; } } @@ -2360,11 +2902,20 @@ libgnunet_plugin_transport_udp_init (void *cls) if (broadcast == GNUNET_SYSERR) broadcast = GNUNET_NO; - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (env->cfg, "transport-udp", - "BROADCAST_INTERVAL", &interval)) + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp", + "BROADCAST_INTERVAL", &fancy_interval)) { interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); } + else + { + MEMDEBUG_add_alloc (fancy_interval, strlen (fancy_interval)+ 1, __LINE__); + if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_relative(fancy_interval, &interval)) + { + interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); + } + MEMDEBUG_free (fancy_interval, __LINE__); + } /* Maximum datarate */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", @@ -2373,12 +2924,12 @@ libgnunet_plugin_transport_udp_init (void *cls) udp_max_bps = 1024 * 1024 * 50; /* 50 MB/s == infinity for practical purposes */ } - p = GNUNET_malloc (sizeof (struct Plugin)); - api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + p = MEMDEBUG_malloc (sizeof (struct Plugin), __LINE__ ); + api = MEMDEBUG_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions), __LINE__ ); GNUNET_BANDWIDTH_tracker_init (&p->tracker, GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30); - p->sessions = GNUNET_CONTAINER_multihashmap_create (10); + p->sessions = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 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; @@ -2404,8 +2955,8 @@ libgnunet_plugin_transport_udp_init (void *cls) if ((res == 0) || ((p->sockv4 == NULL) && (p->sockv6 == NULL))) { LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin failed\n"); - GNUNET_free (p); - GNUNET_free (api); + MEMDEBUG_free (p, __LINE__); + MEMDEBUG_free (api, __LINE__); return NULL; } @@ -2415,8 +2966,8 @@ libgnunet_plugin_transport_udp_init (void *cls) setup_broadcast (p, &serverAddrv6, &serverAddrv4); } - GNUNET_free_non_null (bind4_address); - GNUNET_free_non_null (bind6_address); + MEMDEBUG_free_non_null (bind4_address, __LINE__); + MEMDEBUG_free_non_null (bind6_address, __LINE__); return api; } @@ -2432,7 +2983,7 @@ heap_cleanup_iterator (void *cls, GNUNET_CONTAINER_heap_remove_node (node); GNUNET_DEFRAGMENT_context_destroy(d_ctx->defrag); - GNUNET_free (d_ctx); + MEMDEBUG_free (d_ctx, __LINE__); return GNUNET_YES; } @@ -2453,12 +3004,11 @@ libgnunet_plugin_transport_udp_done (void *cls) if (NULL == plugin) { - GNUNET_free (api); + MEMDEBUG_free (api, __LINE__); return NULL; } stop_broadcast (plugin); - if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->select_task); @@ -2504,23 +3054,25 @@ libgnunet_plugin_transport_udp_done (void *cls) } /* Clean up leftover messages */ - struct UDPMessageWrapper * udpw; + struct UDP_MessageWrapper * udpw; udpw = plugin->ipv4_queue_head; while (udpw != NULL) { - struct UDPMessageWrapper *tmp = udpw->next; - GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); + struct UDP_MessageWrapper *tmp = udpw->next; + dequeue (plugin, udpw); call_continuation(udpw, GNUNET_SYSERR); - GNUNET_free (udpw); + MEMDEBUG_free (udpw, __LINE__); + udpw = tmp; } udpw = plugin->ipv6_queue_head; while (udpw != NULL) { - struct UDPMessageWrapper *tmp = udpw->next; - GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); + struct UDP_MessageWrapper *tmp = udpw->next; + dequeue (plugin, udpw); call_continuation(udpw, GNUNET_SYSERR); - GNUNET_free (udpw); + MEMDEBUG_free (udpw, __LINE__); + udpw = tmp; } @@ -2531,8 +3083,24 @@ libgnunet_plugin_transport_udp_done (void *cls) GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); plugin->nat = NULL; - GNUNET_free (plugin); - GNUNET_free (api); + MEMDEBUG_free (plugin, __LINE__); + MEMDEBUG_free (api, __LINE__); +#if DEBUG_MALLOC + struct Allocation *allocation; + while (NULL != ahead) + { + allocation = ahead; + GNUNET_CONTAINER_DLL_remove (ahead, atail, allocation); + GNUNET_free (allocation); + } + struct Allocator *allocator; + while (NULL != aehead) + { + allocator = aehead; + GNUNET_CONTAINER_DLL_remove (aehead, aetail, allocator); + GNUNET_free (allocator); + } +#endif return NULL; } diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h index 5637524..bab8e6c 100644 --- a/src/transport/plugin_transport_udp.h +++ b/src/transport/plugin_transport_udp.h @@ -159,6 +159,12 @@ struct Plugin */ char *bind6_address; + + /** + * Bytes currently in buffer + */ + int64_t bytes_in_buffer; + /** * Handle to NAT traversal support. */ @@ -175,8 +181,6 @@ struct Plugin struct GNUNET_NETWORK_FDSet *ws_v4; - int with_v4_ws; - /** * The read socket for IPv4 */ @@ -193,8 +197,6 @@ struct Plugin */ struct GNUNET_NETWORK_FDSet *ws_v6; - int with_v6_ws; - /** * The read socket for IPv6 */ @@ -268,11 +270,11 @@ struct Plugin */ uint16_t aport; - struct UDPMessageWrapper *ipv4_queue_head; - struct UDPMessageWrapper *ipv4_queue_tail; + struct UDP_MessageWrapper *ipv4_queue_head; + struct UDP_MessageWrapper *ipv4_queue_tail; - struct UDPMessageWrapper *ipv6_queue_head; - struct UDPMessageWrapper *ipv6_queue_tail; + struct UDP_MessageWrapper *ipv6_queue_head; + struct UDP_MessageWrapper *ipv6_queue_tail; }; diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c index baabf45..db6c1fe 100644 --- a/src/transport/plugin_transport_udp_broadcasting.c +++ b/src/transport/plugin_transport_udp_broadcasting.c @@ -228,6 +228,8 @@ prepare_beacon (struct Plugin *plugin, struct UDP_Beacon_Message *msg) const struct GNUNET_MessageHeader *hello; hello = plugin->env->get_our_hello (); + if (NULL == hello) + return 0; hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); msg_size = hello_size + sizeof (struct UDP_Beacon_Message); @@ -258,7 +260,7 @@ udp_ipv4_broadcast_send (void *cls, sent = 0; baddr = plugin->ipv4_broadcast_head; /* just IPv4 */ - while ((baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in))) + while ((msg_size > 0) && (baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in))) { struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr; @@ -268,7 +270,19 @@ udp_ipv4_broadcast_send (void *cls, (const struct sockaddr *) addr, baddr->addrlen); if (sent == GNUNET_SYSERR) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); + { + if ((ENETUNREACH == errno) || (ENETDOWN == errno)) + { + /* "Network unreachable" or "Network down" + * + * This indicates that we just do not have network connectivity + */ + GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, + "Network connectivity is down, cannot send beacon!\n"); + } + else + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); + } else { LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -301,7 +315,20 @@ udp_ipv6_broadcast_send (void *cls, &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6)); if (sent == GNUNET_SYSERR) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); + { + if ((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 + */ + GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, + "Network connectivity is down, cannot send beacon!\n"); + } + else + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); + } else { LOG (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 057479d..940582d 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c @@ -43,6 +43,10 @@ #include "transport.h" #define MAX_PROBES 20 +#define MAX_RETRIES 3 +#define RETRY 0 + +#define LOG(kind,...) GNUNET_log_from (kind, "transport-unix",__VA_ARGS__) /* * Transport cost to peer, always 1 for UNIX (direct connection) @@ -82,9 +86,10 @@ struct UNIXMessage struct Session { + struct GNUNET_PeerIdentity target; + void *addr; size_t addrlen; - struct GNUNET_PeerIdentity target; /** * Session timeout task @@ -101,8 +106,9 @@ struct UNIXMessageWrapper struct UNIXMessage * msg; size_t msgsize; + size_t payload; - struct GNUNET_TIME_Relative timeout; + struct GNUNET_TIME_Absolute timeout; unsigned int priority; struct Session *session; @@ -310,7 +316,7 @@ struct LookupCtx }; int lookup_session_it (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, void *value) { struct LookupCtx *lctx = cls; @@ -359,7 +365,7 @@ disconnect_session (struct Session *s) 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); + 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); @@ -374,7 +380,8 @@ disconnect_session (struct 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); + msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, + msgw->payload, 0); GNUNET_free (msgw->msg); GNUNET_free (msgw); removed = GNUNET_YES; @@ -394,7 +401,7 @@ disconnect_session (struct Session *s) } static int -get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) +get_session_delete_it (void *cls, const struct GNUNET_HashCode * key, void *value) { struct Session *s = value; disconnect_session (s); @@ -432,14 +439,14 @@ static int unix_transport_server_stop (void *cls) { struct Plugin *plugin = cls; - - struct UNIXMessageWrapper * msgw = plugin->msg_head; + struct UNIXMessageWrapper * msgw; while (NULL != (msgw = plugin->msg_head)) { GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw); if (msgw->cont != NULL) - msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR); + msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, + msgw->payload, 0); GNUNET_free (msgw->msg); GNUNET_free (msgw); } @@ -474,21 +481,25 @@ unix_transport_server_stop (void *cls) * @param timeout when should we time out (give up) if we can not transmit? * @param addr the addr to send the message to, needs to be a sockaddr for us * @param addrlen the len of addr + * @param payload bytes payload to send * @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...) * @param cont_cls closure for cont * - * @return the number of bytes written, -1 on errors + * @return on success : the number of bytes written, 0 n retry, -1 on errors */ static ssize_t unix_real_send (void *cls, struct GNUNET_NETWORK_Handle *send_handle, const struct GNUNET_PeerIdentity *target, const char *msgbuf, size_t msgbuf_size, unsigned int priority, - struct GNUNET_TIME_Relative timeout, const void *addr, - size_t addrlen, GNUNET_TRANSPORT_TransmitContinuation cont, + struct GNUNET_TIME_Absolute timeout, + const void *addr, + size_t addrlen, + size_t payload, + GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) { struct Plugin *plugin = cls; @@ -497,25 +508,18 @@ unix_real_send (void *cls, size_t sbs; struct sockaddr_un un; size_t slen; - int retry; GNUNET_assert (NULL != plugin); if (send_handle == NULL) { - /* We do not have a send handle */ - GNUNET_break (0); - if (cont != NULL) - cont (cont_cls, target, GNUNET_SYSERR); - return -1; + GNUNET_break (0); /* We do not have a send handle */ + return GNUNET_SYSERR; } if ((addr == NULL) || (addrlen == 0)) { - /* Can never send if we don't have an address */ - GNUNET_break (0); - if (cont != NULL) - cont (cont_cls, target, GNUNET_SYSERR); - return -1; + GNUNET_break (0); /* Can never send if we don't have an address */ + return GNUNET_SYSERR; } /* Prepare address */ @@ -537,88 +541,61 @@ unix_real_send (void *cls, sb = (struct sockaddr *) &un; sbs = slen; +resend: /* 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))) + if (GNUNET_SYSERR == sent) { - /* We have to retry later: retry */ - return 0; - } - - if ((GNUNET_SYSERR == sent) && (errno == EMSGSIZE)) - { - socklen_t size = 0; - socklen_t len = sizeof (size); - - GNUNET_NETWORK_socket_getsockopt ((struct GNUNET_NETWORK_Handle *) - send_handle, SOL_SOCKET, SO_SNDBUF, &size, - &len); - - if (size < msgbuf_size) + if (errno == EAGAIN) + { + return RETRY; /* We have to retry later */ + } + if (errno == ENOBUFS) + { + return RETRY; /* We have to retry later */ + } + if (errno == EMSGSIZE) { - 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; - if (GNUNET_NETWORK_socket_setsockopt - ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF, - &size, sizeof (size)) == GNUNET_OK) + socklen_t size = 0; + socklen_t len = sizeof (size); + + GNUNET_NETWORK_socket_getsockopt ((struct GNUNET_NETWORK_Handle *) + send_handle, SOL_SOCKET, SO_SNDBUF, &size, + &len); + if (size < msgbuf_size) { - /* Increased buffer size, retry sending */ - return 0; + 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; + if (GNUNET_OK == GNUNET_NETWORK_socket_setsockopt + ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF, + &size, sizeof (size))) + goto resend; /* Increased buffer size, retry sending */ + else + { + /* Could not increase buffer size: error, no retry */ + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); + return GNUNET_SYSERR; + } } else { - /* Could not increase buffer size: error, no retry */ - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); - return -1; + /* Buffer is bigger than message: error, no retry + * This should never happen!*/ + GNUNET_break (0); + return GNUNET_SYSERR; } } - else - { - /* Buffer is bigger than message: error, no retry - * This should never happen!*/ - GNUNET_break (0); - return -1; - } } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + 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"); - - /* Calling continuation */ - if (cont != NULL) - { - if ((sent == GNUNET_SYSERR) && (retry == GNUNET_NO)) - cont (cont_cls, target, GNUNET_SYSERR); - if (sent > 0) - cont (cont_cls, target, GNUNET_OK); - } - - /* 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; - /* default */ - return -1; + return sent; } struct gsi_ctx @@ -630,12 +607,12 @@ struct gsi_ctx static int -get_session_it (void *cls, const GNUNET_HashCode * key, void *value) +get_session_it (void *cls, const struct GNUNET_HashCode * key, void *value) { struct gsi_ctx *gsi = cls; struct Session *s = value; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing session %s %s\n", gsi->address, s->addr); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Comparing session %s %s\n", gsi->address, s->addr); if ((gsi->addrlen == s->addrlen) && (0 == memcmp (gsi->address, s->addr, s->addrlen))) { @@ -672,7 +649,7 @@ 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) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Found existing session\n"); return gsi.res; } @@ -694,7 +671,7 @@ unix_plugin_get_session (void *cls, "# UNIX sessions active", GNUNET_CONTAINER_multihashmap_size(plugin->session_map), GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating new session\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new session\n"); return s; } @@ -749,20 +726,24 @@ unix_plugin_send (void *cls, struct UNIXMessageWrapper *wrapper; struct UNIXMessage *message; int ssize; - + GNUNET_assert (plugin != NULL); GNUNET_assert (session != NULL); 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", + 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; } + LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending %u bytes with session for peer `%s' `%s'\n", + msgbuf_size, + GNUNET_i2s (&session->target), + (char *) session->addr); ssize = sizeof (struct UNIXMessage) + msgbuf_size; message = GNUNET_malloc (sizeof (struct UNIXMessage) + msgbuf_size); @@ -777,8 +758,9 @@ unix_plugin_send (void *cls, wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper)); wrapper->msg = message; wrapper->msgsize = ssize; + wrapper->payload = msgbuf_size; wrapper->priority = priority; - wrapper->timeout = to; + wrapper->timeout = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), to); wrapper->cont = cont; wrapper->cont_cls = cont_cls; wrapper->session = session; @@ -786,15 +768,16 @@ unix_plugin_send (void *cls, GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, wrapper); plugin->bytes_in_queue += ssize; - GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes in send queue", + GNUNET_STATISTICS_set (plugin->env->stats,"# bytes currently in UNIX buffers", plugin->bytes_in_queue, GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", ssize, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", ssize, (char *) session->addr); if (plugin->with_ws == GNUNET_NO) { reschedule_select (plugin); } + return ssize; } @@ -824,11 +807,13 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, GNUNET_assert (fromlen >= sizeof (struct sockaddr_un)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", un->sun_path); + + plugin->bytes_in_recv += ntohs(currhdr->size); - GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes received", + GNUNET_STATISTICS_set (plugin->env->stats,"# bytes received via UNIX", plugin->bytes_in_recv, GNUNET_NO); addr = GNUNET_HELLO_address_allocate(sender, "unix", un->sun_path, strlen (un->sun_path) + 1); @@ -879,7 +864,7 @@ unix_plugin_select_read (struct Plugin * plugin) #if LINUX un.sun_path[0] = '/'; #endif - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from socket %s\n", ret, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from socket %s\n", ret, &un.sun_path[0]); } @@ -916,9 +901,37 @@ unix_plugin_select_read (struct Plugin * plugin) static void unix_plugin_select_write (struct Plugin * plugin) { - static int retry_counter; int sent = 0; - struct UNIXMessageWrapper * msgw = plugin->msg_head; + + struct UNIXMessageWrapper * msgw = plugin->msg_tail; + while (NULL != msgw) + { + if (GNUNET_TIME_absolute_get_remaining (msgw->timeout).rel_value > 0) + break; /* Message is ready for sending */ + else + { + /* Message has a timeout */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for message with %llu bytes \n", msgw->msgsize); + 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, msgw->payload, 0); + + plugin->bytes_in_queue -= msgw->msgsize; + GNUNET_STATISTICS_set (plugin->env->stats, "# bytes currently in UNIX buffers", + 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); + } + msgw = plugin->msg_tail; + } + if (NULL == msgw) + return; /* Nothing to send at the moment */ sent = unix_real_send (plugin, plugin->unix_sock.desc, @@ -929,33 +942,26 @@ unix_plugin_select_write (struct Plugin * plugin) msgw->timeout, msgw->session->addr, msgw->session->addrlen, + msgw->payload, msgw->cont, msgw->cont_cls); - if (sent == 0) + if (RETRY == sent) { - /* failed and retry */ - retry_counter++; - GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", - retry_counter, GNUNET_NO); - return; - } + GNUNET_STATISTICS_update (plugin->env->stats,"# UNIX retry attempts", + 1, GNUNET_NO); - 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) + else if (GNUNET_SYSERR == sent) { /* failed and no retry */ + if (NULL != msgw->cont) + msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, msgw->payload, 0); + 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", + GNUNET_STATISTICS_set (plugin->env->stats, "# bytes currently in UNIX buffers", plugin->bytes_in_queue, GNUNET_NO); plugin->bytes_discarded += msgw->msgsize; GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes discarded", @@ -965,25 +971,26 @@ unix_plugin_select_write (struct Plugin * plugin) GNUNET_free (msgw); return; } - - if (sent > 0) + else if (sent > 0) { /* successfully sent bytes */ + if (NULL != msgw->cont) + msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_OK, msgw->payload, msgw->msgsize); + 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", + GNUNET_STATISTICS_set (plugin->env->stats,"# bytes currently in UNIX buffers", plugin->bytes_in_queue, GNUNET_NO); plugin->bytes_in_sent += msgw->msgsize; - GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes sent", + GNUNET_STATISTICS_set (plugin->env->stats,"# bytes transmitted via UNIX", plugin->bytes_in_sent, GNUNET_NO); GNUNET_free (msgw->msg); GNUNET_free (msgw); return; } - } @@ -1074,8 +1081,7 @@ unix_transport_server_start (void *cls) plugin->unix_sock.desc = NULL; return GNUNET_SYSERR; } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "unix", "Bound to `%s'\n", - &un.sun_path[0]); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", plugin->unix_socket_path); plugin->rs = GNUNET_NETWORK_fdset_create (); plugin->ws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_zero (plugin->rs); @@ -1108,7 +1114,7 @@ unix_transport_server_start (void *cls) static int unix_check_address (void *cls, const void *addr, size_t addrlen) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Informing transport service about my address `%s'\n", (char *) addr); return GNUNET_OK; @@ -1223,7 +1229,8 @@ address_notification (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) plugin->env->notify_address (plugin->env->cls, GNUNET_YES, plugin->unix_socket_path, - strlen (plugin->unix_socket_path) + 1); + strlen (plugin->unix_socket_path) + 1, + "unix"); } @@ -1237,15 +1244,14 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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); - + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Session %p was idle for %llu ms, disconnecting\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); /* call session destroy function */ disconnect_session(s); - } + /** * Start session timeout */ @@ -1254,15 +1260,15 @@ 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); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for session %p set to %llu ms\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } + /** * Increment session timeout due to activity */ @@ -1276,11 +1282,12 @@ reschedule_session_timeout (struct Session *s) 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); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout rescheduled for session %p set to %llu ms\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } + /** * Cancel timeout */ @@ -1293,18 +1300,12 @@ stop_session_timeout (struct Session *s) { 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); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout stopped for session %p canceled\n", + s, (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); } } - /** * The exported method. Makes the core api available via a global and * returns the unix transport API. @@ -1353,9 +1354,9 @@ libgnunet_plugin_transport_unix_init (void *cls) 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")); + LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UNIX sockets\n")); - plugin->session_map = GNUNET_CONTAINER_multihashmap_create(10); + plugin->session_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); GNUNET_SCHEDULER_add_now (address_notification, plugin); return api; @@ -1372,11 +1373,19 @@ libgnunet_plugin_transport_unix_done (void *cls) GNUNET_free (api); return NULL; } + + plugin->env->notify_address (plugin->env->cls, GNUNET_NO, + plugin->unix_socket_path, + strlen (plugin->unix_socket_path) + 1, + "unix"); + unix_transport_server_stop (plugin); + GNUNET_CONTAINER_multihashmap_iterate (plugin->session_map, &get_session_delete_it, plugin); GNUNET_CONTAINER_multihashmap_destroy (plugin->session_map); + if (NULL != plugin->rs) GNUNET_NETWORK_fdset_destroy (plugin->rs); if (NULL != plugin->ws) diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index aed4b22..5fed7a7 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -152,6 +152,11 @@ struct PendingMessage */ struct Session { + /** + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) + */ + struct GNUNET_PeerIdentity target; /** * API requirement (must be first). @@ -186,12 +191,6 @@ struct Session struct PendingMessage *pending_message_tail; /** - * To whom are we talking to (set to our identity - * if we are still waiting for the welcome message) - */ - struct GNUNET_PeerIdentity target; - - /** * When should this session time out? */ struct GNUNET_TIME_Absolute timeout; @@ -261,6 +260,16 @@ struct FragmentMessage */ void *cont_cls; + /** + * Size of original message + */ + size_t size_payload; + + /** + * Number of bytes used to transmit message + */ + size_t size_on_wire; + }; @@ -331,6 +340,16 @@ struct MacEndpoint struct GNUNET_TRANSPORT_WLAN_MacAddress addr; /** + * Message delay for fragmentation context + */ + struct GNUNET_TIME_Relative msg_delay; + + /** + * ACK delay for fragmentation context + */ + struct GNUNET_TIME_Relative ack_delay; + + /** * Desired transmission power for this MAC */ uint16_t tx_power; @@ -707,6 +726,7 @@ fragment_transmission_done (void *cls, { struct FragmentMessage *fm = cls; + fm->sh = NULL; GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); } @@ -745,11 +765,18 @@ transmit_fragment (void *cls, &radio_header->header, GNUNET_NO, &fragment_transmission_done, fm); + fm->size_on_wire += size; 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); + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, + "# bytes currently in WLAN buffers", + -msize, GNUNET_NO); + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, + "# bytes transmitted via WLAN", + msize, GNUNET_NO); } } @@ -773,7 +800,9 @@ free_fragment_message (struct FragmentMessage *fm) GNUNET_HELPER_send_cancel (fm->sh); fm->sh = NULL; } - GNUNET_FRAGMENT_context_destroy (fm->fragcontext); + GNUNET_FRAGMENT_context_destroy (fm->fragcontext, + &endpoint->msg_delay, + &endpoint->ack_delay); if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (fm->timeout_task); @@ -798,7 +827,7 @@ fragmentmessage_timeout (void *cls, fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; if (NULL != fm->cont) { - fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR); + fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR, fm->size_payload, fm->size_on_wire); fm->cont = NULL; } free_fragment_message (fm); @@ -812,6 +841,7 @@ fragmentmessage_timeout (void *cls, * @param timeout how long can the message wait? * @param target peer that should receive the message * @param msg message to transmit + * @param payload_size bytes of payload * @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 @@ -823,6 +853,7 @@ send_with_fragmentation (struct MacEndpoint *endpoint, struct GNUNET_TIME_Relative timeout, const struct GNUNET_PeerIdentity *target, const struct GNUNET_MessageHeader *msg, + size_t payload_size, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) { @@ -833,13 +864,17 @@ send_with_fragmentation (struct MacEndpoint *endpoint, fm = GNUNET_malloc (sizeof (struct FragmentMessage)); fm->macendpoint = endpoint; fm->target = *target; + fm->size_payload = payload_size; + fm->size_on_wire = 0; fm->timeout = GNUNET_TIME_relative_to_absolute (timeout); fm->cont = cont; fm->cont_cls = cont_cls; + /* 1 MBit/s typical data rate, 1430 byte fragments => ~100 ms per message */ fm->fragcontext = GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, &plugin->tracker, - GNUNET_TIME_UNIT_SECONDS, + endpoint->msg_delay, + endpoint->ack_delay, msg, &transmit_fragment, fm); fm->timeout_task = @@ -939,6 +974,10 @@ create_macendpoint (struct Plugin *plugin, pos, &wlan_data_message_handler, &send_ack); + + pos->msg_delay = GNUNET_TIME_UNIT_MILLISECONDS; + pos->ack_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, + 100); pos->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT); pos->timeout_task = GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, @@ -1064,10 +1103,16 @@ wlan_plugin_send (void *cls, wlanheader->target = session->target; wlanheader->crc = htonl (GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size)); memcpy (&wlanheader[1], msgbuf, msgbuf_size); + + GNUNET_STATISTICS_update (plugin->env->stats, + "# bytes currently in WLAN buffers", + msgbuf_size, GNUNET_NO); + send_with_fragmentation (session->mac, to, &session->target, &wlanheader->header, + msgbuf_size, cont, cont_cls); return size; } @@ -1100,6 +1145,11 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); ats[1].value = htonl (GNUNET_ATS_NET_WLAN); msize = ntohs (hdr->size); + + GNUNET_STATISTICS_update (plugin->env->stats, + "# bytes received via WLAN", + msize, GNUNET_NO); + switch (ntohs (hdr->type)) { case GNUNET_MESSAGE_TYPE_HELLO: @@ -1161,7 +1211,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) 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 (fm->cont_cls, &fm->target, GNUNET_OK, fm->size_payload, fm->size_on_wire); fm->cont = NULL; } free_fragment_message (fm); @@ -1286,7 +1336,8 @@ handle_helper_message (void *cls, void *client, /* remove old address */ plugin->env->notify_address (plugin->env->cls, GNUNET_NO, &plugin->mac_address, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress), + "wlan"); } plugin->mac_address = cm->mac; plugin->have_mac = GNUNET_YES; @@ -1296,7 +1347,8 @@ handle_helper_message (void *cls, void *client, GNUNET_i2s (plugin->env->my_identity)); plugin->env->notify_address (plugin->env->cls, GNUNET_YES, &plugin->mac_address, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress), + "wlan"); break; case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER: LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -1476,7 +1528,7 @@ wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) return NULL; } mac = addr; - return GNUNET_strdup (mac_to_string (mac)); + return mac_to_string (mac); } @@ -1538,6 +1590,16 @@ libgnunet_plugin_transport_wlan_done (void *cls) GNUNET_free (api); return NULL; } + + if (GNUNET_YES == plugin->have_mac) + { + plugin->env->notify_address (plugin->env->cls, GNUNET_NO, + &plugin->mac_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress), + "wlan"); + plugin->have_mac = GNUNET_NO; + } + if (GNUNET_SCHEDULER_NO_TASK != plugin->beacon_task) { GNUNET_SCHEDULER_cancel (plugin->beacon_task); @@ -1641,6 +1703,7 @@ libgnunet_plugin_transport_wlan_init (void *cls) struct Plugin *plugin; char *interface; unsigned long long testmode; + char *binary; /* check for 'special' mode */ if (NULL == env->receive) @@ -1663,30 +1726,29 @@ libgnunet_plugin_transport_wlan_init (void *cls) 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"); + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "transport-wlan", "TESTMODE"); return NULL; } + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-transport-wlan"); if ( (0 == testmode) && - (GNUNET_YES != GNUNET_OS_check_helper_binary ("gnunet-helper-transport-wlan")) ) + (GNUNET_YES != GNUNET_OS_check_helper_binary (binary)) ) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Helper binary `%s' not SUID, cannot run WLAN transport\n"), "gnunet-helper-transport-wlan"); + GNUNET_free (binary); return NULL; } + GNUNET_free (binary); 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"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "transport-wlan", "INTERFACE"); return NULL; } @@ -1705,33 +1767,40 @@ libgnunet_plugin_transport_wlan_init (void *cls) plugin->helper_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); plugin->beacon_task = GNUNET_SCHEDULER_add_now (&send_hello_beacon, plugin); - switch (testmode) + /* some compilers do not like switch on 'long long'... */ + switch ((unsigned int) 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->suid_helper = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-transport-wlan", plugin->helper_argv, &handle_helper_message, + NULL, 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->suid_helper = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-transport-wlan-dummy", plugin->helper_argv, &handle_helper_message, + NULL, 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->suid_helper = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-transport-wlan-dummy", plugin->helper_argv, &handle_helper_message, + NULL, plugin); break; default: diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h index 2b70fc0..b7f22de 100644 --- a/src/transport/plugin_transport_wlan.h +++ b/src/transport/plugin_transport_wlan.h @@ -80,6 +80,29 @@ struct GNUNET_TRANSPORT_WLAN_HelperControlMessage struct GNUNET_TRANSPORT_WLAN_MacAddress mac; }; +/** + * generic definitions for IEEE 802.3 frames + */ +struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame +{ + + /** + * Address 1: destination address in ad-hoc mode or AP, BSSID if station, + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress dst; + + /** + * Address 2: source address if in ad-hoc-mode or station, BSSID if AP + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress src; + + /** + * Packet type ID. + */ + uint16_t type; + +}; + /** * generic definitions for IEEE 802.11 frames diff --git a/src/transport/template_cfg_peer1.conf b/src/transport/template_cfg_peer1.conf index 2b8e9b2..8856418 100644 --- a/src/transport/template_cfg_peer1.conf +++ b/src/transport/template_cfg_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ test_transport_defaults.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = template_cfg_peer1.conf [gnunetd] HOSTKEY = $SERVICEHOME/.hostkey @@ -40,13 +39,11 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] #PREFIX = valgrind --leak-check=full PORT = 12001 -#DEBUG = YES UNIXPATH = /tmp/gnunet-p1-service-transport.sock [ats] -#DEBUG = YES -WAN_QUOTA_IN = 1 GB -WAN_QUOTA_OUT = 1 GB +WAN_QUOTA_IN = unlimited +WAN_QUOTA_OUT = unlimited PORT = 12006 UNIXPATH = /tmp/gnunet-p1-service-ats.sock diff --git a/src/transport/template_cfg_peer2.conf b/src/transport/template_cfg_peer2.conf index 3b86137..54636ca 100644 --- a/src/transport/template_cfg_peer2.conf +++ b/src/transport/template_cfg_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ test_transport_defaults.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = template_cfg_peer2.conf [gnunetd] HOSTKEY = $SERVICEHOME/.hostkey @@ -44,9 +43,8 @@ PORT = 12010 UNIXPATH = /tmp/gnunet-p2-service-transport.sock [ats] -#DEBUG = YES -WAN_QUOTA_IN = 1 GB -WAN_QUOTA_OUT = 1 GB +WAN_QUOTA_IN = unlimited +WAN_QUOTA_OUT = unlimited PORT = 12016 UNIXPATH = /tmp/gnunet-p2-service-ats.sock diff --git a/src/transport/test_http_common.c b/src/transport/test_http_common.c new file mode 100644 index 0000000..c97ae17 --- /dev/null +++ b/src/transport/test_http_common.c @@ -0,0 +1,264 @@ +/* + 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 transport/test_http_common.c + * @brief base test case for common http functionality + */ +#include "platform.h" +#include "gnunet_transport_service.h" +#include "transport-testing.h" +#include "plugin_transport_http_common.h" + +struct SplittedHTTPAddress +{ + char *protocol; + char *host; + char *path; + int port; +}; + +void +clean (struct SplittedHTTPAddress *addr) +{ + if (NULL != addr) + { + GNUNET_free_non_null (addr->host); + GNUNET_free_non_null (addr->path); + GNUNET_free_non_null (addr->protocol); + GNUNET_free_non_null (addr); + } +} + + +int +check (struct SplittedHTTPAddress *addr, + char * protocol, + char * host, + int port, + char * path) +{ + + if (NULL == addr) + return GNUNET_NO; + if (((NULL == addr->protocol) && (NULL != protocol)) || + ((NULL != addr->protocol) && (NULL == protocol))) + { + GNUNET_break (0); + return GNUNET_NO; + } + else if ((NULL != addr->protocol) && (NULL != protocol)) + { + if (0 != strcmp(addr->protocol, protocol)) + { + GNUNET_break (0); + return GNUNET_NO; + } + } + + if (((NULL == addr->host) && (NULL != host)) || + ((NULL != addr->host) && (NULL == host))) + { + GNUNET_break (0); + return GNUNET_NO; + } + else if ((NULL != addr->host) && (NULL != host)) + { + if (0 != strcmp(addr->host, host)) + { + GNUNET_break (0); + return GNUNET_NO; + } + } + + + if (((NULL == addr->path) && (NULL != path)) || + ((NULL != addr->path) && (NULL == path))) + { + GNUNET_break (0); + return GNUNET_NO; + } + else if ((NULL != addr->path) && (NULL != path)) + { + if (0 != strcmp(addr->path, path)) + { + GNUNET_break (0); + return GNUNET_NO; + } + } + + if ((addr->port != port)) + { + GNUNET_break (0); + return GNUNET_NO; + } + + return GNUNET_OK; +} + +int +check_pass (char *src, + char * protocol, + char * host, + int port, + char * path) +{ + struct SplittedHTTPAddress * spa; + spa = http_split_address (src); + if (NULL == spa) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + else + { + if (GNUNET_OK != check(spa, protocol, host, port, path)) + { + clean (spa); + GNUNET_break (0); + return GNUNET_SYSERR; + } + clean (spa); + } + return GNUNET_OK; +} + +int +check_fail (char *src) +{ + struct SplittedHTTPAddress * spa; + spa = http_split_address (src); + if (NULL != spa) + { + GNUNET_break (0); + clean (spa); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +void +test_pass_hostname () +{ + check_pass("http://test.local", "http", "test.local", HTTP_DEFAULT_PORT, ""); + check_pass("http://test.local/", "http", "test.local", HTTP_DEFAULT_PORT, "/"); + check_pass("http://test.local/path", "http", "test.local", HTTP_DEFAULT_PORT, "/path"); + check_pass("http://test.local/path/", "http", "test.local", HTTP_DEFAULT_PORT, "/path/"); + check_pass("http://test.local/path/more", "http", "test.local", HTTP_DEFAULT_PORT, "/path/more"); + check_pass("http://test.local:81", "http", "test.local", 81, ""); + check_pass("http://test.local:81/", "http", "test.local", 81, "/"); + check_pass("http://test.local:81/path", "http", "test.local", 81, "/path"); + check_pass("http://test.local:81/path/", "http", "test.local", 81, "/path/"); + check_pass("http://test.local:81/path/more", "http", "test.local", 81, "/path/more"); + +} + + +void +test_pass_ipv4 () +{ + check_pass("http://127.0.0.1", "http", "127.0.0.1", HTTP_DEFAULT_PORT, ""); + check_pass("http://127.0.0.1/", "http", "127.0.0.1", HTTP_DEFAULT_PORT, "/"); + check_pass("http://127.0.0.1/path", "http", "127.0.0.1", HTTP_DEFAULT_PORT, "/path"); + check_pass("http://127.0.0.1/path/", "http", "127.0.0.1", HTTP_DEFAULT_PORT, "/path/"); + check_pass("http://127.0.0.1:81", "http", "127.0.0.1", 81, ""); + check_pass("http://127.0.0.1:81/", "http", "127.0.0.1", 81, "/"); + check_pass("http://127.0.0.1:81/path", "http", "127.0.0.1", 81, "/path"); + check_pass("http://127.0.0.1:81/path/", "http", "127.0.0.1", 81, "/path/"); + check_pass("http://127.0.0.1:81/path/more", "http", "127.0.0.1", 81, "/path/more"); +} + +void +test_fail_ipv6 () +{ + check_pass("http://[::1]", "http", "[::1]", HTTP_DEFAULT_PORT, ""); + check_pass("http://[::1]/", "http", "[::1]", HTTP_DEFAULT_PORT, "/"); + check_pass("http://[::1]/path", "http", "[::1]", HTTP_DEFAULT_PORT, "/path"); + check_pass("http://[::1]/path/", "http", "[::1]", HTTP_DEFAULT_PORT, "/path/"); + check_pass("http://[::1]:81", "http", "[::1]", 81, ""); + check_pass("http://[::1]:81/", "http", "[::1]", 81, "/"); + check_pass("http://[::1]:81/path", "http", "[::1]", 81, "/path"); + check_pass("http://[::1]:81/path/", "http", "[::1]", 81, "/path/"); + check_pass("http://[::1]:81/path/more", "http", "[::1]", 81, "/path/more"); +} + + +void +test_fail () +{ + if (GNUNET_SYSERR == check_fail ("")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("http")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("://")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("http://")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("//localhost")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("//:80")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("//:80/")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("//:80:")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("http://localhost:a/")) + GNUNET_break (0); + if (GNUNET_SYSERR == check_fail ("http://127.0.0.1:a/")) + GNUNET_break (0); +} + +int +main (int argc, char *argv[]) +{ + int ret = 0; + struct SplittedHTTPAddress * spa; + GNUNET_log_setup ("test", "DEBUG", NULL); + + spa = http_split_address (""); + if (NULL != spa) + { + clean (spa); + GNUNET_break (0); + } + + http_split_address ("http://"); + if (NULL != spa) + { + clean (spa); + GNUNET_break (0); + } + + http_split_address ("://"); + if (NULL != spa) + { + clean (spa); + GNUNET_break (0); + } + + test_pass_hostname (); + test_pass_ipv4 (); + test_fail_ipv6 (); + test_fail (); + + return ret; +} + +/* end of test_http_common.c */ diff --git a/src/transport/test_plugin_hostkey b/src/transport/test_plugin_hostkey Binary files differnew file mode 100644 index 0000000..13f1dc9 --- /dev/null +++ b/src/transport/test_plugin_hostkey diff --git a/src/transport/test_plugin_hostkey.ecc b/src/transport/test_plugin_hostkey.ecc Binary files differnew file mode 100644 index 0000000..c56a08e --- /dev/null +++ b/src/transport/test_plugin_hostkey.ecc diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c new file mode 100644 index 0000000..f0dbc41 --- /dev/null +++ b/src/transport/test_plugin_transport.c @@ -0,0 +1,728 @@ +/* + 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 transport/test_plugin_transport.c + * @brief testcase for transport_api.c + * @author Sailor Siraj + * @author Christian Grothoff + */ + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_constants.h" +#include "gnunet_util_lib.h" +#include "gnunet_hello_lib.h" +#include "gnunet_peerinfo_service.h" +#include "gnunet_statistics_service.h" +#include "gnunet_protocols.h" +#include "gnunet_signatures.h" +#include "gnunet_transport_plugin.h" + +#include "transport.h" + +/** + * How long until we give up on transmitting the message? + */ +#define WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +#define HOSTKEY_FILE "test_plugin_hostkey" + +/** + * Our public key. + */ +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; + +/** + * Our identity. + */ +static struct GNUNET_PeerIdentity my_identity; + +/** + * Our private key. + */ +static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; + +/** + * Our configuration. + */ +const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Our configuration. + */ +struct GNUNET_STATISTICS_Handle *stats; + +/** + * Our HELLO + */ +struct GNUNET_HELLO_Message *hello; + +/** + * Number of neighbours we'd like to have. + */ +static uint32_t max_connect_per_transport; + +/** + * Environment for this plugin. + */ +struct GNUNET_TRANSPORT_PluginEnvironment env; + +/** + *handle for the api provided by this plugin + */ +struct GNUNET_TRANSPORT_PluginFunctions *api; + +/** + * Helper handler + */ +struct GNUNET_HELPER_Handle *suid_helper; + +/** + * Timeout task + */ +static GNUNET_SCHEDULER_TaskIdentifier timeout_endbadly; + +/** + * Timeout task + */ +static GNUNET_SCHEDULER_TaskIdentifier timeout_wait; + +/** + * Library name + */ +static char *libname; + +/** + * Plugin addresses head + */ +struct AddressWrapper *head; + +/** + * Plugin addresses tail + */ +struct AddressWrapper *tail; + +unsigned int addresses_reported; + +unsigned int pretty_printers_running; + +/** + * Did the test pass or fail? + */ +static int ok; + + +struct AddressWrapper +{ + struct AddressWrapper *next; + + struct AddressWrapper *prev; + + void *addr; + + size_t addrlen; + + char *addrstring; +}; + + +static void +end () +{ + struct AddressWrapper *w; + int c = 0; + ok = 0; + + if (GNUNET_SCHEDULER_NO_TASK != timeout_endbadly) + { + GNUNET_SCHEDULER_cancel (timeout_endbadly); + timeout_endbadly = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != api) + GNUNET_PLUGIN_unload (libname, api); + + while (NULL != head) + { + w = head; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin did not remove address `%s' \n"), w->addrstring); + GNUNET_CONTAINER_DLL_remove (head, tail, w); + c ++; + GNUNET_free (w->addr); + GNUNET_free (w->addrstring); + GNUNET_free (w); + } + if (c > 0) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin did not remove %u addresses \n"), c); + ok = 1; + } + + + GNUNET_free (libname); + libname = NULL; + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; + + if (NULL != suid_helper) + { + GNUNET_HELPER_stop (suid_helper); + suid_helper = NULL; + } +} + + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct AddressWrapper *w; + int c = 0; + timeout_endbadly = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_SCHEDULER_NO_TASK != timeout_wait) + { + GNUNET_SCHEDULER_cancel (timeout_wait); + timeout_wait = GNUNET_SCHEDULER_NO_TASK; + } + + if (pretty_printers_running > 0) + { + timeout_endbadly = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS, &end_badly, &ok); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Have pending calls to pretty_printer ... deferring shutdown\n")); + return; + } + + if (NULL != cls) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Test took too long to execute, timeout .... \n")); + } + + if (NULL != libname) + { + if (NULL != api) + GNUNET_PLUGIN_unload (libname, api); + GNUNET_free (libname); + libname = NULL; + } + + while (NULL != head) + { + w = head; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin did not remove address `%s' \n"), w->addrstring); + GNUNET_CONTAINER_DLL_remove (head, tail, w); + c ++; + GNUNET_free (w->addr); + GNUNET_free (w->addrstring); + GNUNET_free (w); + } + if (c > 0) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin did not remove %u addresses \n"), c); + } + + if (NULL != stats) + { + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; + } + + if (NULL != suid_helper) + { + GNUNET_HELPER_stop (suid_helper); + suid_helper = NULL; + } + + ok = 1; +} + + +static void +wait_end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + timeout_wait = GNUNET_SCHEDULER_NO_TASK; + if (0 == addresses_reported) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Plugin did not report any addresses, could not check address conversion functions\n")); + end (); +} + + +static void +end_badly_now () +{ + if (GNUNET_SCHEDULER_NO_TASK != timeout_wait) + { + GNUNET_SCHEDULER_cancel (timeout_wait); + timeout_wait = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != timeout_endbadly) + { + GNUNET_SCHEDULER_cancel (timeout_endbadly); + timeout_endbadly = GNUNET_SCHEDULER_NO_TASK; + } + timeout_endbadly = GNUNET_SCHEDULER_add_now (&end_badly, NULL); +} + + +static struct GNUNET_TIME_Relative +env_receive (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, + struct Session * session, + const char *sender_address, + uint16_t sender_address_len) +{ + /* do nothing */ + return GNUNET_TIME_relative_get_zero_(); +} + + +static int got_reply; + + +/** + * Take the given address and append it to the set of results sent back to + * the client. + * + * @param cls the transmission context used ('struct GNUNET_SERVER_TransmitContext*') + * @param buf text to transmit + */ +static void +address_pretty_printer_cb (void *cls, const char *buf) +{ + if (NULL != buf) + { + got_reply = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Pretty address : `%s'\n", buf); + pretty_printers_running --; + } + else + { + if (GNUNET_NO == got_reply) + { + pretty_printers_running --; + GNUNET_break (0); + end_badly_now (); + } + } +} + + +static void +env_notify_address (void *cls, + int add_remove, + const void *addr, + size_t addrlen, + const char *plugin) +{ + struct AddressWrapper *w; + char *a2s; + void *s2a; + size_t s2a_len; + + if (GNUNET_YES == add_remove) + { + addresses_reported ++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Adding address of length %u\n"), addrlen); + + w = GNUNET_malloc (sizeof (struct AddressWrapper)); + w->addr = GNUNET_malloc (addrlen); + w->addrlen = addrlen; + memcpy (w->addr, addr, addrlen); + GNUNET_CONTAINER_DLL_insert(head, tail, w); + got_reply = GNUNET_NO; + pretty_printers_running ++; + api->address_pretty_printer (api->cls, plugin, addr, addrlen, + GNUNET_YES, GNUNET_TIME_UNIT_MINUTES, + &address_pretty_printer_cb, + w); + + a2s = strdup (api->address_to_string (api, w->addr, w->addrlen)); + if (NULL == a2s) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin cannot convert address to string!\n")); + end_badly_now(); + return; + } + w->addrstring = strdup (api->address_to_string (api, w->addr, w->addrlen)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Plugin added address `%s'\n"), a2s); + + if ((GNUNET_OK != api->string_to_address (api, a2s, strlen (a2s)+1, &s2a, &s2a_len)) || (NULL == s2a)) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin cannot convert string to address!\n")); + end_badly_now(); + return; + } + + if (s2a_len != w->addrlen) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin creates different address length when converting address->string->address: %u != %u\n"), w->addrlen, s2a_len); + } + else + { + if (0 != memcmp (s2a, w->addr, s2a_len)) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin creates different address length when connecting back and forth!\n")); + } + GNUNET_free (s2a); + GNUNET_free (a2s); + if (GNUNET_OK != api->check_address (api->cls, w->addr, w->addrlen)) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin refuses added address!\n")); + end_badly_now(); + return; + } + if (GNUNET_SCHEDULER_NO_TASK != timeout_wait) + { + GNUNET_SCHEDULER_cancel (timeout_wait); + timeout_wait = GNUNET_SCHEDULER_NO_TASK; + } + + timeout_wait = GNUNET_SCHEDULER_add_delayed (WAIT, &wait_end, NULL); + + } + else if (GNUNET_NO == add_remove) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Removing address of length %u\n"), addrlen); + + w = head; + while (NULL != w) + { + if ((addrlen == w->addrlen) && (0 == memcmp (w->addr, addr, addrlen))) + { + break; + } + w = w->next; + } + + if (w == NULL) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin removes address never added!\n")); + end_badly_now(); + return; + } + + GNUNET_CONTAINER_DLL_remove (head, tail, w); + GNUNET_free (w->addr); + GNUNET_free (w->addrstring); + GNUNET_free (w); + } + else + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Invalid operation: %u \n"), add_remove); + end_badly_now (); + return; + } +} + + +static struct GNUNET_ATS_Information +env_get_address_type (void *cls, + const struct sockaddr *addr, + size_t addrlen) +{ + struct GNUNET_ATS_Information ats; + ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); + ats.value = htonl (GNUNET_ATS_NET_LOOPBACK); + return ats; +} + + +static const struct GNUNET_MessageHeader * +env_get_our_hello () +{ + return (const struct GNUNET_MessageHeader *) hello; +} + + +static void +env_session_end (void *cls, + const struct GNUNET_PeerIdentity *peer, + struct Session * session) +{ +} + + +static void +setup_plugin_environment () +{ + env.cfg = cfg; + env.cls = &env; + env.my_identity = &my_identity; + env.max_connections = max_connect_per_transport; + env.stats = stats; + + env.receive = &env_receive; + env.notify_address = &env_notify_address; + env.get_address_type = &env_get_address_type; + env.get_our_hello = &env_get_our_hello; + env.session_end = &env_session_end; +} + +static int +handle_helper_message (void *cls, void *client, + const struct GNUNET_MessageHeader *hdr) +{ + return GNUNET_OK; +} + + +/** + * Runs the test. + * + * @param cls closure + * @param c configuration to use + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + char *const *argv = cls; + unsigned long long tneigh; + char *keyfile; + char *plugin; + char *sep; + + timeout_endbadly = GNUNET_SCHEDULER_add_delayed (TIMEOUT, end_badly, &ok); + + cfg = c; + /* parse configuration */ + if ( (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, + "TRANSPORT", + "NEIGHBOUR_LIMIT", + &tneigh)) || + (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, + "GNUNETD", "HOSTKEY", + &keyfile))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Transport service is lacking key configuration settings. Exiting.\n")); + return; + } + + if (NULL == (stats = GNUNET_STATISTICS_create ("transport", cfg))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not create statistics. Exiting.\n")); + end_badly_now (); + return; + } + + if (GNUNET_OK != GNUNET_DISK_file_test (HOSTKEY_FILE)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Hostkey `%s' missing. Exiting.\n"), + HOSTKEY_FILE); + } + + if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (keyfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not create a directory for hostkey `%s'. Exiting.\n"), + keyfile); + end_badly_now (); + return; + } + + if (GNUNET_OK != GNUNET_DISK_file_copy (HOSTKEY_FILE, keyfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not copy hostkey `%s' to destination `%s'. Exiting.\n"), + HOSTKEY_FILE, keyfile); + end_badly_now (); + return; + } + + + max_connect_per_transport = (uint32_t) tneigh; + my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + GNUNET_free (keyfile); + if (NULL == my_private_key) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Transport service could not access hostkey. Exiting.\n")); + end_badly_now (); + return; + } + GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); + GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), + &my_identity.hashPubKey); + + + hello = GNUNET_HELLO_create(&my_public_key, NULL, NULL); + + /* load plugins... */ + setup_plugin_environment (); + + GNUNET_assert (strlen (argv[0]) > strlen ("test_plugin_")); + plugin = strstr(argv[0],"test_plugin_"); + sep = strrchr(argv[0],'.'); + if (NULL == plugin) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Not a valid test name\n")); + end_badly_now (); + return; + } + plugin += strlen ("test_plugin_"); + if (NULL != sep) + sep[0] = '\0'; + + /* Hack for WLAN: start a second helper */ + if (0 == strcmp (plugin, "wlan")) + { + char * helper_argv[3]; + helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy"; + helper_argv[1] = (char *) "2"; + helper_argv[2] = NULL; + suid_helper = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-transport-wlan-dummy", + helper_argv, + &handle_helper_message, + NULL, + NULL); + } + + /* Loading plugin */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading transport plugin %s\n"), plugin); + GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", plugin); + api = GNUNET_PLUGIN_load (libname, &env); + if (api == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to load transport plugin for %s\n"), plugin); + end_badly_now (); + return; + } + + timeout_wait = GNUNET_SCHEDULER_add_delayed (WAIT, &wait_end, NULL); + + /* Check if all functions are implemented */ + if (NULL == api->address_pretty_printer) + { + GNUNET_break (0); + end_badly_now (); + return; + } + if (NULL == api->address_to_string) + { + GNUNET_break (0); + end_badly_now (); + return; + } + GNUNET_assert (NULL != api->check_address); + if (NULL == api->check_address) + { + GNUNET_break (0); + end_badly_now (); + return; + } + GNUNET_assert (NULL != api->disconnect); + if (NULL == api->disconnect) + { + GNUNET_break (0); + end_badly_now (); + return; + } + GNUNET_assert (NULL != api->get_session); + if (NULL == api->get_session) + { + GNUNET_break (0); + end_badly_now (); + return; + } + if (NULL == api->address_pretty_printer) + { + GNUNET_break (0); + end_badly_now (); + return; + } + if (NULL == api->string_to_address) + { + GNUNET_break (0); + end_badly_now (); + return; + } + +} + + +/** + * The main function for the test + * + * @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 struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + int ret; + + GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport"); + + char *const argv_prog[] = { + "test_plugin_transport", + "-c", + "test_plugin_transport_data.conf", + NULL + }; + GNUNET_log_setup ("test-plugin-transport", + "WARNING", + NULL); + ok = 1; /* set to fail */ + ret = (GNUNET_OK == GNUNET_PROGRAM_run (3, + argv_prog, + "test-plugin-transport", + "testcase", + options, + &run, + (void *) argv)) ? ok : 1; + GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport"); + return ret; +} + +/* end of test_plugin_transport.c */ diff --git a/src/transport/test_plugin_transport_data.conf b/src/transport/test_plugin_transport_data.conf index adc7a59..189238c 100644 --- a/src/transport/test_plugin_transport_data.conf +++ b/src/transport/test_plugin_transport_data.conf @@ -1,25 +1,49 @@ @INLINE@ test_transport_defaults.conf [PATHS] SERVICEHOME = /tmp/test-gnunetd-plugin-transport/ -DEFAULTCONFIG = test_plugin_transport_data.conf [transport-tcp] -PORT = 2368 -TIMEOUT = 5 s +PORT = 2400 + +[transport-udp] +PORT = 2401 + +[transport-unix] + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 1 + +[transport-http_client] + +[transport-http_server] +PORT = 2402 + +[transport-https_client] + +[transport-https_server] +PORT = 2403 [arm] -PORT = 2366 +PORT = 2360 +UNIXPATH = /tmp/gnunet-service-arm.sock [statistics] -PORT = 2367 +PORT = 2361 +UNIXPATH = /tmp/gnunet-service-statistics.sock [resolver] -PORT = 2364 +PORT = 2362 +UNIXPATH = /tmp/gnunet-service-resolver.sock [peerinfo] -PORT = 2369 +PORT = 2363 +UNIXPATH = /tmp/gnunet-service-peerinfo.sock [transport] -PORT = 2365 - +PORT = 2364 +UNIXPATH = /tmp/gnunet-service-transport.sock +[nat] +RETURN_LOCAL_ADDRESSES = YES +DISABLEV6 = NO diff --git a/src/transport/test_quota_compliance.c b/src/transport/test_quota_compliance.c index 8f4db53..7f0247e 100644 --- a/src/transport/test_quota_compliance.c +++ b/src/transport/test_quota_compliance.c @@ -24,24 +24,11 @@ * This test case tests quota compliance both on transport level */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_os_lib.h" -#include "gnunet_program_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" #include "gnunet_transport_service.h" +#include "gnunet_ats_service.h" #include "gauger.h" -#include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES - /** * Testcase timeout */ @@ -60,8 +47,6 @@ static char *test_plugin; static char *test_name; -static int ok; - static GNUNET_SCHEDULER_TaskIdentifier die_task; static GNUNET_SCHEDULER_TaskIdentifier measure_task; @@ -212,7 +197,7 @@ end_badly () if (p2 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); - ok = GNUNET_SYSERR; + test_failed = GNUNET_YES; } @@ -311,7 +296,7 @@ notify_ready (void *cls, size_t size, void *buf) if (GNUNET_SCHEDULER_NO_TASK != die_task) GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); - ok = 42; + test_failed = 1; return 0; } @@ -466,11 +451,10 @@ start_cb (struct PeerContext *p, void *cls) receiver = p1; char *sender_c = GNUNET_strdup (GNUNET_i2s (&sender->id)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test tries to send from %u (%s) -> peer %u (%s)\n", sender->no, sender_c, receiver->no, GNUNET_i2s (&receiver->id)); - + GNUNET_free (sender_c); cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb, NULL); @@ -480,16 +464,28 @@ static char * generate_config (char *cfg_file, unsigned long long quota_in, unsigned long long quota_out) { + char *networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString; + char *in_name; + char *out_name; char *fname = NULL; struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); + int c; GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, cfg_file)); GNUNET_asprintf (&fname, "q_in_%llu_q_out_%llu_%s", quota_in, quota_out, cfg_file); + GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", fname); - GNUNET_CONFIGURATION_set_value_number (cfg, "ats", "WAN_QUOTA_IN", quota_in); - GNUNET_CONFIGURATION_set_value_number (cfg, "ats", "WAN_QUOTA_OUT", - quota_out); + + for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) + { + GNUNET_asprintf (&in_name, "%s_QUOTA_IN", networks[c]); + GNUNET_asprintf (&out_name, "%s_QUOTA_OUT", networks[c]); + GNUNET_CONFIGURATION_set_value_number (cfg, "ats", in_name, quota_in); + GNUNET_CONFIGURATION_set_value_number (cfg, "ats", out_name, quota_out); + GNUNET_free (in_name); + GNUNET_free (out_name); + } GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_write (cfg, fname)); GNUNET_CONFIGURATION_destroy (cfg); return fname; @@ -564,20 +560,15 @@ check () static char *argv[] = { "test_transport-quota-compliance", "-c", "test_quota_compliance_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; - ok = 1; GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, - "nohelp", options, &run, &ok); - - return ok; + "nohelp", options, &run, NULL); + return test_failed; } int @@ -586,11 +577,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_quota_compliance_data.conf b/src/transport/test_quota_compliance_data.conf index 93f75dd..b0fb0e0 100644 --- a/src/transport/test_quota_compliance_data.conf +++ b/src/transport/test_quota_compliance_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_transport_defaults.conf [PATHS] SERVICEHOME = /tmp/test-gnunetd-plugin-transport/ -DEFAULTCONFIG = test_quota_compliance_data.conf [transport-tcp] PORT = 2368 diff --git a/src/transport/test_quota_compliance_http_asymmetric_peer1.conf b/src/transport/test_quota_compliance_http_asymmetric_peer1.conf index f56b157..885bcba 100644 --- a/src/transport/test_quota_compliance_http_asymmetric_peer1.conf +++ b/src/transport/test_quota_compliance_http_asymmetric_peer1.conf @@ -1,10 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1 -DEFAULTCONFIG = test_quota_compliance_http_peer1.conf -[transport-http] -PORT = 4010 +[transport-http_client] [arm] PORT = 4015 @@ -24,7 +22,7 @@ UNIXPATH = /tmp/test_quota_compliance_http_peerinfo_peer1.sock [transport] PORT = 4011 -PLUGINS = http +PLUGINS = http_client UNIXPATH = /tmp/test_quota_compliance_http_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_http_asymmetric_peer2.conf b/src/transport/test_quota_compliance_http_asymmetric_peer2.conf index 20ef582..33f8be5 100644 --- a/src/transport/test_quota_compliance_http_asymmetric_peer2.conf +++ b/src/transport/test_quota_compliance_http_asymmetric_peer2.conf @@ -1,10 +1,12 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_http_peer2.conf -[transport-http] +[transport-http_server] PORT = 3010 +USE_IPv6 = NO +BINDTO = 127.0.0.1 + [arm] PORT = 3015 @@ -24,7 +26,7 @@ UNIXPATH = /tmp/test_quota_compliance_http_peerinfo_peer2.sock [transport] PORT = 3011 -PLUGINS = http +PLUGINS = http_server UNIXPATH = /tmp/test_quota_compliance_http_transport_peer2.sock diff --git a/src/transport/test_quota_compliance_http_peer1.conf b/src/transport/test_quota_compliance_http_peer1.conf index f56b157..885bcba 100644 --- a/src/transport/test_quota_compliance_http_peer1.conf +++ b/src/transport/test_quota_compliance_http_peer1.conf @@ -1,10 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1 -DEFAULTCONFIG = test_quota_compliance_http_peer1.conf -[transport-http] -PORT = 4010 +[transport-http_client] [arm] PORT = 4015 @@ -24,7 +22,7 @@ UNIXPATH = /tmp/test_quota_compliance_http_peerinfo_peer1.sock [transport] PORT = 4011 -PLUGINS = http +PLUGINS = http_client UNIXPATH = /tmp/test_quota_compliance_http_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_http_peer2.conf b/src/transport/test_quota_compliance_http_peer2.conf index 20ef582..33f8be5 100644 --- a/src/transport/test_quota_compliance_http_peer2.conf +++ b/src/transport/test_quota_compliance_http_peer2.conf @@ -1,10 +1,12 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_http_peer2.conf -[transport-http] +[transport-http_server] PORT = 3010 +USE_IPv6 = NO +BINDTO = 127.0.0.1 + [arm] PORT = 3015 @@ -24,7 +26,7 @@ UNIXPATH = /tmp/test_quota_compliance_http_peerinfo_peer2.sock [transport] PORT = 3011 -PLUGINS = http +PLUGINS = http_server UNIXPATH = /tmp/test_quota_compliance_http_transport_peer2.sock diff --git a/src/transport/test_quota_compliance_https_asymmetric_peer1.conf b/src/transport/test_quota_compliance_https_asymmetric_peer1.conf index ad4aab0..271bbe0 100644 --- a/src/transport/test_quota_compliance_https_asymmetric_peer1.conf +++ b/src/transport/test_quota_compliance_https_asymmetric_peer1.conf @@ -1,12 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1/ -DEFAULTCONFIG = test_quota_compliance_https_peer1.conf -[transport-https] -PORT = 4001 -KEY_FILE = https_key_quota_p1.key -CERT_FILE = https_cert_quota_p1.crt +[transport-https_client] [arm] PORT = 4006 @@ -26,7 +22,7 @@ UNIXPATH = /tmp/test_quota_compliance_https_peerinfo_peer1.sock [transport] PORT = 4002 -PLUGINS = https +PLUGINS = https_client UNIXPATH = /tmp/test_quota_compliance_https_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_https_asymmetric_peer2.conf b/src/transport/test_quota_compliance_https_asymmetric_peer2.conf index 94d7412..8e07ff3 100644 --- a/src/transport/test_quota_compliance_https_asymmetric_peer2.conf +++ b/src/transport/test_quota_compliance_https_asymmetric_peer2.conf @@ -1,9 +1,8 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_https_peer2.conf -[transport-https] +[transport-https_server] PORT = 3001 KEY_FILE = https_key_quota_p2.key CERT_FILE = https_cert_qutoa_p2.crt @@ -26,7 +25,7 @@ UNIXPATH = /tmp/test_quota_compliance_https_peerinfo_peer2.sock [transport] PORT = 3002 -PLUGINS = https +PLUGINS = https_server UNIXPATH = /tmp/https_transport_peer2.sock diff --git a/src/transport/test_quota_compliance_https_peer1.conf b/src/transport/test_quota_compliance_https_peer1.conf index ad4aab0..271bbe0 100644 --- a/src/transport/test_quota_compliance_https_peer1.conf +++ b/src/transport/test_quota_compliance_https_peer1.conf @@ -1,12 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1/ -DEFAULTCONFIG = test_quota_compliance_https_peer1.conf -[transport-https] -PORT = 4001 -KEY_FILE = https_key_quota_p1.key -CERT_FILE = https_cert_quota_p1.crt +[transport-https_client] [arm] PORT = 4006 @@ -26,7 +22,7 @@ UNIXPATH = /tmp/test_quota_compliance_https_peerinfo_peer1.sock [transport] PORT = 4002 -PLUGINS = https +PLUGINS = https_client UNIXPATH = /tmp/test_quota_compliance_https_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_https_peer2.conf b/src/transport/test_quota_compliance_https_peer2.conf index 94d7412..8e07ff3 100644 --- a/src/transport/test_quota_compliance_https_peer2.conf +++ b/src/transport/test_quota_compliance_https_peer2.conf @@ -1,9 +1,8 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_https_peer2.conf -[transport-https] +[transport-https_server] PORT = 3001 KEY_FILE = https_key_quota_p2.key CERT_FILE = https_cert_qutoa_p2.crt @@ -26,7 +25,7 @@ UNIXPATH = /tmp/test_quota_compliance_https_peerinfo_peer2.sock [transport] PORT = 3002 -PLUGINS = https +PLUGINS = https_server UNIXPATH = /tmp/https_transport_peer2.sock diff --git a/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf b/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf index 8a1dad5..b7eb287 100644 --- a/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf +++ b/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/quota-tcp-p1/ -DEFAULTCONFIG = test_quota_compliance_tcp_asymmetric_peer1.conf [transport-tcp] PORT = 4094 diff --git a/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf b/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf index bbfa8ec..cc949df 100644 --- a/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf +++ b/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/quota-tcp-p2/ -DEFAULTCONFIG = test_quota_compliance_tcp_asymmetric_peer2.conf [transport-tcp] PORT = 12015 diff --git a/src/transport/test_quota_compliance_tcp_peer1.conf b/src/transport/test_quota_compliance_tcp_peer1.conf index 29e56fe..b7eb287 100644 --- a/src/transport/test_quota_compliance_tcp_peer1.conf +++ b/src/transport/test_quota_compliance_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/quota-tcp-p1/ -DEFAULTCONFIG = test_quota_compliance_tcp_peer1.conf [transport-tcp] PORT = 4094 diff --git a/src/transport/test_quota_compliance_tcp_peer2.conf b/src/transport/test_quota_compliance_tcp_peer2.conf index 5da60d0..67f171e 100644 --- a/src/transport/test_quota_compliance_tcp_peer2.conf +++ b/src/transport/test_quota_compliance_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_quota_compliance_tcp_peer2.conf [transport-tcp] PORT = 12015 diff --git a/src/transport/test_quota_compliance_udp_peer1.conf b/src/transport/test_quota_compliance_udp_peer1.conf index fceee7b..0d49d4e 100644 --- a/src/transport/test_quota_compliance_udp_peer1.conf +++ b/src/transport/test_quota_compliance_udp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1/ -DEFAULTCONFIG = test_quota_compliance_udp_peer1.conf [transport-udp] PORT = 4368 diff --git a/src/transport/test_quota_compliance_udp_peer2.conf b/src/transport/test_quota_compliance_udp_peer2.conf index 4b58c93..3c57fe5 100644 --- a/src/transport/test_quota_compliance_udp_peer2.conf +++ b/src/transport/test_quota_compliance_udp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_udp_peer2.conf [transport-udp] PORT = 3368 diff --git a/src/transport/test_quota_compliance_unix_asymmetric_peer1.conf b/src/transport/test_quota_compliance_unix_asymmetric_peer1.conf index 649cf1c..1e4afce 100644 --- a/src/transport/test_quota_compliance_unix_asymmetric_peer1.conf +++ b/src/transport/test_quota_compliance_unix_asymmetric_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1/ -DEFAULTCONFIG = test_quota_compliance_unix_asymmetric_peer1.conf [arm] PORT = 4087 diff --git a/src/transport/test_quota_compliance_unix_asymmetric_peer2.conf b/src/transport/test_quota_compliance_unix_asymmetric_peer2.conf index a2d1bdd..f732e98 100644 --- a/src/transport/test_quota_compliance_unix_asymmetric_peer2.conf +++ b/src/transport/test_quota_compliance_unix_asymmetric_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_unix_asymmetric_peer2.conf [arm] PORT = 3087 diff --git a/src/transport/test_quota_compliance_unix_peer1.conf b/src/transport/test_quota_compliance_unix_peer1.conf index 60e656b..bde7846 100644 --- a/src/transport/test_quota_compliance_unix_peer1.conf +++ b/src/transport/test_quota_compliance_unix_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer1/ -DEFAULTCONFIG = test_quota_compliance_unix_peer1.conf [transport-unix] PORT = 12120 diff --git a/src/transport/test_quota_compliance_unix_peer2.conf b/src/transport/test_quota_compliance_unix_peer2.conf index b4f0b64..0b803cc 100644 --- a/src/transport/test_quota_compliance_unix_peer2.conf +++ b/src/transport/test_quota_compliance_unix_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test_quota_compliance_peer2 -DEFAULTCONFIG = test_quota_compliance_unix_peer2.conf [transport-unix] PORT = 12136 diff --git a/src/transport/test_quota_compliance_wlan_asymmetric_peer1.conf b/src/transport/test_quota_compliance_wlan_asymmetric_peer1.conf new file mode 100644 index 0000000..e81a3f9 --- /dev/null +++ b/src/transport/test_quota_compliance_wlan_asymmetric_peer1.conf @@ -0,0 +1,29 @@ +@INLINE@ template_cfg_peer1.conf +[PATHS] +SERVICEHOME = /tmp/test-transport/api-wlan-p1/ + +[transport-wlan] +TESTMODE = 1 + +[arm] +PORT = 12164 +UNIXPATH = /tmp/gnunet-p1-service-arm.sock + +[statistics] +PORT = 12163 +UNIXPATH = /tmp/gnunet-p1-service-statistics.sock + +[resolver] +PORT = 12162 +UNIXPATH = /tmp/gnunet-p1-service-resolver.sock + +[peerinfo] +PORT = 12161 +UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock + +[transport] +PORT = 12160 +PLUGINS = wlan +UNIXPATH = /tmp/gnunet-p1-service-transport.sock + + diff --git a/src/transport/test_transport_api_https_nat_peer2.conf b/src/transport/test_quota_compliance_wlan_asymmetric_peer2.conf index a23f3a5..bd53876 100644 --- a/src/transport/test_transport_api_https_nat_peer2.conf +++ b/src/transport/test_quota_compliance_wlan_asymmetric_peer2.conf @@ -1,33 +1,29 @@ @INLINE@ template_cfg_peer2.conf [PATHS] -SERVICEHOME = /tmp/test-transport/api-https-p2/ -DEFAULTCONFIG = test_transport_api_https_nat_peer2.conf +SERVICEHOME = /tmp/test-transport/api-wlan-p2/ -[transport-https] -PORT = 12110 -KEY_FILE = $SERVICEHOME/https_key_p2.key -CERT_FILE = $SERVICEHOME/https_cert_p2.crt +[transport-wlan] +INTERFACE = mon1 +TESTMODE = 2 [arm] -PORT = 12115 +PORT = 12174 UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 12114 +PORT = 12173 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] -PORT = 12113 +PORT = 12172 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 12112 +PORT = 12171 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -PORT = 12111 -PLUGINS = https +PORT = 12170 +PLUGINS = wlan UNIXPATH = /tmp/gnunet-p2-service-transport.sock -DEBUG = NO - diff --git a/src/transport/test_quota_compliance_wlan_peer1.conf b/src/transport/test_quota_compliance_wlan_peer1.conf new file mode 100644 index 0000000..e81a3f9 --- /dev/null +++ b/src/transport/test_quota_compliance_wlan_peer1.conf @@ -0,0 +1,29 @@ +@INLINE@ template_cfg_peer1.conf +[PATHS] +SERVICEHOME = /tmp/test-transport/api-wlan-p1/ + +[transport-wlan] +TESTMODE = 1 + +[arm] +PORT = 12164 +UNIXPATH = /tmp/gnunet-p1-service-arm.sock + +[statistics] +PORT = 12163 +UNIXPATH = /tmp/gnunet-p1-service-statistics.sock + +[resolver] +PORT = 12162 +UNIXPATH = /tmp/gnunet-p1-service-resolver.sock + +[peerinfo] +PORT = 12161 +UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock + +[transport] +PORT = 12160 +PLUGINS = wlan +UNIXPATH = /tmp/gnunet-p1-service-transport.sock + + diff --git a/src/transport/test_transport_api_reliability_https_nat_peer2.conf b/src/transport/test_quota_compliance_wlan_peer2.conf index b7c2e97..bd53876 100644 --- a/src/transport/test_transport_api_reliability_https_nat_peer2.conf +++ b/src/transport/test_quota_compliance_wlan_peer2.conf @@ -1,33 +1,29 @@ @INLINE@ template_cfg_peer2.conf [PATHS] -SERVICEHOME = /tmp/test-transport/api-https-p2/ -DEFAULTCONFIG = test_transport_api_reliability_https_nat_peer2.conf +SERVICEHOME = /tmp/test-transport/api-wlan-p2/ -[transport-https] -PORT = 12110 -KEY_FILE = $SERVICEHOME/https_key_p2.key -CERT_FILE = $SERVICEHOME/https_cert_p2.crt +[transport-wlan] +INTERFACE = mon1 +TESTMODE = 2 [arm] -PORT = 12115 +PORT = 12174 UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 12114 +PORT = 12173 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] -PORT = 12113 +PORT = 12172 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 12112 +PORT = 12171 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -PORT = 12111 -PLUGINS = https +PORT = 12170 +PLUGINS = wlan UNIXPATH = /tmp/gnunet-p2-service-transport.sock -DEBUG = NO - diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index f944fac..1316efe 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c @@ -27,19 +27,9 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" - -#define START_ARM GNUNET_YES - /** * How long until we give up on transmitting the message? */ @@ -383,9 +373,6 @@ check () GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif send_task = GNUNET_SCHEDULER_NO_TASK; ok = 1; diff --git a/src/transport/test_transport_api_bidirectional_connect.c b/src/transport/test_transport_api_bidirectional_connect.c index 2c4eeab..3923216 100644 --- a/src/transport/test_transport_api_bidirectional_connect.c +++ b/src/transport/test_transport_api_bidirectional_connect.c @@ -25,14 +25,7 @@ * (almost) the same time */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" diff --git a/src/transport/test_transport_api_bidirectional_connect_peer1.conf b/src/transport/test_transport_api_bidirectional_connect_peer1.conf index 49fc662..ba6afbe 100644 --- a/src/transport/test_transport_api_bidirectional_connect_peer1.conf +++ b/src/transport/test_transport_api_bidirectional_connect_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_bidirectional_connect_peer1.conf [arm] PORT = 12000 @@ -23,7 +22,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12004 UNIXPATH = /tmp/gnunet-p1-service-transport.sock -#DEBUG = YES [transport-tcp] PORT = 12005 @@ -43,4 +41,4 @@ TIMEOUT = 5 s [transport-https] PORT = 12009 -TIMEOUT = 5 s
\ No newline at end of file +TIMEOUT = 5 s diff --git a/src/transport/test_transport_api_bidirectional_connect_peer2.conf b/src/transport/test_transport_api_bidirectional_connect_peer2.conf index 2d64351..4aeee7c 100644 --- a/src/transport/test_transport_api_bidirectional_connect_peer2.conf +++ b/src/transport/test_transport_api_bidirectional_connect_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_bidirectional_connect_peer2.conf [arm] PORT = 12010 @@ -42,4 +41,4 @@ TIMEOUT = 5 s [transport-https] PORT = 12019 -TIMEOUT = 5 s
\ No newline at end of file +TIMEOUT = 5 s diff --git a/src/transport/test_transport_api_blacklisting.c b/src/transport/test_transport_api_blacklisting.c index 909ea57..55adb5b 100644 --- a/src/transport/test_transport_api_blacklisting.c +++ b/src/transport/test_transport_api_blacklisting.c @@ -25,22 +25,9 @@ * */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES - - struct PeerContext *p1; struct PeerContext *p2; @@ -435,19 +422,12 @@ check () static char *const argv[] = { "test-transport-api-blacklisting", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif - ok = 1; GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-transport-api-blacklisting", "nohelp", options, &run, &ok); @@ -461,11 +441,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test-transport-api-blacklisting", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); tth = GNUNET_TRANSPORT_TESTING_init (); diff --git a/src/transport/test_transport_api_data.conf b/src/transport/test_transport_api_data.conf index 3955246..164a38f 100644 --- a/src/transport/test_transport_api_data.conf +++ b/src/transport/test_transport_api_data.conf @@ -1,6 +1,5 @@ @INLINE@ test_transport_defaults.conf [PATHS] -DEFAULTCONFIG = test_transport_api_data.conf [transport-tcp] PORT = 2094 diff --git a/src/transport/test_transport_api_disconnect.c b/src/transport/test_transport_api_disconnect.c index 973c4cf..7a26c7e 100644 --- a/src/transport/test_transport_api_disconnect.c +++ b/src/transport/test_transport_api_disconnect.c @@ -24,21 +24,9 @@ * This test case tests disconnect notifications in peer shutdown */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "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? */ @@ -374,18 +362,12 @@ 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[] = { GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif send_task = GNUNET_SCHEDULER_NO_TASK; ok = 1; @@ -403,11 +385,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_disconnect_tcp_peer1.conf b/src/transport/test_transport_api_disconnect_tcp_peer1.conf index ebb4fd4..5f1d693 100644 --- a/src/transport/test_transport_api_disconnect_tcp_peer1.conf +++ b/src/transport/test_transport_api_disconnect_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_tcp_peer1.conf [transport-tcp] PORT = 12000 @@ -28,5 +27,4 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock 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 fe6d19b..67f171e 100644 --- a/src/transport/test_transport_api_disconnect_tcp_peer2.conf +++ b/src/transport/test_transport_api_disconnect_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_tcp_peer2.conf [transport-tcp] PORT = 12015 diff --git a/src/transport/test_transport_api_http_nat_peer1.conf b/src/transport/test_transport_api_http_nat_peer1.conf deleted file mode 100644 index 447508c..0000000 --- a/src/transport/test_transport_api_http_nat_peer1.conf +++ /dev/null @@ -1,38 +0,0 @@ -@INLINE@ template_cfg_peer1.conf -[PATHS] -SERVICEHOME = /tmp/test-transport/api-http-p1/ -DEFAULTCONFIG = test_transport_api_http_nat_peer1.conf - -[nat] -BEHIND_NAT = YES -ENABLE_NAT_SERVER = YES - -[transport-http] -PORT = 0 - -[arm] -PORT = 12085 -DEFAULTSERVICES = transport -UNIXPATH = /tmp/gnunet-p1-service-arm.sock - -[statistics] -PORT = 12084 -UNIXPATH = /tmp/gnunet-p1-service-statistics.sock - -[resolver] -PORT = 12083 -UNIXPATH = /tmp/gnunet-p1-service-resolver.sock - -[peerinfo] -PORT = 12082 -UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock - -[transport] -#DEBUG = YES -PORT = 12081 -PLUGINS = http -#BINARY = .libs/gnunet-service-transport -UNIXPATH = /tmp/gnunet-p1-service-transport.sock -#PREFIX = valgrind --leak-check=full -#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args - diff --git a/src/transport/test_transport_api_http_peer1.conf b/src/transport/test_transport_api_http_peer1.conf index 26c2969..3c1b41d 100644 --- a/src/transport/test_transport_api_http_peer1.conf +++ b/src/transport/test_transport_api_http_peer1.conf @@ -1,10 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p1/ -DEFAULTCONFIG = test_transport_api_http_peer1.conf -[transport-http] -PORT = 12080 +[transport-http_client] [arm] PORT = 12085 @@ -24,9 +22,8 @@ PORT = 12082 UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] -#DEBUG = YES PORT = 12081 -PLUGINS = http +PLUGINS = http_client #BINARY = .libs/gnunet-service-transport UNIXPATH = /tmp/gnunet-p1-service-transport.sock #PREFIX = valgrind --leak-check=full diff --git a/src/transport/test_transport_api_http_peer2.conf b/src/transport/test_transport_api_http_peer2.conf index fa7aa3b..f348bf4 100644 --- a/src/transport/test_transport_api_http_peer2.conf +++ b/src/transport/test_transport_api_http_peer2.conf @@ -1,10 +1,11 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p2/ -DEFAULTCONFIG = test_transport_api_http_peer2.conf -[transport-http] +[transport-http_server] PORT = 12090 +USE_IPv6 = YES +#BINDTO = 127.0.0.1 [arm] PORT = 12095 @@ -24,8 +25,7 @@ PORT = 12092 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -#DEBUG = YES PORT = 12091 -PLUGINS = http +PLUGINS = http_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock #PREFIX = valgrind --leak-check=full diff --git a/src/transport/test_transport_api_reliability_http_nat_peer1.conf b/src/transport/test_transport_api_http_reverse_peer1.conf index cd841a3..93d8bd3 100644 --- a/src/transport/test_transport_api_reliability_http_nat_peer1.conf +++ b/src/transport/test_transport_api_http_reverse_peer1.conf @@ -1,38 +1,39 @@ -@INLINE@ template_cfg_peer1.conf +INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p1/ -DEFAULTCONFIG = test_transport_api_reliability_http_nat_peer1.conf -[nat] -BEHIND_NAT = YES -ENABLE_NAT_SERVER = YES -[transport-http] -PORT = 0 +[transport-http_client] [arm] -PORT = 12085 +PORT = 12095 DEFAULTSERVICES = transport UNIXPATH = /tmp/gnunet-p1-service-arm.sock [statistics] -PORT = 12084 +PORT = 12094 UNIXPATH = /tmp/gnunet-p1-service-statistics.sock [resolver] -PORT = 12083 +PORT = 12093 UNIXPATH = /tmp/gnunet-p1-service-resolver.sock [peerinfo] -PORT = 12082 +PORT = 12092 UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] -#DEBUG = YES -PORT = 12081 -PLUGINS = http +PORT = 12091 +PLUGINS = http_client #BINARY = .libs/gnunet-service-transport UNIXPATH = /tmp/gnunet-p1-service-transport.sock -#PREFIX = valgrind --leak-check=full +PREFIX = valgrind --leak-check=full #PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args + +[ats] +WAN_QUOTA_IN = unlimited +WAN_QUOTA_OUT = unlimited +PORT = 12006 +UNIXPATH = /tmp/gnunet-http_reserver_p1-service-ats.sock + diff --git a/src/transport/test_transport_api_http_reverse_peer2.conf b/src/transport/test_transport_api_http_reverse_peer2.conf new file mode 100644 index 0000000..b73921f --- /dev/null +++ b/src/transport/test_transport_api_http_reverse_peer2.conf @@ -0,0 +1,40 @@ +INLINE@ template_cfg_peer2.conf +[PATHS] +SERVICEHOME = /tmp/test-transport/api-http-p2/ + + +[transport-http_client] + +[transport-http_server] +PORT = 8080 +EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de/gnunet +EXTERNAL_HOSTNAME_ONLY = YES +#USE_IPV4 = YES +#USE_IPV6 = YES +#BINDTO = 127.0.0.1 +#BINDTO6 = ::1 + +[arm] +PORT = 12085 +DEFAULTSERVICES = transport +UNIXPATH = /tmp/gnunet-p2-service-arm.sock + +[statistics] +PORT = 12084 +UNIXPATH = /tmp/gnunet-p2-service-statistics.sock + +[resolver] +PORT = 12083 +UNIXPATH = /tmp/gnunet-p2-service-resolver.sock + +[peerinfo] +PORT = 12082 +UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock + +[transport] +PORT = 12081 +PLUGINS = http_server +UNIXPATH = /tmp/gnunet-p2-service-transport.sock +PREFIX = valgrind --leak-check=full +#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args + diff --git a/src/transport/test_transport_api_https_nat_peer1.conf b/src/transport/test_transport_api_https_nat_peer1.conf deleted file mode 100644 index e97b473..0000000 --- a/src/transport/test_transport_api_https_nat_peer1.conf +++ /dev/null @@ -1,36 +0,0 @@ -@INLINE@ template_cfg_peer1.conf -[PATHS] -SERVICEHOME = /tmp/test-transport/api-https-p1/ -DEFAULTCONFIG = test_transport_api_https_nat_peer1.conf - -[nat] -BEHIND_NAT = YES -ENABLE_NAT_SERVER = YES - -[transport-https] -PORT = 0 -KEY_FILE = $SERVICEHOME/https_key_p1.key -CERT_FILE = $SERVICEHOME/https_cert_p1.crt - -[arm] -PORT = 12105 - -[statistics] -PORT = 12104 -UNIXPATH = /tmp/gnunet-p1-service-statistics.sock - -[resolver] -PORT = 12103 -UNIXPATH = /tmp/gnunet-p1-service-resolver.sock - -[peerinfo] -PORT = 12102 -UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock - -[transport] -PORT = 12101 -PLUGINS = https -UNIXPATH = /tmp/gnunet-p1-service-transport.sock -DEBUG = NO - - diff --git a/src/transport/test_transport_api_https_peer1.conf b/src/transport/test_transport_api_https_peer1.conf index 8a93ca1..48302a6 100644 --- a/src/transport/test_transport_api_https_peer1.conf +++ b/src/transport/test_transport_api_https_peer1.conf @@ -1,9 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p1/ -DEFAULTCONFIG = test_transport_api_https_peer1.conf -[transport-https] +[transport-https_client] PORT = 12100 KEY_FILE = $SERVICEHOME/https_key_p1.key CERT_FILE = $SERVICEHOME/https_cert_p1.crt @@ -25,8 +24,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12101 -PLUGINS = https +PLUGINS = https_client UNIXPATH = /tmp/gnunet-p1-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_https_peer2.conf b/src/transport/test_transport_api_https_peer2.conf index 0710f41..566997f 100644 --- a/src/transport/test_transport_api_https_peer2.conf +++ b/src/transport/test_transport_api_https_peer2.conf @@ -1,10 +1,11 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p2/ -DEFAULTCONFIG = test_transport_api_https_peer2.conf -[transport-https] +[transport-https_server] PORT = 12110 +USE_IPv6 = YES +#BINDTO = 127.0.0.1 KEY_FILE = $SERVICEHOME/https_key_p2.key CERT_FILE = $SERVICEHOME/https_cert_p2.crt @@ -26,8 +27,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12111 -PLUGINS = https +PLUGINS = https_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_limited_sockets.c b/src/transport/test_transport_api_limited_sockets.c index e6ad84a..69a5100 100644 --- a/src/transport/test_transport_api_limited_sockets.c +++ b/src/transport/test_transport_api_limited_sockets.c @@ -27,22 +27,9 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "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? */ @@ -57,6 +44,9 @@ #define MAX_FILES 50 + +#if HAVE_SETRLIMIT + static char *test_source; static char *test_plugin; @@ -107,6 +97,8 @@ end () GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); + GNUNET_TRANSPORT_TESTING_done (tth); + } static void @@ -131,6 +123,9 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (p2 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); + if (NULL != th) + GNUNET_TRANSPORT_TESTING_done (tth); + ok = GNUNET_SYSERR; } @@ -241,7 +236,7 @@ start_cb (struct PeerContext *p, void *cls) if (started != 2) return; - cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb, + cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p2, p1, &testing_connect_cb, NULL); } @@ -279,9 +274,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[] = { @@ -300,39 +292,24 @@ check () return ok; } + int main (int argc, char *argv[]) { + struct rlimit r_file_old; + struct rlimit r_file_new; + int res; int ret = 0; test_plugin = NULL; - GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source, &test_plugin); GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); - GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); -#if !HAVE_SETRLIMIT - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot run test on this system\n"); - - GNUNET_free (test_source); - GNUNET_free (test_plugin); - GNUNET_free (test_name); - - return 0; -#else - struct rlimit r_file_old; - struct rlimit r_file_new; - int res; - res = getrlimit (RLIMIT_NOFILE, &r_file_old); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Maximum number of open files was: %u/%u\n", r_file_old.rlim_cur, @@ -355,27 +332,27 @@ main (int argc, char *argv[]) GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1); GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2); ret = check (); -#endif - GNUNET_free (cfg_file_p1); GNUNET_free (cfg_file_p2); - GNUNET_free (test_source); GNUNET_free (test_plugin); GNUNET_free (test_name); - -#if HAVE_SETRLIMIT - 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) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Restoring limit failed!\n"); - return 0; - } -#endif return ret; } +#else +/* cannot setrlimit */ + + +int +main (int argc, char *argv[]) +{ + fprintf (stderr, "Cannot run test on this system\n"); + return 0; +} + +#endif + /* 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 d29b946..dceeccb 100644 --- a/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf +++ b/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_tcp_peer1.conf [transport-tcp] PORT = 12000 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 3c0e496..caaddde 100644 --- a/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf +++ b/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_tcp_peer2.conf [transport-tcp] PORT = 0 diff --git a/src/transport/test_transport_api_manipulation_recv_tcp.c b/src/transport/test_transport_api_manipulation_recv_tcp.c new file mode 100644 index 0000000..4621507 --- /dev/null +++ b/src/transport/test_transport_api_manipulation_recv_tcp.c @@ -0,0 +1,493 @@ +/* + 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 transport/test_transport_api_manipulation_recv_tcp.c + * @brief base test case for transport traffic manipulation implementation + * + * This test case will setup 2 peers and connect them, the first message + * will be sent without manipulation, then a receive delay of 1 second will + * be configured and 2 more message will be sent. Time will be measured + * + * In addition the distance on receiver side will be manipulated to be 10 + */ +#include "platform.h" +#include "gnunet_transport_service.h" +#include "transport-testing.h" + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +#define TEST_MESSAGE_SIZE 2600 + +#define TEST_MESSAGE_TYPE 12345 + +static char *test_source; + +static char *test_plugin; + +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; + +static struct PeerContext *p1; + +static struct PeerContext *p2; + +static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; + +static struct GNUNET_TRANSPORT_TransmitHandle *th; + +static struct GNUNET_TRANSPORT_TESTING_handle *tth; + +static char *cfg_file_p1; + +static char *cfg_file_p2; + +static int messages_recv; + +static struct GNUNET_TIME_Absolute start_normal; +static struct GNUNET_TIME_Relative dur_normal; + +static struct GNUNET_TIME_Absolute start_delayed; +static struct GNUNET_TIME_Relative dur_delayed; + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n"); + + if (send_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (send_task); + + if (die_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (die_task); + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + th = NULL; + + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); + 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 (send_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (send_task); + + if (cc != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n")); + GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc); + cc = NULL; + } + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + else + 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")); + else + 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")); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were connected\n")); + + if (s_sending == GNUNET_NO) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n")); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were ready to send data\n")); + + th = NULL; + + if (p1 != NULL) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 1 was not started\n")); + if (p2 != NULL) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 2 was not started\n")); + + ok = GNUNET_SYSERR; +} + + +static void +sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +static void +notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + struct PeerContext *p = cls; + struct PeerContext *t = NULL; + int c; + + if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) + t = p1; + if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) + t = p2; + GNUNET_assert (t != NULL); + + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s') received message of type %d and size %u size from peer %u (`%4s')!\n", + p->no, ps, ntohs (message->type), ntohs (message->size), t->no, + GNUNET_i2s (&t->id)); + GNUNET_free (ps); + + if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && + (TEST_MESSAGE_SIZE == ntohs (message->size))) + { + ok = 0; + + } + else + { + GNUNET_break (0); + ok = 1; + end (); + return; + } + + if (messages_recv <= 1) + { + /* Received non-delayed message */ + dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received non-delayed message %u after %llu\n", + messages_recv, + (long long unsigned int) dur_normal.rel_value); + + struct GNUNET_ATS_Information ats[2]; + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); + ats[0].value = htonl (1000); + ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + ats[1].value = htonl (10); + + GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, TM_RECEIVE, ats, 2); + send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); + } + if (2 == messages_recv) + { + /* Received manipulated message */ + dur_delayed = GNUNET_TIME_absolute_get_duration(start_delayed); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received delayed message %u after %llu\n", + messages_recv, + (long long unsigned int) dur_delayed.rel_value); + if (dur_delayed.rel_value < 1000) + { + GNUNET_break (0); + ok += 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Delayed message was not delayed correctly: took only %llu\n", + (long long unsigned int) dur_delayed.rel_value); + } + for (c = 0; c < ats_count; c++) + { + if (ntohl (ats[c].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) + { + if (ntohl (ats[c].value) == 10) + ok += 0; + else + { + GNUNET_break (0); + ok += 1; + } + } + } + /* shutdown */ + end (); + } + + messages_recv ++; +} + + +static size_t +notify_ready (void *cls, size_t size, void *buf) +{ + struct PeerContext *p = cls; + struct GNUNET_MessageHeader *hdr; + + th = NULL; + + if (buf == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout occurred while waiting for transmit_ready\n"); + if (GNUNET_SCHEDULER_NO_TASK != die_task) + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + ok = 42; + return 0; + } + + GNUNET_assert (size >= TEST_MESSAGE_SIZE); + if (buf != NULL) + { + memset (buf, '\0', TEST_MESSAGE_SIZE); + hdr = buf; + hdr->size = htons (TEST_MESSAGE_SIZE); + hdr->type = htons (TEST_MESSAGE_TYPE); + } + + char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n", + p2->no, ps, ntohs (hdr->type), ntohs (hdr->size), p->no, + GNUNET_i2s (&p->id)); + GNUNET_free (ps); + + return TEST_MESSAGE_SIZE; +} + + +static void +sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + send_task = GNUNET_SCHEDULER_NO_TASK; + + if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + return; + char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n", + p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); + GNUNET_free (receiver_s); + + + if (0 == messages_recv) + { + start_normal = GNUNET_TIME_absolute_get(); + } + if (1 == messages_recv) + { + start_delayed = GNUNET_TIME_absolute_get(); + } + + s_sending = GNUNET_YES; + th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, TEST_MESSAGE_SIZE, 0, + TIMEOUT_TRANSMIT, ¬ify_ready, + p1); +} + + +static void +notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + static int c; + + c++; + struct PeerContext *p = cls; + struct PeerContext *t = NULL; + + if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) + t = p1; + if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) + t = p2; + GNUNET_assert (t != NULL); + + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s'): peer %u (`%s') connected to me!\n", p->no, ps, + t->no, GNUNET_i2s (peer)); + GNUNET_free (ps); +} + + +static void +notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + struct PeerContext *p = cls; + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s'): peer (`%s') disconnected from me!\n", p->no, ps, + GNUNET_i2s (peer)); + + GNUNET_free (ps); + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + th = NULL; +} + + +static void +testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) +{ + cc = NULL; + char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n", + p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id)); + GNUNET_free (p1_c); + + s_connected = GNUNET_YES; + send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); +} + + +static void +start_cb (struct PeerContext *p, void *cls) +{ + static int started; + started++; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", p->no, + GNUNET_i2s (&p->id)); + + if (started != 2) + return; + else + s_started = GNUNET_YES; + char *sender_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n", + p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id)); + GNUNET_free (sender_c); + + cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb, + NULL); + +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); + + s_started = GNUNET_NO; + s_connected = GNUNET_NO; + s_sending = GNUNET_NO; + + p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1, + ¬ify_receive, ¬ify_connect, + ¬ify_disconnect, &start_cb, + NULL); + + p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2, + ¬ify_receive, ¬ify_connect, + ¬ify_disconnect, &start_cb, + NULL); + + if ((p1 == NULL) || (p2 == NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n"); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } +} + + +static int +check () +{ + static char *const argv[] = { "test-transport-api-manipulation", + "-c", + "test_transport_api_data.conf", + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + send_task = GNUNET_SCHEDULER_NO_TASK; + + ok = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, + "nohelp", options, &run, &ok); + + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); + GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); + GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source, + &test_plugin); + + GNUNET_log_setup (test_name, + "WARNING", + NULL); + tth = GNUNET_TRANSPORT_TESTING_init (); + + GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1); + GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2); + + ret = check (); + + GNUNET_free (cfg_file_p1); + GNUNET_free (cfg_file_p2); + + GNUNET_free (test_source); + GNUNET_free (test_plugin); + GNUNET_free (test_name); + + GNUNET_TRANSPORT_TESTING_done (tth); + + return ret; +} + +/* end of test_transport_api_manipulation_recv_tcp.c */ diff --git a/src/transport/test_transport_api_manipulation_recv_tcp_peer1.conf b/src/transport/test_transport_api_manipulation_recv_tcp_peer1.conf new file mode 100644 index 0000000..db66282 --- /dev/null +++ b/src/transport/test_transport_api_manipulation_recv_tcp_peer1.conf @@ -0,0 +1,30 @@ +@INLINE@ template_cfg_peer1.conf +[PATHS] +SERVICEHOME = /tmp/test-transport/api-tcp-p1/ + +[transport-tcp] +PORT = 12000 +TIMEOUT = 5 s + +[arm] +PORT = 12005 +DEFAULTSERVICES = transport +UNIXPATH = /tmp/gnunet-p1-service-arm.sock + +[statistics] +PORT = 12004 +UNIXPATH = /tmp/gnunet-p1-service-statistics.sock + +[resolver] +PORT = 12003 +UNIXPATH = /tmp/gnunet-p1-service-resolver.sock + +[peerinfo] +PORT = 12002 +UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock + +[transport] +PORT = 12001 +UNIXPATH = /tmp/gnunet-p1-service-transport.sock +PLUGINS = tcp + diff --git a/src/transport/test_transport_api_http_nat_peer2.conf b/src/transport/test_transport_api_manipulation_recv_tcp_peer2.conf index 2f56eab..67f171e 100644 --- a/src/transport/test_transport_api_http_nat_peer2.conf +++ b/src/transport/test_transport_api_manipulation_recv_tcp_peer2.conf @@ -1,31 +1,30 @@ @INLINE@ template_cfg_peer2.conf [PATHS] -SERVICEHOME = /tmp/test-transport/api-http-p2/ -DEFAULTCONFIG = test_transport_api_http_nat_peer2.conf +SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -[transport-http] -PORT = 12090 +[transport-tcp] +PORT = 12015 +TIMEOUT = 5 s [arm] -PORT = 12095 +PORT = 12014 DEFAULTSERVICES = transport UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 12094 +PORT = 12013 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] -PORT = 12093 +PORT = 12012 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 12092 +PORT = 12011 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -#DEBUG = YES -PORT = 12091 -PLUGINS = http +PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock -#PREFIX = valgrind --leak-check=full + diff --git a/src/transport/test_transport_api_manipulation_send_tcp.c b/src/transport/test_transport_api_manipulation_send_tcp.c new file mode 100644 index 0000000..2e40e9f --- /dev/null +++ b/src/transport/test_transport_api_manipulation_send_tcp.c @@ -0,0 +1,500 @@ +/* + 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 transport/test_transport_api_manipulation_send_tcp.c + * @brief base test case for transport traffic manipulation implementation + * + * This test case will setup 2 peers and connect them, the first message + * will be sent without manipulation, then a send delay of 1 second will + * be configured and 1 more message will be sent. Time will be measured. + * + * In addition the distance on receiver side will be manipulated to be 10 + */ +#include "platform.h" +#include "gnunet_transport_service.h" +#include "transport-testing.h" + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +#define TEST_MESSAGE_SIZE 2600 + +#define TEST_MESSAGE_TYPE 12345 + +static char *test_source; + +static char *test_plugin; + +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; + +static struct PeerContext *p1; + +static struct PeerContext *p2; + +static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; + +static struct GNUNET_TRANSPORT_TransmitHandle *th; + +static struct GNUNET_TRANSPORT_TESTING_handle *tth; + +static char *cfg_file_p1; + +static char *cfg_file_p2; + +static int messages_recv; + +static struct GNUNET_TIME_Absolute start_normal; +static struct GNUNET_TIME_Relative dur_normal; + +static struct GNUNET_TIME_Absolute start_delayed; +static struct GNUNET_TIME_Relative dur_delayed; + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n"); + + if (send_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (send_task); + + if (die_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (die_task); + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + th = NULL; + + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); + 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 (send_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (send_task); + + if (cc != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n")); + GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc); + cc = NULL; + } + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + else + 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")); + else + 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")); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were connected\n")); + + if (s_sending == GNUNET_NO) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n")); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were ready to send data\n")); + + th = NULL; + + if (p1 != NULL) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 1 was not started\n")); + if (p2 != NULL) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 2 was not started\n")); + + ok = GNUNET_SYSERR; +} + + +static void +sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +static void +notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + struct PeerContext *p = cls; + struct PeerContext *t = NULL; + int c; + + if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) + t = p1; + if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) + t = p2; + GNUNET_assert (t != NULL); + + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s') received message of type %d and size %u size from peer %u (`%4s')!\n", + p->no, ps, ntohs (message->type), ntohs (message->size), t->no, + GNUNET_i2s (&t->id)); + GNUNET_free (ps); + + if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && + (TEST_MESSAGE_SIZE == ntohs (message->size))) + { + ok = 0; + + } + else + { + GNUNET_break (0); + ok = 1; + end (); + return; + } + + if (0 == messages_recv) + { + /* Received non-delayed message */ + dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received non-delayed message %u after %llu\n", + messages_recv, + (long long unsigned int) dur_normal.rel_value); + send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); + } + if (1 == messages_recv) + { + /* Received manipulated message */ + dur_delayed = GNUNET_TIME_absolute_get_duration(start_delayed); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received delayed message %u after %llu\n", + messages_recv, + (long long unsigned int) dur_delayed.rel_value); + if (dur_delayed.rel_value < 1000) + { + GNUNET_break (0); + ok += 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Delayed message was not delayed correctly: took only %llu\n", + (long long unsigned int) dur_delayed.rel_value); + } + for (c = 0; c < ats_count; c++) + { + if (ntohl (ats[c].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) + { + if (ntohl (ats[c].value) == 10) + ok += 0; + else + { + GNUNET_break (0); + ok += 1; + } + } + } + /* shutdown */ + end (); + } + messages_recv ++; +} + + +static size_t +notify_ready (void *cls, size_t size, void *buf) +{ + struct PeerContext *p = cls; + struct GNUNET_MessageHeader *hdr; + + th = NULL; + + if (buf == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout occurred while waiting for transmit_ready\n"); + if (GNUNET_SCHEDULER_NO_TASK != die_task) + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + ok = 42; + return 0; + } + + GNUNET_assert (size >= TEST_MESSAGE_SIZE); + if (buf != NULL) + { + memset (buf, '\0', TEST_MESSAGE_SIZE); + hdr = buf; + hdr->size = htons (TEST_MESSAGE_SIZE); + hdr->type = htons (TEST_MESSAGE_TYPE); + } + + char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n", + p2->no, ps, ntohs (hdr->type), ntohs (hdr->size), p->no, + GNUNET_i2s (&p->id)); + GNUNET_free (ps); + + return TEST_MESSAGE_SIZE; +} + + +static void +sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_ATS_Information ats[1]; + send_task = GNUNET_SCHEDULER_NO_TASK; + + if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + return; + char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n", + p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); + GNUNET_free (receiver_s); + + + if (0 == messages_recv) + { + start_normal = GNUNET_TIME_absolute_get(); + } + if (1 == messages_recv) + { + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); + ats[0].value = htonl (1000); + GNUNET_TRANSPORT_set_traffic_metric (p2->th, &p1->id, TM_SEND, ats, 1); + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + ats[0].value = htonl (10); + GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, TM_BOTH, ats, 1); + + start_delayed = GNUNET_TIME_absolute_get(); + } + + s_sending = GNUNET_YES; + th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, TEST_MESSAGE_SIZE, 0, + TIMEOUT_TRANSMIT, ¬ify_ready, + p1); +} + + +static void +notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + static int c; + + c++; + struct PeerContext *p = cls; + struct PeerContext *t = NULL; + + if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) + t = p1; + if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) + t = p2; + GNUNET_assert (t != NULL); + + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s'): peer %u (`%s') connected to me!\n", p->no, ps, + t->no, GNUNET_i2s (peer)); + GNUNET_free (ps); +} + + +static void +notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + struct PeerContext *p = cls; + char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u (`%4s'): peer (`%s') disconnected from me!\n", p->no, ps, + GNUNET_i2s (peer)); + + GNUNET_free (ps); + + if (th != NULL) + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); + th = NULL; +} + + +static void +testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) +{ + cc = NULL; + char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n", + p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id)); + GNUNET_free (p1_c); + + s_connected = GNUNET_YES; + send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); +} + + +static void +start_cb (struct PeerContext *p, void *cls) +{ + static int started; + started++; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", p->no, + GNUNET_i2s (&p->id)); + + if (started != 2) + return; + else + s_started = GNUNET_YES; + char *sender_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n", + p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id)); + GNUNET_free (sender_c); + /* + struct GNUNET_ATS_Information ats[2]; + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); + ats[0].value = htonl (1000); + ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + ats[1].value = htonl (10); + + GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, TM_RECEIVE, ats, 2); +*/ + cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb, + NULL); + +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); + + s_started = GNUNET_NO; + s_connected = GNUNET_NO; + s_sending = GNUNET_NO; + + p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1, + ¬ify_receive, ¬ify_connect, + ¬ify_disconnect, &start_cb, + NULL); + + p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2, + ¬ify_receive, ¬ify_connect, + ¬ify_disconnect, &start_cb, + NULL); + + if ((p1 == NULL) || (p2 == NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n"); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } +} + + +static int +check () +{ + static char *const argv[] = { "test-transport-api-manipulation", + "-c", + "test_transport_api_data.conf", + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + send_task = GNUNET_SCHEDULER_NO_TASK; + + ok = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, + "nohelp", options, &run, &ok); + + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); + GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); + GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source, + &test_plugin); + + GNUNET_log_setup (test_name, + "WARNING", + NULL); + tth = GNUNET_TRANSPORT_TESTING_init (); + + GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1); + GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2); + + ret = check (); + + GNUNET_free (cfg_file_p1); + GNUNET_free (cfg_file_p2); + + GNUNET_free (test_source); + GNUNET_free (test_plugin); + GNUNET_free (test_name); + + GNUNET_TRANSPORT_TESTING_done (tth); + + return ret; +} + +/* end of test_transport_api.c */ diff --git a/src/transport/test_transport_api_manipulation_send_tcp_peer1.conf b/src/transport/test_transport_api_manipulation_send_tcp_peer1.conf new file mode 100644 index 0000000..db66282 --- /dev/null +++ b/src/transport/test_transport_api_manipulation_send_tcp_peer1.conf @@ -0,0 +1,30 @@ +@INLINE@ template_cfg_peer1.conf +[PATHS] +SERVICEHOME = /tmp/test-transport/api-tcp-p1/ + +[transport-tcp] +PORT = 12000 +TIMEOUT = 5 s + +[arm] +PORT = 12005 +DEFAULTSERVICES = transport +UNIXPATH = /tmp/gnunet-p1-service-arm.sock + +[statistics] +PORT = 12004 +UNIXPATH = /tmp/gnunet-p1-service-statistics.sock + +[resolver] +PORT = 12003 +UNIXPATH = /tmp/gnunet-p1-service-resolver.sock + +[peerinfo] +PORT = 12002 +UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock + +[transport] +PORT = 12001 +UNIXPATH = /tmp/gnunet-p1-service-transport.sock +PLUGINS = tcp + diff --git a/src/transport/test_transport_api_reliability_http_nat_peer2.conf b/src/transport/test_transport_api_manipulation_send_tcp_peer2.conf index c87a256..67f171e 100644 --- a/src/transport/test_transport_api_reliability_http_nat_peer2.conf +++ b/src/transport/test_transport_api_manipulation_send_tcp_peer2.conf @@ -1,35 +1,30 @@ @INLINE@ template_cfg_peer2.conf [PATHS] -SERVICEHOME = /tmp/test-transport/api-http-p2/ -DEFAULTCONFIG = test_transport_api_reliability_http_nat_peer2.conf +SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -[ats] -WAN_QUOTA_OUT = 1073741824 -WAN_QUOTA_IN = 1073741824 - -[transport-http] -PORT = 12090 +[transport-tcp] +PORT = 12015 +TIMEOUT = 5 s [arm] -PORT = 12095 +PORT = 12014 DEFAULTSERVICES = transport UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 12094 +PORT = 12013 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] -PORT = 12093 +PORT = 12012 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 12092 +PORT = 12011 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -#DEBUG = YES -PORT = 12091 -PLUGINS = http +PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock -#PREFIX = valgrind --leak-check=full + diff --git a/src/transport/test_transport_api_multi_peer1.conf b/src/transport/test_transport_api_multi_peer1.conf index a7c57fc..61b0f56 100644 --- a/src/transport/test_transport_api_multi_peer1.conf +++ b/src/transport/test_transport_api_multi_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-multi-p1/ -DEFAULTCONFIG = test_transport_api_multi_peer1.conf [transport-tcp] PORT = 12140 @@ -35,7 +34,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12145 -PLUGINS = tcp udp unix +PLUGINS = tcp udp UNIXPATH = /tmp/gnunet-p1-service-transport.sock [transport-unix] diff --git a/src/transport/test_transport_api_multi_peer2.conf b/src/transport/test_transport_api_multi_peer2.conf index 8008e7f..c660c3c 100644 --- a/src/transport/test_transport_api_multi_peer2.conf +++ b/src/transport/test_transport_api_multi_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-multi-p2/ -DEFAULTCONFIG = test_transport_api_multi_peer2.conf [nat] ALLOW_NAT = NO @@ -38,7 +37,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12155 -PLUGINS = tcp udp unix +PLUGINS = tcp udp UNIXPATH = /tmp/gnunet-p2-service-transport.sock [transport-unix] diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c index 759241c..bef2d0f 100644 --- a/src/transport/test_transport_api_reliability.c +++ b/src/transport/test_transport_api_reliability.c @@ -26,24 +26,9 @@ * achieve reliable message delivery. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_os_lib.h" -#include "gnunet_program_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" #include "gnunet_transport_service.h" #include "gauger.h" -#include "transport.h" #include "transport-testing.h" - -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES - /** * Testcase timeout */ @@ -479,18 +464,12 @@ check () static char *argv[] = { "test_transport", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif ok = 1; GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, "nohelp", options, &run, &ok); @@ -506,11 +485,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_reliability_http_peer1.conf b/src/transport/test_transport_api_reliability_http_peer1.conf index ebb6e43..ea5de0b 100644 --- a/src/transport/test_transport_api_reliability_http_peer1.conf +++ b/src/transport/test_transport_api_reliability_http_peer1.conf @@ -1,7 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p1/ -DEFAULTCONFIG = test_transport_api_reliability_http_peer1.conf + +[transport-http_client] [transport-tcp] TIMEOUT = 5 s @@ -27,7 +28,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12181 -PLUGINS = http +PLUGINS = http_client UNIXPATH = /tmp/gnunet-p1-service-transport.sock -#DEBUG = YES diff --git a/src/transport/test_transport_api_reliability_http_peer2.conf b/src/transport/test_transport_api_reliability_http_peer2.conf index c21fa1d..083cd4d 100644 --- a/src/transport/test_transport_api_reliability_http_peer2.conf +++ b/src/transport/test_transport_api_reliability_http_peer2.conf @@ -1,10 +1,11 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p2/ -DEFAULTCONFIG = test_transport_api_reliability_http_peer2.conf -[transport-http] -PORT = 12190 +[transport-http_server] +PORT = 12090 +USE_IPv6 = NO +BINDTO = 127.0.0.1 [arm] PORT = 12195 @@ -24,7 +25,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12191 -PLUGINS = http +PLUGINS = http_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock -#DEBUG = YES diff --git a/src/transport/test_transport_api_reliability_https_nat_peer1.conf b/src/transport/test_transport_api_reliability_https_nat_peer1.conf deleted file mode 100644 index ca14c72..0000000 --- a/src/transport/test_transport_api_reliability_https_nat_peer1.conf +++ /dev/null @@ -1,36 +0,0 @@ -@INLINE@ template_cfg_peer1.conf -[PATHS] -SERVICEHOME = /tmp/test-transport/api-https-p1/ -DEFAULTCONFIG = test_transport_api_reliability_https_nat_peer1.conf - -[nat] -BEHIND_NAT = YES -ENABLE_NAT_SERVER = YES - -[transport-https] -PORT = 0 -KEY_FILE = $SERVICEHOME/https_key_p1.key -CERT_FILE = $SERVICEHOME/https_cert_p1.crt - -[arm] -PORT = 12105 - -[statistics] -PORT = 12104 -UNIXPATH = /tmp/gnunet-p1-service-statistics.sock - -[resolver] -PORT = 12103 -UNIXPATH = /tmp/gnunet-p1-service-resolver.sock - -[peerinfo] -PORT = 12102 -UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock - -[transport] -PORT = 12101 -PLUGINS = https -UNIXPATH = /tmp/gnunet-p1-service-transport.sock -DEBUG = NO - - diff --git a/src/transport/test_transport_api_reliability_https_peer1.conf b/src/transport/test_transport_api_reliability_https_peer1.conf index 0699f69..d5e8826 100644 --- a/src/transport/test_transport_api_reliability_https_peer1.conf +++ b/src/transport/test_transport_api_reliability_https_peer1.conf @@ -1,12 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p1/ -DEFAULTCONFIG = test_transport_api_reliability_https_peer1.conf -[transport-https] -PORT = 12300 -KEY_FILE = $SERVICEHOME/https_key_p1.key -CERT_FILE = $SERVICEHOME/https_cert_p1.crt +[transport-https_client] [arm] PORT = 12305 @@ -26,6 +22,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12301 -PLUGINS = https +PLUGINS = https_client UNIXPATH = /tmp/gnunet-p1-service-transport.sock diff --git a/src/transport/test_transport_api_reliability_https_peer2.conf b/src/transport/test_transport_api_reliability_https_peer2.conf index bd344ab..5cc0d24 100644 --- a/src/transport/test_transport_api_reliability_https_peer2.conf +++ b/src/transport/test_transport_api_reliability_https_peer2.conf @@ -1,9 +1,8 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p2/ -DEFAULTCONFIG = test_transport_api_reliability_https_peer2.conf -[transport-https] +[transport-https_server] PORT = 12310 KEY_FILE = $SERVICEHOME/https_key_p2.key CERT_FILE = $SERVICEHOME/https_cert_p2.crt @@ -26,7 +25,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12311 -PLUGINS = https +PLUGINS = https_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock 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 ffd3d2f..9490d40 100644 --- a/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf +++ b/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-reliability-tcp-nat-p1/ -DEFAULTCONFIG = test_transport_api_reliability_tcp_nat_peer1.conf [nat] BEHIND_NAT = YES 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 c6020ff..b59916b 100644 --- a/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf +++ b/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-reliability-tcp-nat-p2/ -DEFAULTCONFIG = test_transport_api_reliability_tcp_nat_peer2.conf [nat] DISABLEV6 = YES diff --git a/src/transport/test_transport_api_reliability_tcp_peer1.conf b/src/transport/test_transport_api_reliability_tcp_peer1.conf index 3be982d..5f1d693 100644 --- a/src/transport/test_transport_api_reliability_tcp_peer1.conf +++ b/src/transport/test_transport_api_reliability_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_reliability_tcp_peer1.conf [transport-tcp] PORT = 12000 diff --git a/src/transport/test_transport_api_reliability_tcp_peer2.conf b/src/transport/test_transport_api_reliability_tcp_peer2.conf index 62575a9..181aab3 100644 --- a/src/transport/test_transport_api_reliability_tcp_peer2.conf +++ b/src/transport/test_transport_api_reliability_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_reliability_tcp_peer2.conf [transport-tcp] PORT = 12015 @@ -28,4 +27,3 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock PORT = 12010 PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock -#DEBUG = YES diff --git a/src/transport/test_transport_api_reliability_wlan_peer1.conf b/src/transport/test_transport_api_reliability_wlan_peer1.conf index 9dd9d1b..e81a3f9 100644 --- a/src/transport/test_transport_api_reliability_wlan_peer1.conf +++ b/src/transport/test_transport_api_reliability_wlan_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p1/ -DEFAULTCONFIG = test_transport_api_wlan_peer1.conf [transport-wlan] TESTMODE = 1 diff --git a/src/transport/test_transport_api_reliability_wlan_peer2.conf b/src/transport/test_transport_api_reliability_wlan_peer2.conf index bc868d7..bd53876 100644 --- a/src/transport/test_transport_api_reliability_wlan_peer2.conf +++ b/src/transport/test_transport_api_reliability_wlan_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p2/ -DEFAULTCONFIG = test_transport_api_wlan_peer2.conf [transport-wlan] INTERFACE = mon1 diff --git a/src/transport/test_transport_api_restart_1peer.c b/src/transport/test_transport_api_restart_1peer.c index b7fc7ab..9927946 100644 --- a/src/transport/test_transport_api_restart_1peer.c +++ b/src/transport/test_transport_api_restart_1peer.c @@ -26,19 +26,9 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" - -#define START_ARM GNUNET_YES - /** * How long until we give up on transmitting the message? */ @@ -156,7 +146,7 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) reconnect_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_TRANSPORT_try_connect (p->th, &p2->id); + GNUNET_TRANSPORT_try_connect (p->th, &p2->id, NULL, NULL); /*FIXME TRY_CONNECT change */ reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect, p); } @@ -437,9 +427,6 @@ check () GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif send_task = GNUNET_SCHEDULER_NO_TASK; ok = 1; diff --git a/src/transport/test_transport_api_restart_2peers.c b/src/transport/test_transport_api_restart_2peers.c index 1d7790c..6e55f57 100644 --- a/src/transport/test_transport_api_restart_2peers.c +++ b/src/transport/test_transport_api_restart_2peers.c @@ -26,18 +26,9 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" -#define START_ARM GNUNET_YES - /** * How long until we give up on transmitting the message? */ @@ -147,7 +138,7 @@ 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); + GNUNET_TRANSPORT_try_connect (p1->th, &p2->id, NULL, NULL); /*FIXME TRY_CONNECT change */ reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect, p); } @@ -417,9 +408,6 @@ check () GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif send_task = GNUNET_SCHEDULER_NO_TASK; ok = 1; diff --git a/src/transport/test_transport_api_tcp_nat_peer1.conf b/src/transport/test_transport_api_tcp_nat_peer1.conf index 73f36f3..8e33f27 100644 --- a/src/transport/test_transport_api_tcp_nat_peer1.conf +++ b/src/transport/test_transport_api_tcp_nat_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-nat-p1/ -DEFAULTCONFIG = test_transport_api_tcp_nat_peer1.conf [nat] BEHIND_NAT = YES @@ -33,5 +32,4 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock 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 0bf50fd..f8b8b01 100644 --- a/src/transport/test_transport_api_tcp_nat_peer2.conf +++ b/src/transport/test_transport_api_tcp_nat_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-nat-p2/ -DEFAULTCONFIG = test_transport_api_tcp_nat_peer2.conf [nat] DISABLEV6 = YES @@ -32,4 +31,3 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock 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 9532b73..db66282 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_tcp_peer1.conf [transport-tcp] PORT = 12000 @@ -28,5 +27,4 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock 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 fe6d19b..67f171e 100644 --- a/src/transport/test_transport_api_tcp_peer2.conf +++ b/src/transport/test_transport_api_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_tcp_peer2.conf [transport-tcp] PORT = 12015 diff --git a/src/transport/test_transport_api_timeout.c b/src/transport/test_transport_api_timeout.c index 8b92dce..2645739 100644 --- a/src/transport/test_transport_api_timeout.c +++ b/src/transport/test_transport_api_timeout.c @@ -28,20 +28,9 @@ */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * How long until we give up on transmitting the message? */ @@ -305,9 +294,6 @@ check () GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif timer_task = GNUNET_SCHEDULER_NO_TASK; ok = 1; diff --git a/src/transport/test_transport_api_timeout_http_peer1.conf b/src/transport/test_transport_api_timeout_http_peer1.conf index a28750a..665527b 100644 --- a/src/transport/test_transport_api_timeout_http_peer1.conf +++ b/src/transport/test_transport_api_timeout_http_peer1.conf @@ -1,12 +1,10 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p1/ -DEFAULTCONFIG = test_transport_api_http_peer1.conf [nat] -[transport-http] -PORT = 12080 +[transport-http_client] [arm] PORT = 12085 @@ -26,9 +24,8 @@ PORT = 12082 UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] -#DEBUG = YES PORT = 12081 -PLUGINS = http +PLUGINS = http_client #BINARY = .libs/gnunet-service-transport UNIXPATH = /tmp/gnunet-p1-service-transport.sock #PREFIX = valgrind --leak-check=full diff --git a/src/transport/test_transport_api_timeout_http_peer2.conf b/src/transport/test_transport_api_timeout_http_peer2.conf index 1269358..1fdc947 100644 --- a/src/transport/test_transport_api_timeout_http_peer2.conf +++ b/src/transport/test_transport_api_timeout_http_peer2.conf @@ -1,12 +1,14 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-http-p2/ -DEFAULTCONFIG = test_transport_api_http_peer2.conf [nat] -[transport-http] +[transport-http_server] PORT = 12090 +USE_IPv6 = NO +BINDTO = 127.0.0.1 + [arm] PORT = 12095 @@ -26,8 +28,7 @@ PORT = 12092 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -#DEBUG = YES PORT = 12091 -PLUGINS = http +PLUGINS = http_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock #PREFIX = valgrind --leak-check=full diff --git a/src/transport/test_transport_api_timeout_https_peer1.conf b/src/transport/test_transport_api_timeout_https_peer1.conf index 8a93ca1..fda69ae 100644 --- a/src/transport/test_transport_api_timeout_https_peer1.conf +++ b/src/transport/test_transport_api_timeout_https_peer1.conf @@ -1,12 +1,8 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p1/ -DEFAULTCONFIG = test_transport_api_https_peer1.conf -[transport-https] -PORT = 12100 -KEY_FILE = $SERVICEHOME/https_key_p1.key -CERT_FILE = $SERVICEHOME/https_cert_p1.crt +[transport-https_client] [arm] PORT = 12105 @@ -25,8 +21,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12101 -PLUGINS = https +PLUGINS = https_client UNIXPATH = /tmp/gnunet-p1-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_timeout_https_peer2.conf b/src/transport/test_transport_api_timeout_https_peer2.conf index 0710f41..ca54e17 100644 --- a/src/transport/test_transport_api_timeout_https_peer2.conf +++ b/src/transport/test_transport_api_timeout_https_peer2.conf @@ -1,9 +1,8 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-https-p2/ -DEFAULTCONFIG = test_transport_api_https_peer2.conf -[transport-https] +[transport-https_server] PORT = 12110 KEY_FILE = $SERVICEHOME/https_key_p2.key CERT_FILE = $SERVICEHOME/https_cert_p2.crt @@ -26,8 +25,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12111 -PLUGINS = https +PLUGINS = https_server UNIXPATH = /tmp/gnunet-p2-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_timeout_tcp_peer1.conf b/src/transport/test_transport_api_timeout_tcp_peer1.conf index ecb599f..dceeccb 100644 --- a/src/transport/test_transport_api_timeout_tcp_peer1.conf +++ b/src/transport/test_transport_api_timeout_tcp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p1/ -DEFAULTCONFIG = test_transport_api_timeout_tcp_peer1.conf [transport-tcp] PORT = 12000 diff --git a/src/transport/test_transport_api_timeout_tcp_peer2.conf b/src/transport/test_transport_api_timeout_tcp_peer2.conf index ba2e27e..f89c3a3 100644 --- a/src/transport/test_transport_api_timeout_tcp_peer2.conf +++ b/src/transport/test_transport_api_timeout_tcp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-tcp-p2/ -DEFAULTCONFIG = test_transport_api_timeout_tcp_peer2.conf [nat] ALLOW_NAT = NO diff --git a/src/transport/test_transport_api_timeout_udp_peer1.conf b/src/transport/test_transport_api_timeout_udp_peer1.conf index a1216e4..7c3e33a 100644 --- a/src/transport/test_transport_api_timeout_udp_peer1.conf +++ b/src/transport/test_transport_api_timeout_udp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p1/ -DEFAULTCONFIG = test_transport_api_udp_peer1.conf [transport-udp] PORT = 12040 diff --git a/src/transport/test_transport_api_timeout_udp_peer2.conf b/src/transport/test_transport_api_timeout_udp_peer2.conf index 3e487a6..9b79c3b 100644 --- a/src/transport/test_transport_api_timeout_udp_peer2.conf +++ b/src/transport/test_transport_api_timeout_udp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p2/ -DEFAULTCONFIG = test_transport_api_udp_peer2.conf [transport-udp] PORT = 12050 diff --git a/src/transport/test_transport_api_timeout_unix_peer1.conf b/src/transport/test_transport_api_timeout_unix_peer1.conf index b1ace7d..5d0235f 100644 --- a/src/transport/test_transport_api_timeout_unix_peer1.conf +++ b/src/transport/test_transport_api_timeout_unix_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p1/ -DEFAULTCONFIG = test_transport_api_unix_peer1.conf [arm] PORT = 12125 diff --git a/src/transport/test_transport_api_timeout_unix_peer2.conf b/src/transport/test_transport_api_timeout_unix_peer2.conf index a153588..255c7e2 100644 --- a/src/transport/test_transport_api_timeout_unix_peer2.conf +++ b/src/transport/test_transport_api_timeout_unix_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p2/ -DEFAULTCONFIG = test_transport_api_unix_peer2.conf [arm] PORT = 12135 diff --git a/src/transport/test_transport_api_udp_nat_peer1.conf b/src/transport/test_transport_api_udp_nat_peer1.conf index 16a4e62..e406883 100644 --- a/src/transport/test_transport_api_udp_nat_peer1.conf +++ b/src/transport/test_transport_api_udp_nat_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-nat-p1/ -DEFAULTCONFIG = test_transport_api_udp_nat_peer1.conf [nat] BEHIND_NAT = YES @@ -32,6 +31,5 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock PORT = 12061 PLUGINS = udp UNIXPATH = /tmp/gnunet-p1-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_udp_nat_peer2.conf b/src/transport/test_transport_api_udp_nat_peer2.conf index 0852b25..43ed3a9 100644 --- a/src/transport/test_transport_api_udp_nat_peer2.conf +++ b/src/transport/test_transport_api_udp_nat_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-nat-p2/ -DEFAULTCONFIG = test_transport_api_udp_nat_peer2.conf [nat] ALLOW_NAT = YES @@ -30,6 +29,5 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock PORT = 12071 PLUGINS = udp UNIXPATH = /tmp/gnunet-p2-service-transport.sock -DEBUG = NO diff --git a/src/transport/test_transport_api_udp_peer1.conf b/src/transport/test_transport_api_udp_peer1.conf index a1216e4..7c3e33a 100644 --- a/src/transport/test_transport_api_udp_peer1.conf +++ b/src/transport/test_transport_api_udp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p1/ -DEFAULTCONFIG = test_transport_api_udp_peer1.conf [transport-udp] PORT = 12040 diff --git a/src/transport/test_transport_api_udp_peer2.conf b/src/transport/test_transport_api_udp_peer2.conf index 3e487a6..9b79c3b 100644 --- a/src/transport/test_transport_api_udp_peer2.conf +++ b/src/transport/test_transport_api_udp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p2/ -DEFAULTCONFIG = test_transport_api_udp_peer2.conf [transport-udp] PORT = 12050 diff --git a/src/transport/test_transport_api_unix_peer1.conf b/src/transport/test_transport_api_unix_peer1.conf index b1ace7d..5d0235f 100644 --- a/src/transport/test_transport_api_unix_peer1.conf +++ b/src/transport/test_transport_api_unix_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p1/ -DEFAULTCONFIG = test_transport_api_unix_peer1.conf [arm] PORT = 12125 diff --git a/src/transport/test_transport_api_unix_peer2.conf b/src/transport/test_transport_api_unix_peer2.conf index a153588..255c7e2 100644 --- a/src/transport/test_transport_api_unix_peer2.conf +++ b/src/transport/test_transport_api_unix_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p2/ -DEFAULTCONFIG = test_transport_api_unix_peer2.conf [arm] PORT = 12135 diff --git a/src/transport/test_transport_api_unreliability.c b/src/transport/test_transport_api_unreliability.c index 53de91a..3658198 100644 --- a/src/transport/test_transport_api_unreliability.c +++ b/src/transport/test_transport_api_unreliability.c @@ -27,24 +27,10 @@ * achieve reliable message delivery. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_os_lib.h" -#include "gnunet_program_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" #include "gnunet_transport_service.h" #include "gauger.h" -#include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES - /** * Testcase timeout */ @@ -85,6 +71,8 @@ struct GNUNET_TRANSPORT_TESTING_handle *tth; */ /** + * Total number of messages to send + * * Note that this value must not significantly exceed * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise * messages may be dropped even for a reliable transport. @@ -175,7 +163,7 @@ end () { if (get_bit (bitmap, i) == 0) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Did not receive message %d\n", i); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Did not receive message %d\n", i); ok = -1; } } @@ -203,6 +191,16 @@ end_badly () GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test had timeout while waiting to send data\n"); + int i; + + for (i = 0; i < TOTAL_MSGS; i++) + { + if (get_bit (bitmap, i) == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Did not receive message %d\n", i); + ok = -1; + } + } if (th != NULL) GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); @@ -244,8 +242,9 @@ get_size (unsigned int iter) * Sets a bit active in the bitmap. * * @param bitIdx which bit to set + * @return GNUNET_SYSERR on error, GNUNET_OK on success */ -static void +static int set_bit (unsigned int bitIdx) { size_t arraySlot; @@ -253,13 +252,14 @@ set_bit (unsigned int bitIdx) if (bitIdx >= sizeof (bitmap) * 8) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "tried to set bit %d of %d(!?!?)\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "tried to set bit %d of %d(!?!?)\n", bitIdx, sizeof (bitmap) * 8); - return; + return GNUNET_SYSERR; } arraySlot = bitIdx / 8; targetBit = (1L << (bitIdx % 8)); bitmap[arraySlot] |= targetBit; + return GNUNET_OK; } /** @@ -272,7 +272,7 @@ set_bit (unsigned int bitIdx) static int get_bit (const char *map, unsigned int bit) { - if (bit >= TOTAL_MSGS) + if (bit > TOTAL_MSGS) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "get bit %d of %d(!?!?)\n", bit, sizeof (bitmap) * 8); @@ -333,7 +333,12 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, } #endif n++; - set_bit (ntohl (hdr->num)); + if (GNUNET_SYSERR == set_bit (ntohl (hdr->num))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Message id %u is bigger than maxmimum number of messages %u expected\n"), + ntohl (hdr->num), TOTAL_MSGS); + } test_sending = GNUNET_YES; if (0 == (n % (TOTAL_MSGS / 100))) { @@ -376,9 +381,11 @@ notify_ready (void *cls, size_t size, void *buf) s = get_size (n); GNUNET_assert (size >= s); GNUNET_assert (buf != NULL); + GNUNET_assert (n < TOTAL_MSGS); cbuf = buf; do { + GNUNET_assert (n < TOTAL_MSGS); hdr.header.size = htons (s); hdr.header.type = htons (MTYPE); hdr.num = htonl (n); @@ -387,20 +394,20 @@ notify_ready (void *cls, size_t size, void *buf) ret += sizeof (struct TestMessage); memset (&cbuf[ret], n, s - sizeof (struct TestMessage)); ret += s - sizeof (struct TestMessage); + #if VERBOSE if (n % 5000 == 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message %u of size %u\n", n, s); } - #endif n++; s = get_size (n); if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16)) break; /* sometimes pack buffer full, sometimes not */ } - while (size - ret >= s); + while ((size - ret >= s) && (n < TOTAL_MSGS)); if (n < TOTAL_MSGS) { th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, s, 0, @@ -450,6 +457,8 @@ static void sendtask () { start_time = GNUNET_TIME_absolute_get (); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to send %u messages\n", + TOTAL_MSGS); th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, get_size (0), 0, TIMEOUT_TRANSMIT, ¬ify_ready, NULL); @@ -525,9 +534,6 @@ check () static char *const argv[] = { "test-transport-api-unreliability", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -553,11 +559,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_unreliability_constant.c b/src/transport/test_transport_api_unreliability_constant.c index fb72b0f..cb24675 100644 --- a/src/transport/test_transport_api_unreliability_constant.c +++ b/src/transport/test_transport_api_unreliability_constant.c @@ -27,24 +27,10 @@ * achieve reliable message delivery. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_os_lib.h" -#include "gnunet_program_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" #include "gnunet_transport_service.h" #include "gauger.h" -#include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES - /** * Testcase timeout */ @@ -464,18 +450,12 @@ check () static char *const argv[] = { "test-transport-api-unreliability-constant", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; -#if WRITECONFIG - setTransportOptions ("test_transport_api_data.conf"); -#endif ok = GNUNET_SYSERR; GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, @@ -492,11 +472,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_unreliability_constant_udp_peer1.conf b/src/transport/test_transport_api_unreliability_constant_udp_peer1.conf index d872f02..a4fd104 100644 --- a/src/transport/test_transport_api_unreliability_constant_udp_peer1.conf +++ b/src/transport/test_transport_api_unreliability_constant_udp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p1/ -DEFAULTCONFIG = test_transport_api_unreliability_constant_udp_peer1.conf [transport-udp] PORT = 12040 diff --git a/src/transport/test_transport_api_unreliability_constant_udp_peer2.conf b/src/transport/test_transport_api_unreliability_constant_udp_peer2.conf index 50ee65a..755e65d 100644 --- a/src/transport/test_transport_api_unreliability_constant_udp_peer2.conf +++ b/src/transport/test_transport_api_unreliability_constant_udp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p2/ -DEFAULTCONFIG = test_transport_api_unreliability_constant_udp_peer2.conf [transport-udp] PORT = 12050 diff --git a/src/transport/test_transport_api_unreliability_udp_peer1.conf b/src/transport/test_transport_api_unreliability_udp_peer1.conf index 8a5a405..b9669bf 100644 --- a/src/transport/test_transport_api_unreliability_udp_peer1.conf +++ b/src/transport/test_transport_api_unreliability_udp_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p1/ -DEFAULTCONFIG = test_transport_api_unreliability_udp_peer1.conf [transport-udp] PORT = 12040 diff --git a/src/transport/test_transport_api_unreliability_udp_peer2.conf b/src/transport/test_transport_api_unreliability_udp_peer2.conf index d240c42..46ad017 100644 --- a/src/transport/test_transport_api_unreliability_udp_peer2.conf +++ b/src/transport/test_transport_api_unreliability_udp_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-udp-p2/ -DEFAULTCONFIG = test_transport_api_unreliability_udp_peer2.conf [transport-udp] PORT = 12050 diff --git a/src/transport/test_transport_api_unreliability_unix_peer1.conf b/src/transport/test_transport_api_unreliability_unix_peer1.conf index 8689e41..5d0235f 100644 --- a/src/transport/test_transport_api_unreliability_unix_peer1.conf +++ b/src/transport/test_transport_api_unreliability_unix_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p1/ -DEFAULTCONFIG = test_transport_api_unreliability_unix_peer1.conf [arm] PORT = 12125 diff --git a/src/transport/test_transport_api_unreliability_unix_peer2.conf b/src/transport/test_transport_api_unreliability_unix_peer2.conf index 7c3cc19..c9dab48 100644 --- a/src/transport/test_transport_api_unreliability_unix_peer2.conf +++ b/src/transport/test_transport_api_unreliability_unix_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-unix-p2/ -DEFAULTCONFIG = test_transport_api_unreliability_unix_peer2.conf [arm] PORT = 12135 diff --git a/src/transport/test_transport_api_unreliability_wlan_peer1.conf b/src/transport/test_transport_api_unreliability_wlan_peer1.conf index 9dd9d1b..e81a3f9 100644 --- a/src/transport/test_transport_api_unreliability_wlan_peer1.conf +++ b/src/transport/test_transport_api_unreliability_wlan_peer1.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p1/ -DEFAULTCONFIG = test_transport_api_wlan_peer1.conf [transport-wlan] TESTMODE = 1 diff --git a/src/transport/test_transport_api_unreliability_wlan_peer2.conf b/src/transport/test_transport_api_unreliability_wlan_peer2.conf index bc868d7..bd53876 100644 --- a/src/transport/test_transport_api_unreliability_wlan_peer2.conf +++ b/src/transport/test_transport_api_unreliability_wlan_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p2/ -DEFAULTCONFIG = test_transport_api_wlan_peer2.conf [transport-wlan] INTERFACE = mon1 diff --git a/src/transport/test_transport_api_wlan_peer1.conf b/src/transport/test_transport_api_wlan_peer1.conf index e379cf0..3f12ce5 100644 --- a/src/transport/test_transport_api_wlan_peer1.conf +++ b/src/transport/test_transport_api_wlan_peer1.conf @@ -1,14 +1,12 @@ @INLINE@ template_cfg_peer1.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p1/ -DEFAULTCONFIG = test_transport_api_wlan_peer1.conf [transport-wlan] INTERFACE = mon0 TESTMODE = 1 [arm] -DEBUG = YES PORT = 12164 UNIXPATH = /tmp/gnunet-p1-service-arm.sock @@ -27,7 +25,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12160 PLUGINS = wlan -#DEBUG = YES UNIXPATH = /tmp/gnunet-p1-service-transport.sock #PREFIX = xterm -T transport2 -e gdb --command=cmd --args #PREFIX = valgrind --leak-check=full --show-reachable=yes --main-stacksize=104857600 diff --git a/src/transport/test_transport_api_wlan_peer2.conf b/src/transport/test_transport_api_wlan_peer2.conf index 3e0ce27..451a2a6 100644 --- a/src/transport/test_transport_api_wlan_peer2.conf +++ b/src/transport/test_transport_api_wlan_peer2.conf @@ -1,7 +1,6 @@ @INLINE@ template_cfg_peer2.conf [PATHS] SERVICEHOME = /tmp/test-transport/api-wlan-p2/ -DEFAULTCONFIG = test_transport_api_wlan_peer2.conf [transport-wlan] INTERFACE = mon1 @@ -9,7 +8,6 @@ TESTMODE = 2 [arm] PORT = 12174 -DEBUG = YES UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] @@ -27,7 +25,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12170 PLUGINS = wlan -#DEBUG = YES UNIXPATH = /tmp/gnunet-p2-service-transport.sock #PREFIX = xterm -T transport2 -e gdb --command=cmd --args #PREFIX = valgrind --leak-check=full --show-reachable=yes --main-stacksize=104857600 diff --git a/src/transport/test_transport_defaults.conf b/src/transport/test_transport_defaults.conf index 0939a79..48814b7 100644 --- a/src/transport/test_transport_defaults.conf +++ b/src/transport/test_transport_defaults.conf @@ -1,6 +1,5 @@ [PATHS] SERVICEHOME = /tmp/test-transport-api/ -DEFAULTCONFIG = test_transport_defaults.conf [transport-tcp] TIMEOUT = 300 s @@ -50,6 +49,9 @@ AUTOSTART = NO [lockmanager] AUTOSTART = NO +[consensus] +AUTOSTART = NO + [nat] DISABLEV6 = YES BINDTO = 127.0.0.1 diff --git a/src/transport/test_transport_startonly.c b/src/transport/test_transport_startonly.c index 79578ab..8a8fef1 100644 --- a/src/transport/test_transport_startonly.c +++ b/src/transport/test_transport_startonly.c @@ -27,22 +27,9 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "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? */ @@ -72,6 +59,7 @@ end () GNUNET_SCHEDULER_cancel (timeout_task); timeout_task = GNUNET_SCHEDULER_NO_TASK; } + GNUNET_TRANSPORT_TESTING_done (tth); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Exiting\n"); } @@ -86,7 +74,8 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (p1 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); - + if (NULL != tth) + GNUNET_TRANSPORT_TESTING_done (tth); ret = GNUNET_SYSERR; } @@ -150,8 +139,6 @@ run (void *cls, char *const *args, const char *cfgfile, FPRINTF (stderr, "..%i", i); } - tth = GNUNET_TRANSPORT_TESTING_init (); - FPRINTF (stderr, "%s", "\n"); end (); } @@ -160,19 +147,13 @@ int main (int argc, char *argv[]) { GNUNET_log_setup ("test_transport_testing", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif + NULL); char *const argv_1[] = { "test_transport_testing", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; diff --git a/src/transport/test_transport_startonly.conf b/src/transport/test_transport_startonly.conf index 255df4c..8e16138 100644 --- a/src/transport/test_transport_startonly.conf +++ b/src/transport/test_transport_startonly.conf @@ -1,6 +1,5 @@ @INLINE@ test_transport_defaults.conf [PATHS] -DEFAULTCONFIG = test_transport_api_data.conf [arm] DEFAULTSERVICES = transport diff --git a/src/transport/test_transport_testing.c b/src/transport/test_transport_testing.c index 842d686..9db5913 100644 --- a/src/transport/test_transport_testing.c +++ b/src/transport/test_transport_testing.c @@ -27,22 +27,8 @@ * C code apparently. */ #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_hello_lib.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 "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? */ @@ -81,12 +67,19 @@ end_badly () timeout_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n"); + if (NULL != cc) + { + GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc); + cc = NULL; + } + if (p1 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); if (p2 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); - GNUNET_TRANSPORT_TESTING_done (tth); + if (NULL != tth) + GNUNET_TRANSPORT_TESTING_done (tth); ret = GNUNET_SYSERR; } @@ -167,15 +160,11 @@ run (void *cls, char *const *args, const char *cfgfile, 1, ¬ify_receive, ¬ify_connect, ¬ify_disconnect, &start_cb, p1); - GNUNET_assert (p1->hostkeyfile != NULL); - p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, "test_transport_api_tcp_peer2.conf", 2, ¬ify_receive, ¬ify_connect, ¬ify_disconnect, &start_cb, p2); - GNUNET_assert (p2->hostkeyfile != NULL); - if (p1 == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -198,19 +187,12 @@ int main (int argc, char *argv[]) { GNUNET_log_setup ("test_transport_testing", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); char *const argv_1[] = { "test_transport_testing", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; diff --git a/src/transport/test_transport_testing_restart.c b/src/transport/test_transport_testing_restart.c new file mode 100644 index 0000000..8ca18f9 --- /dev/null +++ b/src/transport/test_transport_testing_restart.c @@ -0,0 +1,151 @@ +/* + 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 transport/test_transport_testing_restart.c + * @brief test case for transport testing library: + * start the peer, get the HELLO message, restart and stop the peer + * + */ +#include "platform.h" +#include "gnunet_transport_service.h" +#include "transport-testing.h" + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +static struct PeerContext *p; + +struct GNUNET_TRANSPORT_TESTING_handle *tth; + +static int ret = 0; + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n"); + + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (timeout_task); + + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + GNUNET_TRANSPORT_TESTING_done (tth); +} + +static void +end_badly () +{ + timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n"); + + if (NULL != p) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + + if (NULL != tth) + GNUNET_TRANSPORT_TESTING_done (tth); + + ret = GNUNET_SYSERR; +} + +static void +restart_cb (struct PeerContext *p, void *cls) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') successfully restarted\n", + p->no, + GNUNET_i2s (&p->id)); + + ret = 0; + GNUNET_SCHEDULER_add_now (&end, NULL); +} + + +static void +restart_task () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') restarting, \n", + p->no, + GNUNET_i2s (&p->id)); + GNUNET_TRANSPORT_TESTING_restart_peer (tth, p, NULL, restart_cb, p); +} + +static void +start_cb (struct PeerContext *p, void *cls) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') successfully started\n", + p->no, + GNUNET_i2s (&p->id)); + + GNUNET_SCHEDULER_add_now (&restart_task, NULL); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + ret = 1; + tth = GNUNET_TRANSPORT_TESTING_init (); + GNUNET_assert (NULL != tth); + + timeout_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &end_badly, NULL); + + p = GNUNET_TRANSPORT_TESTING_start_peer(tth, cfgfile, 1, + NULL, /* receive cb */ + NULL, /* connect cb */ + NULL, /* disconnect cb */ + start_cb, /* startup cb */ + NULL); /* closure */ + if (NULL == p) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start peer\n"); + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + } +} + +int +main (int argc, char *argv[]) +{ + GNUNET_log_setup ("test_transport_testing_restart", + "WARNING", + NULL); + + char *const argv_1[] = { "test_transport_testing_restart", + "-c", + "test_transport_api_data.conf", + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_PROGRAM_run ((sizeof (argv_1) / sizeof (char *)) - 1, argv_1, + "test_transport_testing_restart", "nohelp", options, &run, &ret); + + return ret; +} + +/* end of test_transport_testing_restart.c */ diff --git a/src/transport/test_transport_testing_startstop.c b/src/transport/test_transport_testing_startstop.c new file mode 100644 index 0000000..22a4e51 --- /dev/null +++ b/src/transport/test_transport_testing_startstop.c @@ -0,0 +1,132 @@ +/* + 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 transport/test_transport_testing_startstop.c + * @brief test case for transport testing library: + * start the peer, get the HELLO message and stop the peer + * + */ +#include "platform.h" +#include "gnunet_transport_service.h" +#include "transport-testing.h" + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + +GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +static struct PeerContext *p; + +struct GNUNET_TRANSPORT_TESTING_handle *tth; + +static int ret = 0; + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n"); + + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (timeout_task); + + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + GNUNET_TRANSPORT_TESTING_done (tth); +} + +static void +end_badly () +{ + timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n"); + + if (NULL != p) + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + + if (NULL != tth) + GNUNET_TRANSPORT_TESTING_done (tth); + + ret = GNUNET_SYSERR; +} + + +static void +start_cb (struct PeerContext *p, void *cls) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') successfully started\n", + p->no, + GNUNET_i2s (&p->id)); + + ret = 0; + GNUNET_SCHEDULER_add_now (&end, NULL); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + ret = 1; + tth = GNUNET_TRANSPORT_TESTING_init (); + GNUNET_assert (NULL != tth); + + timeout_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &end_badly, NULL); + + p = GNUNET_TRANSPORT_TESTING_start_peer(tth, cfgfile, 1, + NULL, /* receive cb */ + NULL, /* connect cb */ + NULL, /* disconnect cb */ + start_cb, /* startup cb */ + NULL); /* closure */ + if (NULL == p) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start peer\n"); + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); + } +} + +int +main (int argc, char *argv[]) +{ + GNUNET_log_setup ("test_transport_testing_startstop", + "WARNING", + NULL); + + char *const argv_1[] = { "test_transport_testing", + "-c", + "test_transport_api_data.conf", + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_PROGRAM_run ((sizeof (argv_1) / sizeof (char *)) - 1, argv_1, + "test_transport_testing_startstop", "nohelp", options, &run, &ret); + + return ret; +} + +/* end of test_transport_testing_startstop.c */ diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c index 695c048..32331d9 100644 --- a/src/transport/transport-testing.c +++ b/src/transport/transport-testing.c @@ -27,31 +27,6 @@ #include "transport-testing.h" -#define HOSTKEYFILESIZE 914 - -static const char * -get_host_key (struct GNUNET_TRANSPORT_TESTING_handle *tth) -{ - if (tth->hostkey_data == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "No precomputed hostkeys available\n"); - return NULL; - } - if (tth->hostkeys_total > tth->hostkeys_last) - { - tth->hostkeys_last++; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Used hostkey %u of %u available hostkeys\n", - tth->hostkeys_last, tth->hostkeys_total); - return &tth->hostkey_data[(tth->hostkeys_last - 1) * HOSTKEYFILESIZE]; - } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "No hostkey available (%u of %u already used)\n", - tth->hostkeys_last, tth->hostkeys_total); - return NULL; -} - static struct PeerContext * find_peer_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, @@ -96,19 +71,15 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { struct PeerContext *p = cls; + char *p2_s; + struct PeerContext *p2; - /* Find PeerContext */ - GNUNET_assert (p != 0); - GNUNET_assert (p->tth != NULL); - struct PeerContext *p2 = find_peer_context (p->tth, peer); - - if (p == NULL) - return; + GNUNET_assert (NULL != p); + GNUNET_assert (NULL != p->tth); + p2 = find_peer_context (p->tth, peer); if (p->nc != NULL) p->nc (p->cb_cls, peer, ats, ats_count); - char *p2_s; - if (p2 != NULL) GNUNET_asprintf (&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id)); else @@ -190,20 +161,21 @@ static void get_hello (void *cb_cls, const struct GNUNET_MessageHeader *message) { struct PeerContext *p = cb_cls; + struct GNUNET_PeerIdentity hello_id; GNUNET_assert (message != NULL); GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) - message, &p->id)); + message, &hello_id)); + GNUNET_assert (0 == memcmp (&hello_id, &p->id, sizeof (hello_id))); GNUNET_free_non_null (p->hello); p->hello = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (message); - if (p->start_cb != NULL) + if (NULL != p->start_cb) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Peer %u (`%s') successfully started\n", p->no, GNUNET_i2s (&p->id)); - p->start_cb (p, p->cb_cls); p->start_cb = NULL; } @@ -236,7 +208,7 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TRANSPORT_offer_hello (cc->th_p1, (const struct GNUNET_MessageHeader *) cc-> p2->hello, NULL, NULL); - GNUNET_TRANSPORT_try_connect (cc->th_p1, &p2->id); + GNUNET_TRANSPORT_try_connect (cc->th_p1, &p2->id, NULL, NULL); /*FIXME TRY_CONNECT change */ cc->tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &try_connect, cc); @@ -247,7 +219,7 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Start a peer with the given configuration * @param tth the testing handle * @param cfgname configuration file - * @param peer_id the peer_id + * @param peer_id a unique number to identify the peer * @param rec receive callback * @param nc connect callback * @param nd disconnect callback @@ -256,18 +228,20 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @return the peer context */ struct PeerContext * -GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle - *tth, const char *cfgname, int peer_id, +GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, + const char *cfgname, int peer_id, GNUNET_TRANSPORT_ReceiveCallback rec, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd, GNUNET_TRANSPORT_TESTING_start_cb start_cb, void *cb_cls) { - const char *hostkey = NULL; - struct GNUNET_DISK_FileHandle *fn; + char *emsg = NULL; + struct GNUNET_PeerIdentity *dummy; + + GNUNET_assert (NULL != tth); + GNUNET_assert (NULL != tth->tl_system); - GNUNET_assert (tth != NULL); if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", @@ -276,47 +250,61 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle } struct PeerContext *p = GNUNET_malloc (sizeof (struct PeerContext)); + GNUNET_CONTAINER_DLL_insert (tth->p_head, tth->p_tail, p); + /* Create configuration and call testing lib to modify it */ p->cfg = GNUNET_CONFIGURATION_create (); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); - if (GNUNET_CONFIGURATION_have_value (p->cfg, "PATHS", "SERVICEHOME")) - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (p->cfg, "PATHS", - "SERVICEHOME", - &p->servicehome)); - - if (NULL != p->servicehome) - GNUNET_DISK_directory_remove (p->servicehome); + if (GNUNET_SYSERR == GNUNET_TESTING_configuration_create (tth->tl_system, p->cfg)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Testing library failed to create unique configuration based on `%s'\n", + cfgname); + GNUNET_free (p); + return NULL; + } - hostkey = get_host_key (tth); - if (hostkey != NULL) + p->no = peer_id; + /* Configure peer with configuration */ + p->peer = GNUNET_TESTING_peer_configure (tth->tl_system, p->cfg, p->no, NULL, &emsg); + if (NULL == p->peer) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Testing library failed to create unique configuration based on `%s': `%s'\n", + cfgname, emsg); + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + GNUNET_free_non_null (emsg); + return NULL; + } + GNUNET_free_non_null (emsg); + if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer)) { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Testing library failed to create unique configuration based on `%s'\n", + cfgname); + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + return NULL; + } - GNUNET_asprintf (&p->hostkeyfile, "%s/.hostkey", p->servicehome); - GNUNET_assert (GNUNET_OK == - GNUNET_DISK_directory_create_for_file (p->hostkeyfile)); - fn = GNUNET_DISK_file_open (p->hostkeyfile, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - GNUNET_assert (fn != NULL); - GNUNET_assert (HOSTKEYFILESIZE == - GNUNET_DISK_file_write (fn, hostkey, HOSTKEYFILESIZE)); - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fn)); + memset(&dummy, '\0', sizeof (dummy)); + GNUNET_TESTING_peer_get_identity (p->peer, &p->id); + if (0 == memcmp (&dummy, &p->id, sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Testing library failed to obtain peer identity for peer %u\n", + p->no); + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + return NULL; + } + else + { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Wrote hostkey to file: `%s' \n", p->hostkeyfile); + "Peer %u configured with identity `%s'\n", + p->no, + GNUNET_i2s (&p->id)); } - p->arm_proc = - GNUNET_OS_start_process (GNUNET_YES, - NULL, NULL, "gnunet-service-arm", - "gnunet-service-arm", "-c", cfgname, - "-L", "ERROR", - NULL); - - p->no = peer_id; p->tth = tth; p->nc = nc; p->nd = nd; @@ -327,15 +315,21 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle else p->cb_cls = p; - p->th = - GNUNET_TRANSPORT_connect (p->cfg, NULL, p, ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); - GNUNET_assert (p->th != NULL); + p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + if (NULL == p->th) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Failed to connect to transport service for peer `%s': `%s'\n", + cfgname, emsg); + GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); + return NULL; + } p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &get_hello, p); GNUNET_assert (p->ghh != NULL); - GNUNET_CONTAINER_DLL_insert (tth->p_head, tth->p_tail, p); return p; } @@ -355,93 +349,55 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_handle GNUNET_TRANSPORT_TESTING_start_cb restart_cb, void *cb_cls) { - struct GNUNET_DISK_FileHandle *fn; - GNUNET_assert (tth != NULL); GNUNET_assert (p != NULL); - GNUNET_assert (p->hostkeyfile != NULL); - GNUNET_assert (p->servicehome != NULL); + GNUNET_assert (NULL != p->peer); + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", + "Restarting peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); /* shutdown */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Stopping peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); - if (p->ghh != NULL) + if (NULL != p->ghh) GNUNET_TRANSPORT_get_hello_cancel (p->ghh); p->ghh = NULL; - if (p->th != NULL) + if (NULL != p->th) GNUNET_TRANSPORT_disconnect (p->th); - if (NULL != p->arm_proc) + if (GNUNET_SYSERR == GNUNET_TESTING_peer_stop(p->peer)) { - 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_destroy (p->arm_proc); - p->arm_proc = NULL; + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", + "Failed to stop peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); + return GNUNET_SYSERR; } - if (p->hello != NULL) - GNUNET_free (p->hello); - p->hello = NULL; - if (p->cfg != NULL) - GNUNET_CONFIGURATION_destroy (p->cfg); - p->cfg = NULL; + sleep (5); - - /* start */ - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Restarting peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); - sleep (5); // YUCK! - - if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO) + /* restart */ + if (GNUNET_SYSERR == GNUNET_TESTING_peer_start(p->peer)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", - "File not found: `%s' \n", cfgname); - goto fail; + "Failed to restart peer %u (`%s')\n", + p->no, GNUNET_i2s (&p->id)); + return GNUNET_SYSERR; } - p->cfg = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); - - if (!GNUNET_CONFIGURATION_have_value (p->cfg, "PATHS", "SERVICEHOME")) - goto fail; - - fn = GNUNET_DISK_file_open (p->hostkeyfile, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (fn == NULL) - goto fail; - if (GNUNET_OK != GNUNET_DISK_file_close (fn)) - goto fail; - - p->arm_proc = - GNUNET_OS_start_process (GNUNET_YES, - NULL, NULL, "gnunet-service-arm", - "gnunet-service-arm", "-c", cfgname, - "-L", "ERROR", - NULL); - - p->th = - GNUNET_TRANSPORT_connect (p->cfg, NULL, p, ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); GNUNET_assert (p->th != NULL); - + GNUNET_assert (p->start_cb == NULL); p->start_cb = restart_cb; p->cb_cls = cb_cls; + p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p, + ¬ify_receive, + ¬ify_connect, + ¬ify_disconnect); + GNUNET_assert (NULL != p->th); + p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &get_hello, p); GNUNET_assert (p->ghh != NULL); return GNUNET_OK; - -fail: - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Restarting peer %u (`%s') failed, removing peer\n", p->no, - GNUNET_i2s (&p->id)); - GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); - return GNUNET_SYSERR; } @@ -461,25 +417,23 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, 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_destroy (p->arm_proc); - p->arm_proc = NULL; - } - if (p->hostkeyfile != NULL) { - GNUNET_DISK_directory_remove (p->hostkeyfile); - GNUNET_free (p->hostkeyfile); + GNUNET_TRANSPORT_disconnect (p->th); + p->th = NULL; } - if (p->servicehome != NULL) + + if (p->peer != NULL) { - GNUNET_DISK_directory_remove (p->servicehome); - GNUNET_free (p->servicehome); + if (GNUNET_OK != GNUNET_TESTING_peer_stop (p->peer)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", + "Testing lib failed to stop peer %u (`%s') \n", p->no, + GNUNET_i2s (&p->id)); + } + GNUNET_TESTING_peer_destroy (p->peer); + p->peer = NULL; } + if (p->hello != NULL) { GNUNET_free (p->hello); @@ -499,9 +453,9 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, /** - * 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 - * before. + * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message + * + * Remarks: start_peer's notify_connect callback can be called before. * * @param tth transport testing handle * @param p1 peer 1 @@ -538,7 +492,7 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle * 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); + "New connect request %p\n", cc); return cc; } @@ -563,7 +517,7 @@ GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_assert (tth != NULL); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Canceling connect request %X!\n", cc); + "Canceling connect request %p!\n", cc); if (cc->tct != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (cc->tct); @@ -592,7 +546,7 @@ GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_handle *tth) { ct = cc->next; GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", - "Developer forgot to cancel connect request %X!\n", cc); + "Developer forgot to cancel connect request %p!\n", cc); GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc); cc = ct; } @@ -606,7 +560,7 @@ GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_handle *tth) p = t; } - GNUNET_free_non_null (tth->hostkey_data); + GNUNET_TESTING_system_destroy (tth->tl_system, GNUNET_YES); GNUNET_free (tth); tth = NULL; @@ -621,50 +575,17 @@ struct GNUNET_TRANSPORT_TESTING_handle * GNUNET_TRANSPORT_TESTING_init () { struct GNUNET_TRANSPORT_TESTING_handle *tth; - struct GNUNET_DISK_FileHandle *fd; - uint64_t fs; - uint64_t total_hostkeys; - /* prepare hostkeys */ tth = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TESTING_handle)); - tth->hostkey_data = NULL; - const char *hostkeys_file = "../../contrib/testing_hostkeys.dat"; - if (GNUNET_YES != GNUNET_DISK_file_test (hostkeys_file)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not read hostkeys file!\n")); - } - else + /* Init testing the testing lib */ + tth->tl_system = GNUNET_TESTING_system_create ("transport-testing", NULL, NULL); + if (NULL == tth->tl_system) { - /* Check hostkey file size, read entire thing into memory */ - fd = GNUNET_DISK_file_open (hostkeys_file, GNUNET_DISK_OPEN_READ, - GNUNET_DISK_PERM_NONE); - if (NULL == fd) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", hostkeys_file); - GNUNET_free (tth); - return NULL; - } - - if (GNUNET_OK != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES, GNUNET_YES)) - fs = 0; - - if (0 != (fs % HOSTKEYFILESIZE)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", - "File size %llu seems incorrect for hostkeys...\n", fs); - } - else - { - total_hostkeys = fs / HOSTKEYFILESIZE; - tth->hostkey_data = GNUNET_malloc_large (fs); - GNUNET_assert (fs == GNUNET_DISK_file_read (fd, tth->hostkey_data, fs)); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Read %llu hostkeys from file\n", total_hostkeys); - tth->hostkeys_total = total_hostkeys; - } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to initialize testing library!\n")); + GNUNET_free (tth); + return NULL; } return tth; @@ -687,7 +608,25 @@ extract_filename (const char *file) char *backup = pch; char *filename = NULL; char *res; - +#if WINDOWS + if ((strlen (pch) >= 3) && pch[1] == ':') + { + if (NULL != strstr (pch, "\\")) + { + pch = strtok (pch, "\\"); + while (pch != NULL) + { + pch = strtok (NULL, "\\"); + if (pch != NULL) + filename = pch; + } + } + } + if (filename != NULL) + pch = filename; /* If we miss the next condition, filename = pch will + * not harm us. + */ +#endif if (NULL != strstr (pch, "/")) { pch = strtok (pch, "/"); @@ -845,5 +784,4 @@ fail: } - /* end of transport-testing.c */ diff --git a/src/transport/transport-testing.h b/src/transport/transport-testing.h index 20e802d..d064ac5 100644 --- a/src/transport/transport-testing.h +++ b/src/transport/transport-testing.h @@ -27,12 +27,11 @@ #include "platform.h" #include "gnunet_common.h" -#include "gnunet_getopt_lib.h" #include "gnunet_hello_lib.h" -#include "gnunet_os_lib.h" #include "gnunet_program_lib.h" #include "gnunet_container_lib.h" #include "gnunet_transport_service.h" +#include "gnunet_testing_lib.h" #define GNUNET_TRANSPORT_TESTING_ConnectRequest void * @@ -59,7 +58,9 @@ typedef void (*GNUNET_TRANSPORT_TESTING_connect_cb) (struct PeerContext * p1, void *cls); - +/** + * Definition for a transport testing handle + */ struct GNUNET_TRANSPORT_TESTING_handle; /** @@ -67,37 +68,84 @@ struct GNUNET_TRANSPORT_TESTING_handle; */ struct PeerContext { + /** + * Next element in the DLL + */ struct PeerContext *next; + + /** + * Previous element in the DLL + */ struct PeerContext *prev; + /** + * Transport testing handle this peer belongs to + */ struct GNUNET_TRANSPORT_TESTING_handle *tth; + /** + * Peer's configuration + */ struct GNUNET_CONFIGURATION_Handle *cfg; + /** + * Peer's transport service handle + */ struct GNUNET_TRANSPORT_Handle *th; + /** + * Peer's transport get hello handle to retrieve peer's HELLO message + */ struct GNUNET_TRANSPORT_GetHelloHandle *ghh; + /** + * Peer's testing handle + */ + struct GNUNET_TESTING_Peer *peer; + + /** + * Peer identity + */ struct GNUNET_PeerIdentity id; + /** + * Handle for the peer's ARM process + */ struct GNUNET_OS_Process *arm_proc; + /** + * Receive callback + */ GNUNET_TRANSPORT_ReceiveCallback rec; + /** + * Notify connect callback + */ GNUNET_TRANSPORT_NotifyConnect nc; + /** + * Notify disconnect callback + */ GNUNET_TRANSPORT_NotifyDisconnect nd; + /** + * Startup completed callback + */ GNUNET_TRANSPORT_TESTING_start_cb start_cb; + /** + * Peers HELLO Message + */ struct GNUNET_HELLO_Message *hello; + /** + * Closure for the callbacks + */ void *cb_cls; - char *servicehome; - - char *hostkeyfile; - + /** + * An unique number to identify the peer + */ unsigned int no; }; @@ -119,14 +167,29 @@ struct ConnectingContext struct GNUNET_TRANSPORT_TESTING_handle { + /** + * Testing library system handle + */ + struct GNUNET_TESTING_System *tl_system; + + /** + * head DLL of connect contexts + */ struct ConnectingContext *cc_head; - struct ConnectingContext *cc_tail; - char *hostkey_data; - int hostkeys_total; - int hostkeys_last; + /** + * head DLL of connect contexts + */ + struct ConnectingContext *cc_tail; + /** + * head DLL of peers + */ struct PeerContext *p_head; + + /** + * tail DLL of peers + */ struct PeerContext *p_tail; }; diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in index 9a6f5d9..e8786be 100644 --- a/src/transport/transport.conf.in +++ b/src/transport/transport.conf.in @@ -3,7 +3,6 @@ AUTOSTART = YES @UNIXONLY@ PORT = 2091 HOSTNAME = localhost HOME = $SERVICEHOME -CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-transport #PREFIX = valgrind NEIGHBOUR_LIMIT = 50 @@ -27,11 +26,13 @@ UNIX_MATCH_GID = YES [transport-unix] PORT = 22086 +TESTING_IGNORE_KEYS = ACCEPT_FROM; [transport-tcp] # Use 0 to ONLY advertise as a peer behind NAT (no port binding) PORT = 2086 ADVERTISED_PORT = 2086 +TESTING_IGNORE_KEYS = ACCEPT_FROM; # Maximum number of open TCP connections allowed MAX_CONNECTIONS = 128 @@ -47,23 +48,37 @@ MAX_CONNECTIONS = 128 [transport-udp] PORT = 2086 BROADCAST = YES -BROADCAST_INTERVAL = 30000 +BROADCAST_INTERVAL = 30 s MAX_BPS = 1000000 +TESTING_IGNORE_KEYS = ACCEPT_FROM; -[transport-http] +[transport-http_client] +MAX_CONNECTIONS = 128 +TESTING_IGNORE_KEYS = ACCEPT_FROM; + +[transport-http_server] +#EXTERNAL_HOSTNAME = <your hostname/path> PORT = 1080 +ADVERTISED_PORT = 1080 MAX_CONNECTIONS = 128 +TESTING_IGNORE_KEYS = ACCEPT_FROM; -[transport-https] +[transport-https_client] +MAX_CONNECTIONS = 128 +TESTING_IGNORE_KEYS = ACCEPT_FROM; + +[transport-https_server] PORT = 4433 +ADVERTISED_PORT = 4433 CRYPTO_INIT = NORMAL -KEY_FILE = https.key -CERT_FILE = https.cert +KEY_FILE = $SERVICEHOME/https.key +CERT_FILE = $SERVICEHOME/https.cert MAX_CONNECTIONS = 128 +TESTING_IGNORE_KEYS = ACCEPT_FROM; [transport-wlan] # Name of the interface in monitor mode (typically monX) INTERFACE = mon0 # Real hardware, no testing TESTMODE = 0 - +TESTING_IGNORE_KEYS = ACCEPT_FROM; diff --git a/src/transport/transport.h b/src/transport/transport.h index e0b8819..be31f0a 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -47,6 +47,12 @@ #define MIN_QUOTA_REFRESH_TIME 2000 /** + * What's the maximum number of sockets transport uses for validation and + * neighbors + */ +#define DEFAULT_MAX_FDS 256 + +/** * Maximum frequency for re-evaluating latencies for all transport addresses. */ #define LATENCY_EVALUATION_MAX_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) @@ -56,6 +62,26 @@ */ #define CONNECTED_LATENCY_EVALUATION_MAX_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) +/** + * Similiar to GNUNET_TRANSPORT_NotifyDisconnect but in and out quotas are + * included here. These values are not required outside transport_api + * + * @param cls closure + * @param peer the peer that connected + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) + * @param bandwidth_in inbound bandwidth in NBO + * @param bandwidth_out outbound bandwidth in NBO + * + */ + +typedef void (*NotifyConnect) (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out); + GNUNET_NETWORK_STRUCT_BEGIN /** @@ -109,6 +135,16 @@ struct ConnectInfoMessage * Identity of the new neighbour. */ struct GNUNET_PeerIdentity id; + + /** + * Current inbound quota for this peer + */ + struct GNUNET_BANDWIDTH_Value32NBO quota_in; + + /** + * Current outbound quota for this peer + */ + struct GNUNET_BANDWIDTH_Value32NBO quota_out; }; @@ -232,6 +268,18 @@ struct SendOkMessage */ uint32_t success GNUNET_PACKED; + + /** + * Size of message sent + */ + uint32_t bytes_msg GNUNET_PACKED; + + /** + * Size of message sent over wire + * Includes plugin and protocol specific overhead + */ + uint32_t bytes_physical GNUNET_PACKED; + /** * Latency estimate. */ @@ -367,6 +415,34 @@ struct AddressIterateMessage /** + * Message from the library to the transport service + * asking for binary addresses known for a peer. + */ +struct TrafficMetricMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC + */ + struct GNUNET_MessageHeader header; + + /** + * SEND, RECEIVE or BOTH? + */ + uint16_t direction; + + /** + * Traffic metrics count + */ + uint16_t ats_count; + + /** + * The identity of the peer to look up. + */ + struct GNUNET_PeerIdentity peer; +}; + + +/** * Message from the transport service to the library * containing binary addresses known for a peer. * Memory layout: diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index b97a245..7f0bc92 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -146,6 +146,11 @@ struct Neighbour */ int is_ready; + /** + * Sending consumed more bytes on wire than payload was announced + * This overhead is added to the delay of next sending operation + */ + size_t traffic_overhead; }; @@ -176,12 +181,52 @@ struct GNUNET_TRANSPORT_GetHelloHandle GNUNET_TRANSPORT_HelloUpdateCallback rec; /** + * Task for calling the HelloUpdateCallback when we already have a HELLO + */ + GNUNET_SCHEDULER_TaskIdentifier notify_task; + + /** * Closure for rec. */ void *rec_cls; }; +/** + * Linked list for all try-connect requests + */ +struct GNUNET_TRANSPORT_TryConnectHandle +{ + struct GNUNET_TRANSPORT_TryConnectHandle *prev; + struct GNUNET_TRANSPORT_TryConnectHandle *next; + + struct GNUNET_PeerIdentity pid; + + struct GNUNET_TRANSPORT_Handle *th; + struct GNUNET_TRANSPORT_TransmitHandle *tth; + GNUNET_TRANSPORT_TryConnectCallback cb; + void *cb_cls; +}; + + +/** + * Linked list for all try-connect requests + */ +struct GNUNET_TRANSPORT_OfferHelloHandle +{ + struct GNUNET_TRANSPORT_OfferHelloHandle *prev; + struct GNUNET_TRANSPORT_OfferHelloHandle *next; + + struct GNUNET_TRANSPORT_Handle *th; + + struct GNUNET_TRANSPORT_TransmitHandle *tth; + GNUNET_SCHEDULER_Task cont; + + void *cls; + + struct GNUNET_MessageHeader *msg; +}; + /** * Handle for the transport service (includes all of the @@ -247,6 +292,26 @@ struct GNUNET_TRANSPORT_Handle struct GNUNET_TRANSPORT_GetHelloHandle *hwl_tail; /** + * Linked list of pending try connect requests head + */ + struct GNUNET_TRANSPORT_TryConnectHandle *tc_head; + + /** + * Linked list of pending try connect requests tail + */ + struct GNUNET_TRANSPORT_TryConnectHandle *tc_tail; + + /** + * Linked list of pending offer HELLO requests head + */ + struct GNUNET_TRANSPORT_OfferHelloHandle *oh_head; + + /** + * Linked list of pending offer HELLO requests tail + */ + struct GNUNET_TRANSPORT_OfferHelloHandle *oh_tail; + + /** * My configuration. */ const struct GNUNET_CONFIGURATION_Handle *cfg; @@ -293,9 +358,15 @@ struct GNUNET_TRANSPORT_Handle * (if GNUNET_NO, then 'self' is all zeros!). */ int check_self; + + /** + * Reconnect in progress + */ + int reconnecting; }; + /** * Schedule the task to send one message, either from the control * list or the peer message queues to the service. @@ -348,12 +419,13 @@ neighbour_add (struct GNUNET_TRANSPORT_Handle *h, n->id = *pid; n->h = h; n->is_ready = GNUNET_YES; + n->traffic_overhead = 0; GNUNET_BANDWIDTH_tracker_init (&n->out_tracker, GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, MAX_BANDWIDTH_CARRY_S); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (h->neighbours, - &pid->hashPubKey, n, + &n->id.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); return n; } @@ -370,7 +442,7 @@ neighbour_add (struct GNUNET_TRANSPORT_Handle *h, * GNUNET_NO if not. */ static int -neighbour_delete (void *cls, const GNUNET_HashCode * key, void *value) +neighbour_delete (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_TRANSPORT_Handle *handle = cls; struct Neighbour *n = value; @@ -410,6 +482,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_PeerIdentity me; uint16_t size; uint32_t ats_count; + uint32_t bytes_msg; + uint32_t bytes_physical; GNUNET_assert (h->client != NULL); if (msg == NULL) @@ -477,6 +551,9 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) break; } n = neighbour_add (h, &cim->id); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message for `%4s' with quota %u\n", + "CONNECT", GNUNET_i2s (&cim->id), ntohl (cim->quota_out.value__)); + GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker, cim->quota_out); if (h->nc_cb != NULL) h->nc_cb (h->cls, &n->id, ats, ats_count); break; @@ -505,11 +582,21 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) break; } okm = (const struct SendOkMessage *) msg; + bytes_msg = ntohl (okm->bytes_msg); + bytes_physical = ntohl (okm->bytes_physical); LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message, transmission %s.\n", "SEND_OK", ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed"); + n = neighbour_find (h, &okm->peer); if (n == NULL) break; + + if (bytes_physical >= bytes_msg) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, "Overhead for %u byte message: %u \n", + bytes_msg, bytes_physical - bytes_msg); + n->traffic_overhead += bytes_physical - bytes_msg; + } GNUNET_break (GNUNET_NO == n->is_ready); n->is_ready = GNUNET_YES; if ((n->th != NULL) && (n->hn == NULL)) @@ -563,6 +650,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) n = neighbour_find (h, &qm->peer); if (n == NULL) break; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message for `%4s' with quota %u\n", + "SET_QUOTA", GNUNET_i2s (&qm->peer), ntohl (qm->quota.value__)); GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker, qm->quota); break; default: @@ -778,9 +867,12 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) if (NULL != h->control_head) delay = GNUNET_TIME_UNIT_ZERO; else if (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) + { delay = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, - n->th->notify_size); + n->th->notify_size + n->traffic_overhead); + n->traffic_overhead = 0; + } else return; /* no work to be done */ LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -799,8 +891,9 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) * @param size number of bytes to be transmitted * @param notify function to call to get the content * @param notify_cls closure for notify + * @return a GNUNET_TRANSPORT_TransmitHandle */ -static void +static struct GNUNET_TRANSPORT_TransmitHandle * schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls) @@ -815,6 +908,7 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, th->notify_size = size; GNUNET_CONTAINER_DLL_insert_tail (h->control_head, h->control_tail, th); schedule_transmission (h); + return th; } @@ -925,19 +1019,30 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) h->reconnect_delay.rel_value); h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); - if (h->reconnect_delay.rel_value == 0) - { - h->reconnect_delay = GNUNET_TIME_UNIT_MILLISECONDS; - } - else - { - h->reconnect_delay = GNUNET_TIME_relative_multiply (h->reconnect_delay, 2); - h->reconnect_delay = - GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS, h->reconnect_delay); - } + h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); +} + + +/** + * Cancel control request for transmission to the transport service. + * + * @param th handle to the transport service + * @param tth transmit handle to cancel + */ +static void +cancel_control_transmit (struct GNUNET_TRANSPORT_Handle *th, struct GNUNET_TRANSPORT_TransmitHandle *tth) +{ + GNUNET_assert (NULL != th); + GNUNET_assert (NULL != tth); + + LOG (GNUNET_ERROR_TYPE_DEBUG, "Canceling transmit of contral transmission requested\n"); + + GNUNET_CONTAINER_DLL_remove (th->control_head, th->control_tail, tth); + GNUNET_free (tth); } + /** * Send REQUEST_CONNECT message to the service. * @@ -949,52 +1054,88 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) static size_t send_try_connect (void *cls, size_t size, void *buf) { - struct GNUNET_PeerIdentity *pid = cls; + struct GNUNET_TRANSPORT_TryConnectHandle *tch = cls; struct TransportRequestConnectMessage msg; if (buf == NULL) { - GNUNET_free (pid); + if (NULL != tch->cb) + tch->cb (tch->cb_cls, GNUNET_SYSERR); + GNUNET_CONTAINER_DLL_remove (tch->th->tc_head, tch->th->tc_tail, tch); + GNUNET_free (tch); return 0; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request with respect to `%4s'.\n", "REQUEST_CONNECT", - GNUNET_i2s (pid)); + GNUNET_i2s (&tch->pid)); GNUNET_assert (size >= sizeof (struct TransportRequestConnectMessage)); msg.header.size = htons (sizeof (struct TransportRequestConnectMessage)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT); msg.reserved = htonl (0); - msg.peer = *pid; + msg.peer = tch->pid; memcpy (buf, &msg, sizeof (msg)); - GNUNET_free (pid); + if (NULL != tch->cb) + tch->cb (tch->cb_cls, GNUNET_OK); + GNUNET_CONTAINER_DLL_remove (tch->th->tc_head, tch->th->tc_tail, tch); + GNUNET_free (tch); return sizeof (struct TransportRequestConnectMessage); } - /** * Ask the transport service to establish a connection to * the given peer. * * @param handle connection to transport service * @param target who we should try to connect to + * @param cb callback to be called when request was transmitted to transport + * service + * @param cb_cls closure for the callback + * @return a GNUNET_TRANSPORT_TryConnectHandle handle or + * NULL on failure (cb will not be called) */ -void +struct GNUNET_TRANSPORT_TryConnectHandle * GNUNET_TRANSPORT_try_connect (struct GNUNET_TRANSPORT_Handle *handle, - const struct GNUNET_PeerIdentity *target) + const struct GNUNET_PeerIdentity *target, + GNUNET_TRANSPORT_TryConnectCallback cb, + void *cb_cls) { - struct GNUNET_PeerIdentity *pid; + struct GNUNET_TRANSPORT_TryConnectHandle *tch = NULL; if (NULL == handle->client) - return; - pid = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); - *pid = *target; - schedule_control_transmit (handle, + return NULL; + + tch = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TryConnectHandle)); + tch->th = handle; + tch->pid = *(target); + tch->cb = cb; + tch->cb_cls = cb_cls; + tch->tth = schedule_control_transmit (handle, sizeof (struct TransportRequestConnectMessage), - &send_try_connect, pid); + &send_try_connect, tch); + GNUNET_CONTAINER_DLL_insert(handle->tc_head, handle->tc_tail, tch); + return tch; } /** + * Cancel the request to transport to try a connect + * Callback will not be called + * + * @param tch GNUNET_TRANSPORT_TryConnectHandle handle to cancel + */ +void +GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *tch) +{ + struct GNUNET_TRANSPORT_Handle *th; + GNUNET_assert (NULL != tch); + + th = tch->th; + cancel_control_transmit (th, tch->tth); + GNUNET_CONTAINER_DLL_remove (th->tc_head, th->tc_tail, tch); + GNUNET_free (tch); +} + +/** * Send HELLO message to the service. * * @param cls the HELLO message to send @@ -1005,14 +1146,23 @@ GNUNET_TRANSPORT_try_connect (struct GNUNET_TRANSPORT_Handle *handle, static size_t send_hello (void *cls, size_t size, void *buf) { - struct GNUNET_MessageHeader *msg = cls; + struct GNUNET_TRANSPORT_OfferHelloHandle *ohh = cls; + struct GNUNET_MessageHeader *msg = ohh->msg; uint16_t ssize; + struct GNUNET_SCHEDULER_TaskContext tc; + tc.read_ready = NULL; + tc.write_ready = NULL; + tc.reason = GNUNET_SCHEDULER_REASON_TIMEOUT; if (buf == NULL) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Timeout while trying to transmit `%s' request.\n", "HELLO"); + if (NULL != ohh->cont) + ohh->cont (ohh->cls, &tc); GNUNET_free (msg); + GNUNET_CONTAINER_DLL_remove (ohh->th->oh_head, ohh->th->oh_tail, ohh); + GNUNET_free (ohh); return 0; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "HELLO"); @@ -1020,32 +1170,132 @@ send_hello (void *cls, size_t size, void *buf) GNUNET_assert (size >= ssize); memcpy (buf, msg, ssize); GNUNET_free (msg); + tc.reason = GNUNET_SCHEDULER_REASON_READ_READY; + if (NULL != ohh->cont) + ohh->cont (ohh->cls, &tc); + GNUNET_CONTAINER_DLL_remove (ohh->th->oh_head, ohh->th->oh_tail, ohh); + GNUNET_free (ohh); return ssize; } /** + * Send traffic metric message to the service. + * + * @param cls the message to send + * @param size number of bytes available in buf + * @param buf where to copy the message + * @return number of bytes copied to buf + */ +static size_t +send_metric (void *cls, size_t size, void *buf) +{ + struct TrafficMetricMessage *msg = cls; + uint16_t ssize; + if (buf == NULL) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout while trying to transmit `%s' request.\n", "TRAFFIC_METRIC"); + GNUNET_free (msg); + return 0; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TRAFFIC_METRIC"); + ssize = ntohs (msg->header.size); + GNUNET_assert (size >= ssize); + memcpy (buf, msg, ssize); + GNUNET_free (msg); + return ssize; +} + + +/** + * Set transport metrics for a peer and a direction + * + * @param handle transport handle + * @param peer the peer to set the metric for + * @param direction can be: TM_SEND, TM_RECV, TM_BOTH + * @param ats the metric as ATS information + * @param ats_count the number of metrics + * + * Supported ATS values: + * GNUNET_ATS_QUALITY_NET_DELAY (value in ms) + * GNUNET_ATS_QUALITY_NET_DISTANCE (value in #hops) + * + * Example + * To enforce a delay of 10 ms for peer p1 in sending direction use: + * + * struct GNUNET_ATS_Information ats; + * ats.type = ntohl (GNUNET_ATS_QUALITY_NET_DELAY); + * ats.value = ntohl (10); + * GNUNET_TRANSPORT_set_traffic_metric (th, p1, TM_SEND, &ats, 1); + * + * Note: + * Delay restrictions in receiving direction will be enforced with + * 1 message delay. + */ +void +GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle, + const struct GNUNET_PeerIdentity *peer, + int direction, + const struct GNUNET_ATS_Information *ats, + size_t ats_count) +{ + struct TrafficMetricMessage *msg; + + GNUNET_assert (NULL != handle); + GNUNET_assert (NULL != peer); + GNUNET_assert (direction >= TM_SEND); + GNUNET_assert (direction <= TM_BOTH); + + if (0 == ats_count) + return; + + size_t len = sizeof (struct TrafficMetricMessage) + + ats_count * sizeof (struct GNUNET_ATS_Information); + + msg = GNUNET_malloc (len); + msg->header.size = htons (len); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC); + msg->direction = htons (direction); + msg->ats_count = htons (ats_count); + msg->peer = (*peer); + memcpy (&msg[1], ats, ats_count * sizeof (struct GNUNET_ATS_Information)); + schedule_control_transmit (handle, len, &send_metric, msg); +} + + + +/** * Offer the transport service the HELLO of another peer. Note that * the transport service may just ignore this message if the HELLO is * malformed or useless due to our local configuration. * * @param handle connection to transport service * @param hello the hello message - * @param cont continuation to call when HELLO has been sent + * @param cont continuation to call when HELLO has been sent, + * tc reason GNUNET_SCHEDULER_REASON_TIMEOUT for fail + * tc reasong GNUNET_SCHEDULER_REASON_READ_READY for success * @param cls closure for continuation + * @return a GNUNET_TRANSPORT_OfferHelloHandle handle or NULL on failure, + * in case of failure cont will not be called * */ -void +struct GNUNET_TRANSPORT_OfferHelloHandle * GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle, const struct GNUNET_MessageHeader *hello, GNUNET_SCHEDULER_Task cont, void *cls) { - uint16_t size; - struct GNUNET_PeerIdentity peer; + struct GNUNET_TRANSPORT_OfferHelloHandle *ohh; struct GNUNET_MessageHeader *msg; + struct GNUNET_PeerIdentity peer; + uint16_t size; + + GNUNET_assert (NULL != handle); + GNUNET_assert (NULL != hello); if (NULL == handle->client) - return; + return NULL; + GNUNET_break (ntohs (hello->type) == GNUNET_MESSAGE_TYPE_HELLO); size = ntohs (hello->size); GNUNET_break (size >= sizeof (struct GNUNET_MessageHeader)); @@ -1053,19 +1303,80 @@ GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle, GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hello, &peer)) { GNUNET_break (0); - return; + return NULL; } + msg = GNUNET_malloc (size); memcpy (msg, hello, size); LOG (GNUNET_ERROR_TYPE_DEBUG, "Offering `%s' message of `%4s' to transport for validation.\n", "HELLO", GNUNET_i2s (&peer)); - schedule_control_transmit (handle, size, &send_hello, msg); + + ohh = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_OfferHelloHandle)); + ohh->th = handle; + ohh->cont = cont; + ohh->cls = cls; + ohh->msg = msg; + ohh->tth = schedule_control_transmit (handle, size, &send_hello, ohh); + GNUNET_CONTAINER_DLL_insert (handle->oh_head, handle->oh_tail, ohh); + return ohh; } /** - * Obtain the HELLO message for this peer. + * Cancel the request to transport to offer the HELLO message + * + * @param ohh the GNUNET_TRANSPORT_OfferHelloHandle to cancel + */ +void +GNUNET_TRANSPORT_offer_hello_cancel (struct GNUNET_TRANSPORT_OfferHelloHandle *ohh) +{ + struct GNUNET_TRANSPORT_Handle *th = ohh->th; + GNUNET_assert (NULL != ohh); + + cancel_control_transmit (ohh->th, ohh->tth); + GNUNET_CONTAINER_DLL_remove (th->oh_head, th->oh_tail, ohh); + GNUNET_free (ohh->msg); + GNUNET_free (ohh); +} + +int +GNUNET_TRANSPORT_check_neighbour_connected (struct GNUNET_TRANSPORT_Handle *handle, + const struct GNUNET_PeerIdentity *peer) +{ + GNUNET_assert (NULL != handle); + GNUNET_assert (NULL != peer); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(handle->neighbours, &peer->hashPubKey)) + return GNUNET_YES; + else + return GNUNET_NO; +} + + +/** + * Task to call the HelloUpdateCallback of the GetHelloHandle + * + * @param cls the GetHelloHandle + * @param tc the scheduler task context + */ +static void +call_hello_update_cb_async (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; + + GNUNET_assert (NULL != ghh->handle->my_hello); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != ghh->notify_task); + ghh->notify_task = GNUNET_SCHEDULER_NO_TASK; + ghh->rec (ghh->rec_cls, + (const struct GNUNET_MessageHeader *) ghh->handle->my_hello); +} + + +/** + * Obtain the HELLO message for this peer. The callback given in this function + * is never called synchronously. * * @param handle connection to transport service * @param rec function to call with the HELLO, sender will be our peer @@ -1088,7 +1399,8 @@ GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, hwl->handle = handle; GNUNET_CONTAINER_DLL_insert (handle->hwl_head, handle->hwl_tail, hwl); if (handle->my_hello != NULL) - rec (rec_cls, (const struct GNUNET_MessageHeader *) handle->my_hello); + hwl->notify_task = GNUNET_SCHEDULER_add_now (&call_hello_update_cb_async, + hwl); return hwl; } @@ -1103,6 +1415,8 @@ GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) { struct GNUNET_TRANSPORT_Handle *handle = ghh->handle; + if (GNUNET_SCHEDULER_NO_TASK != ghh->notify_task) + GNUNET_SCHEDULER_cancel (ghh->notify_task); GNUNET_CONTAINER_DLL_remove (handle->hwl_head, handle->hwl_tail, ghh); GNUNET_free (ghh); } @@ -1142,10 +1456,17 @@ GNUNET_TRANSPORT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, ret->nd_cb = nd; ret->reconnect_delay = GNUNET_TIME_UNIT_ZERO; ret->neighbours = - GNUNET_CONTAINER_multihashmap_create (STARTING_NEIGHBOURS_SIZE); + GNUNET_CONTAINER_multihashmap_create (STARTING_NEIGHBOURS_SIZE, GNUNET_YES); ret->ready_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); - ret->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, ret); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service.\n"); + ret->client = GNUNET_CLIENT_connect ("transport", cfg); + if (ret->client == NULL) + { + GNUNET_free (ret); + return NULL; + } + schedule_control_transmit (ret, sizeof (struct StartMessage), &send_start, ret); return ret; } @@ -1177,6 +1498,8 @@ GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle) } GNUNET_free_non_null (handle->my_hello); handle->my_hello = NULL; + GNUNET_assert (handle->tc_head == NULL); + GNUNET_assert (handle->tc_tail == NULL); GNUNET_assert (handle->hwl_head == NULL); GNUNET_assert (handle->hwl_tail == NULL); GNUNET_CONTAINER_heap_destroy (handle->ready_heap); @@ -1240,7 +1563,8 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle *handle, th->priority = priority; n->th = th; /* calculate when our transmission should be ready */ - delay = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, size); + delay = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, size + n->traffic_overhead); + n->traffic_overhead = 0; if (delay.rel_value > timeout.rel_value) delay.rel_value = 0; /* notify immediately (with failure) */ LOG (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c index 655be83..217aecd 100644 --- a/src/transport/transport_api_address_lookup.c +++ b/src/transport/transport_api_address_lookup.c @@ -157,9 +157,7 @@ reconnect (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx) GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); 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), - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30))); + pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff); pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff, &do_connect, pal_ctx); |