aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am36
-rw-r--r--src/util/Makefile.in90
-rw-r--r--src/util/client.c503
-rw-r--r--src/util/common_logging.c17
-rw-r--r--src/util/configuration.c37
-rw-r--r--src/util/connection.c1184
-rw-r--r--src/util/container_bloomfilter.c31
-rw-r--r--src/util/container_heap.c14
-rw-r--r--src/util/container_slist.c29
-rw-r--r--src/util/crypto_aes.c87
-rw-r--r--src/util/crypto_hash.c235
-rw-r--r--src/util/crypto_hkdf.c1
-rw-r--r--src/util/crypto_ksk.c195
-rw-r--r--src/util/crypto_random.c6
-rw-r--r--src/util/crypto_rsa.c163
-rw-r--r--src/util/disk.c106
-rw-r--r--src/util/getopt.c15
-rw-r--r--src/util/getopt_helpers.c9
-rw-r--r--src/util/gnunet-rsa.c128
-rw-r--r--src/util/gnunet-service-resolver.c8
-rw-r--r--src/util/helper.c142
-rw-r--r--src/util/load.c1
-rw-r--r--src/util/network.c211
-rw-r--r--src/util/os_installation.c2
-rw-r--r--src/util/os_priority.c193
-rw-r--r--src/util/program.c54
-rw-r--r--src/util/pseudonym.c205
-rw-r--r--src/util/resolver.conf.in2
-rw-r--r--src/util/resolver.h2
-rw-r--r--src/util/resolver_api.c40
-rw-r--r--src/util/scheduler.c160
-rw-r--r--src/util/server.c753
-rw-r--r--src/util/server_mst.c13
-rw-r--r--src/util/server_nc.c100
-rw-r--r--src/util/server_tc.c5
-rw-r--r--src/util/service.c408
-rw-r--r--src/util/speedup.c92
-rw-r--r--src/util/strings.c697
-rw-r--r--src/util/test_client.c6
-rw-r--r--src/util/test_common_logging_runtime_loglevels.c2
-rw-r--r--src/util/test_configuration.c7
-rw-r--r--src/util/test_connection.c6
-rw-r--r--src/util/test_connection_addressing.c7
-rw-r--r--src/util/test_connection_receive_cancel.c7
-rw-r--r--src/util/test_connection_timeout.c4
-rw-r--r--src/util/test_connection_transmit_cancel.c2
-rw-r--r--src/util/test_disk.c2
-rw-r--r--src/util/test_os_start_process.c75
-rw-r--r--src/util/test_pseudonym.c30
-rw-r--r--src/util/test_resolver_api.c28
-rw-r--r--src/util/test_scheduler.c44
-rw-r--r--src/util/test_server.c2
-rw-r--r--src/util/test_server_disconnect.c2
-rw-r--r--src/util/test_server_mst_interrupt.c81
-rw-r--r--src/util/test_server_with_client.c2
-rw-r--r--src/util/test_server_with_client_unix.c2
-rw-r--r--src/util/test_service.c63
-rw-r--r--src/util/test_speedup.c120
-rw-r--r--src/util/test_speedup_data.conf3
-rw-r--r--src/util/test_strings.c2
-rw-r--r--src/util/test_time.c24
-rw-r--r--src/util/time.c77
-rw-r--r--src/util/util.conf2
-rw-r--r--src/util/winproc.c3
64 files changed, 3935 insertions, 2642 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index cded34d..8414ef2 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -37,6 +37,7 @@ noinst_PROGRAMS = \
gnunet-config-diff \
test_common_logging_dummy
+
gnunet_config_diff_SOURCES = \
gnunet-config-diff.c
gnunet_config_diff_LDADD = \
@@ -98,23 +99,26 @@ libgnunetutil_la_SOURCES = \
service.c \
signal.c \
strings.c \
- time.c
+ time.c \
+ speedup.c
libgnunetutil_la_LIBADD = \
$(GCLIBADD) $(WINLIB) \
$(LIBGCRYPT_LIBS) \
$(LTLIBICONV) \
- -lltdl -lz $(XLIB)
+ -lltdl -lz -lunistring $(XLIB)
libgnunetutil_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) \
- -version-info 7:0:0
+ -version-info 8:0:0
bin_PROGRAMS = \
gnunet-service-resolver \
- gnunet-resolver
+ gnunet-resolver \
+ gnunet-rsa
+
gnunet_service_resolver_SOURCES = \
gnunet-service-resolver.c
@@ -133,6 +137,15 @@ gnunet_resolver_LDADD = \
gnunet_resolver_DEPENDENCIES = \
libgnunetutil.la
+
+gnunet_rsa_SOURCES = \
+ gnunet-rsa.c
+gnunet_rsa_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(GN_LIBINTL)
+gnunet_rsa_DEPENDENCIES = \
+ libgnunetutil.la
+
plugin_LTLIBRARIES = \
libgnunet_plugin_test.la
@@ -183,6 +196,7 @@ check_PROGRAMS = \
test_resolver_api \
test_scheduler \
test_scheduler_delay \
+ test_server_mst_interrupt \
test_server \
test_server_disconnect \
test_server_with_client \
@@ -190,6 +204,7 @@ check_PROGRAMS = \
test_service \
test_strings \
test_time \
+ test_speedup \
$(BENCHMARKS) \
test_os_start_process \
test_common_logging_runtime_loglevels
@@ -390,6 +405,11 @@ test_scheduler_delay_SOURCES = \
test_scheduler_delay_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
+test_server_mst_interrupt_SOURCES = \
+ test_server_mst_interrupt.c
+test_server_mst_interrupt_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_server_SOURCES = \
test_server.c
test_server_LDADD = \
@@ -426,6 +446,11 @@ test_time_SOURCES = \
test_time_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
+test_speedup_SOURCES = \
+ test_speedup.c
+test_speedup_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
perf_crypto_hash_SOURCES = \
perf_crypto_hash.c
perf_crypto_hash_LDADD = \
@@ -437,4 +462,5 @@ EXTRA_DIST = \
test_program_data.conf \
test_pseudonym_data.conf \
test_resolver_api_data.conf \
- test_service_data.conf
+ test_service_data.conf \
+ test_speedup_data.conf
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
index 3c82fbf..5ea0157 100644
--- a/src/util/Makefile.in
+++ b/src/util/Makefile.in
@@ -40,7 +40,7 @@ target_triplet = @target@
noinst_PROGRAMS = gnunet-config-diff$(EXEEXT) \
test_common_logging_dummy$(EXEEXT)
bin_PROGRAMS = gnunet-service-resolver$(EXEEXT) \
- gnunet-resolver$(EXEEXT)
+ gnunet-resolver$(EXEEXT) gnunet-rsa$(EXEEXT)
check_PROGRAMS = test_bio$(EXEEXT) test_client$(EXEEXT) \
test_common_allocation$(EXEEXT) test_common_endian$(EXEEXT) \
test_common_logging$(EXEEXT) test_configuration$(EXEEXT) \
@@ -62,10 +62,12 @@ check_PROGRAMS = test_bio$(EXEEXT) test_client$(EXEEXT) \
test_peer$(EXEEXT) test_plugin$(EXEEXT) test_program$(EXEEXT) \
test_pseudonym$(EXEEXT) test_resolver_api$(EXEEXT) \
test_scheduler$(EXEEXT) test_scheduler_delay$(EXEEXT) \
- test_server$(EXEEXT) test_server_disconnect$(EXEEXT) \
+ test_server_mst_interrupt$(EXEEXT) test_server$(EXEEXT) \
+ test_server_disconnect$(EXEEXT) \
test_server_with_client$(EXEEXT) $(am__EXEEXT_1) \
test_service$(EXEEXT) test_strings$(EXEEXT) test_time$(EXEEXT) \
- $(am__EXEEXT_2) test_os_start_process$(EXEEXT) \
+ test_speedup$(EXEEXT) $(am__EXEEXT_2) \
+ test_os_start_process$(EXEEXT) \
test_common_logging_runtime_loglevels$(EXEEXT)
subdir = src/util
DIST_COMMON = $(dist_pkgcfg_DATA) $(srcdir)/Makefile.am \
@@ -140,7 +142,7 @@ am_libgnunetutil_la_OBJECTS = bandwidth.lo bio.lo client.lo \
os_installation.lo os_network.lo os_priority.lo peer.lo \
plugin.lo program.lo pseudonym.lo resolver_api.lo scheduler.lo \
server.lo server_mst.lo server_nc.lo server_tc.lo service.lo \
- signal.lo strings.lo time.lo
+ signal.lo strings.lo time.lo speedup.lo
libgnunetutil_la_OBJECTS = $(am_libgnunetutil_la_OBJECTS)
libgnunetutil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
@@ -162,6 +164,8 @@ am_gnunet_config_diff_OBJECTS = gnunet-config-diff.$(OBJEXT)
gnunet_config_diff_OBJECTS = $(am_gnunet_config_diff_OBJECTS)
am_gnunet_resolver_OBJECTS = gnunet-resolver.$(OBJEXT)
gnunet_resolver_OBJECTS = $(am_gnunet_resolver_OBJECTS)
+am_gnunet_rsa_OBJECTS = gnunet-rsa.$(OBJEXT)
+gnunet_rsa_OBJECTS = $(am_gnunet_rsa_OBJECTS)
am_gnunet_service_resolver_OBJECTS = \
gnunet-service-resolver.$(OBJEXT)
gnunet_service_resolver_OBJECTS = \
@@ -345,6 +349,12 @@ am_test_server_disconnect_OBJECTS = test_server_disconnect.$(OBJEXT)
test_server_disconnect_OBJECTS = $(am_test_server_disconnect_OBJECTS)
test_server_disconnect_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la
+am_test_server_mst_interrupt_OBJECTS = \
+ test_server_mst_interrupt.$(OBJEXT)
+test_server_mst_interrupt_OBJECTS = \
+ $(am_test_server_mst_interrupt_OBJECTS)
+test_server_mst_interrupt_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la
am_test_server_with_client_OBJECTS = \
test_server_with_client.$(OBJEXT)
test_server_with_client_OBJECTS = \
@@ -360,6 +370,9 @@ test_server_with_client_unix_DEPENDENCIES = \
am_test_service_OBJECTS = test_service.$(OBJEXT)
test_service_OBJECTS = $(am_test_service_OBJECTS)
test_service_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la
+am_test_speedup_OBJECTS = test_speedup.$(OBJEXT)
+test_speedup_OBJECTS = $(am_test_speedup_OBJECTS)
+test_speedup_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la
am_test_strings_OBJECTS = test_strings.$(OBJEXT)
test_strings_OBJECTS = $(am_test_strings_OBJECTS)
test_strings_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la
@@ -411,9 +424,9 @@ am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libgnunet_plugin_test_la_SOURCES) \
$(libgnunetutil_la_SOURCES) $(libgnunetutilwin_la_SOURCES) \
$(gnunet_config_diff_SOURCES) $(gnunet_resolver_SOURCES) \
- $(gnunet_service_resolver_SOURCES) $(perf_crypto_hash_SOURCES) \
- $(test_bio_SOURCES) $(test_client_SOURCES) \
- $(test_common_allocation_SOURCES) \
+ $(gnunet_rsa_SOURCES) $(gnunet_service_resolver_SOURCES) \
+ $(perf_crypto_hash_SOURCES) $(test_bio_SOURCES) \
+ $(test_client_SOURCES) $(test_common_allocation_SOURCES) \
$(test_common_endian_SOURCES) $(test_common_logging_SOURCES) \
$(test_common_logging_dummy_SOURCES) \
$(test_common_logging_runtime_loglevels_SOURCES) \
@@ -439,17 +452,18 @@ SOURCES = $(libgnunet_plugin_test_la_SOURCES) \
$(test_resolver_api_SOURCES) $(test_scheduler_SOURCES) \
$(test_scheduler_delay_SOURCES) $(test_server_SOURCES) \
$(test_server_disconnect_SOURCES) \
+ $(test_server_mst_interrupt_SOURCES) \
$(test_server_with_client_SOURCES) \
$(test_server_with_client_unix_SOURCES) \
- $(test_service_SOURCES) $(test_strings_SOURCES) \
- $(test_time_SOURCES)
+ $(test_service_SOURCES) $(test_speedup_SOURCES) \
+ $(test_strings_SOURCES) $(test_time_SOURCES)
DIST_SOURCES = $(libgnunet_plugin_test_la_SOURCES) \
$(libgnunetutil_la_SOURCES) \
$(am__libgnunetutilwin_la_SOURCES_DIST) \
$(gnunet_config_diff_SOURCES) $(gnunet_resolver_SOURCES) \
- $(gnunet_service_resolver_SOURCES) $(perf_crypto_hash_SOURCES) \
- $(test_bio_SOURCES) $(test_client_SOURCES) \
- $(test_common_allocation_SOURCES) \
+ $(gnunet_rsa_SOURCES) $(gnunet_service_resolver_SOURCES) \
+ $(perf_crypto_hash_SOURCES) $(test_bio_SOURCES) \
+ $(test_client_SOURCES) $(test_common_allocation_SOURCES) \
$(test_common_endian_SOURCES) $(test_common_logging_SOURCES) \
$(test_common_logging_dummy_SOURCES) \
$(test_common_logging_runtime_loglevels_SOURCES) \
@@ -475,10 +489,11 @@ DIST_SOURCES = $(libgnunet_plugin_test_la_SOURCES) \
$(test_resolver_api_SOURCES) $(test_scheduler_SOURCES) \
$(test_scheduler_delay_SOURCES) $(test_server_SOURCES) \
$(test_server_disconnect_SOURCES) \
+ $(test_server_mst_interrupt_SOURCES) \
$(test_server_with_client_SOURCES) \
$(test_server_with_client_unix_SOURCES) \
- $(test_service_SOURCES) $(test_strings_SOURCES) \
- $(test_time_SOURCES)
+ $(test_service_SOURCES) $(test_speedup_SOURCES) \
+ $(test_strings_SOURCES) $(test_time_SOURCES)
DATA = $(dist_pkgcfg_DATA) $(pkgcfg_DATA)
ETAGS = etags
CTAGS = ctags
@@ -540,6 +555,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+JAVAPORT = @JAVAPORT@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBADD_DL = @LIBADD_DL@
@@ -573,6 +589,7 @@ LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+MONKEYPREFIX = @MONKEYPREFIX@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
@@ -780,17 +797,18 @@ libgnunetutil_la_SOURCES = \
service.c \
signal.c \
strings.c \
- time.c
+ time.c \
+ speedup.c
libgnunetutil_la_LIBADD = \
$(GCLIBADD) $(WINLIB) \
$(LIBGCRYPT_LIBS) \
$(LTLIBICONV) \
- -lltdl -lz $(XLIB)
+ -lltdl -lz -lunistring $(XLIB)
libgnunetutil_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) \
- -version-info 7:0:0
+ -version-info 8:0:0
gnunet_service_resolver_SOURCES = \
gnunet-service-resolver.c
@@ -812,6 +830,16 @@ gnunet_resolver_LDADD = \
gnunet_resolver_DEPENDENCIES = \
libgnunetutil.la
+gnunet_rsa_SOURCES = \
+ gnunet-rsa.c
+
+gnunet_rsa_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(GN_LIBINTL)
+
+gnunet_rsa_DEPENDENCIES = \
+ libgnunetutil.la
+
plugin_LTLIBRARIES = \
libgnunet_plugin_test.la
@@ -1054,6 +1082,12 @@ test_scheduler_delay_SOURCES = \
test_scheduler_delay_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
+test_server_mst_interrupt_SOURCES = \
+ test_server_mst_interrupt.c
+
+test_server_mst_interrupt_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_server_SOURCES = \
test_server.c
@@ -1096,6 +1130,12 @@ test_time_SOURCES = \
test_time_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
+test_speedup_SOURCES = \
+ test_speedup.c
+
+test_speedup_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
perf_crypto_hash_SOURCES = \
perf_crypto_hash.c
@@ -1107,7 +1147,8 @@ EXTRA_DIST = \
test_program_data.conf \
test_pseudonym_data.conf \
test_resolver_api_data.conf \
- test_service_data.conf
+ test_service_data.conf \
+ test_speedup_data.conf
all: all-am
@@ -1289,6 +1330,9 @@ gnunet-config-diff$(EXEEXT): $(gnunet_config_diff_OBJECTS) $(gnunet_config_diff_
gnunet-resolver$(EXEEXT): $(gnunet_resolver_OBJECTS) $(gnunet_resolver_DEPENDENCIES)
@rm -f gnunet-resolver$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gnunet_resolver_OBJECTS) $(gnunet_resolver_LDADD) $(LIBS)
+gnunet-rsa$(EXEEXT): $(gnunet_rsa_OBJECTS) $(gnunet_rsa_DEPENDENCIES)
+ @rm -f gnunet-rsa$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gnunet_rsa_OBJECTS) $(gnunet_rsa_LDADD) $(LIBS)
gnunet-service-resolver$(EXEEXT): $(gnunet_service_resolver_OBJECTS) $(gnunet_service_resolver_DEPENDENCIES)
@rm -f gnunet-service-resolver$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gnunet_service_resolver_OBJECTS) $(gnunet_service_resolver_LDADD) $(LIBS)
@@ -1418,6 +1462,9 @@ test_server$(EXEEXT): $(test_server_OBJECTS) $(test_server_DEPENDENCIES)
test_server_disconnect$(EXEEXT): $(test_server_disconnect_OBJECTS) $(test_server_disconnect_DEPENDENCIES)
@rm -f test_server_disconnect$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_server_disconnect_OBJECTS) $(test_server_disconnect_LDADD) $(LIBS)
+test_server_mst_interrupt$(EXEEXT): $(test_server_mst_interrupt_OBJECTS) $(test_server_mst_interrupt_DEPENDENCIES)
+ @rm -f test_server_mst_interrupt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_server_mst_interrupt_OBJECTS) $(test_server_mst_interrupt_LDADD) $(LIBS)
test_server_with_client$(EXEEXT): $(test_server_with_client_OBJECTS) $(test_server_with_client_DEPENDENCIES)
@rm -f test_server_with_client$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_server_with_client_OBJECTS) $(test_server_with_client_LDADD) $(LIBS)
@@ -1427,6 +1474,9 @@ test_server_with_client_unix$(EXEEXT): $(test_server_with_client_unix_OBJECTS) $
test_service$(EXEEXT): $(test_service_OBJECTS) $(test_service_DEPENDENCIES)
@rm -f test_service$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_service_OBJECTS) $(test_service_LDADD) $(LIBS)
+test_speedup$(EXEEXT): $(test_speedup_OBJECTS) $(test_speedup_DEPENDENCIES)
+ @rm -f test_speedup$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_speedup_OBJECTS) $(test_speedup_LDADD) $(LIBS)
test_strings$(EXEEXT): $(test_strings_OBJECTS) $(test_strings_DEPENDENCIES)
@rm -f test_strings$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_strings_OBJECTS) $(test_strings_LDADD) $(LIBS)
@@ -1466,6 +1516,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_helpers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-config-diff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-resolver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-rsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-resolver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load.Plo@am__quote@
@@ -1486,6 +1537,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_tc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speedup.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strings.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_client.Po@am__quote@
@@ -1529,9 +1581,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_scheduler_delay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_disconnect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_mst_interrupt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_with_client.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_with_client_unix.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_speedup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_strings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_time.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
diff --git a/src/util/client.c b/src/util/client.c
index 2f09a90..c29b48e 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2006, 2008, 2009 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2006, 2008, 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -26,7 +26,6 @@
* Generic TCP code for reliable, record-oriented TCP
* connections between clients and service providers.
*/
-
#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_client_lib.h"
@@ -34,7 +33,6 @@
#include "gnunet_server_lib.h"
#include "gnunet_scheduler_lib.h"
-#define DEBUG_CLIENT GNUNET_EXTRA_LOGGING
/**
* How often do we re-try tranmsitting requests before giving up?
@@ -53,7 +51,7 @@ struct GNUNET_CLIENT_TransmitHandle
/**
* Connection state.
*/
- struct GNUNET_CLIENT_Connection *sock;
+ struct GNUNET_CLIENT_Connection *client;
/**
* Function to call to get the data for transmission.
@@ -113,7 +111,7 @@ struct TransmitGetResponseContext
/**
* Client handle.
*/
- struct GNUNET_CLIENT_Connection *sock;
+ struct GNUNET_CLIENT_Connection *client;
/**
* Message to transmit; do not free, allocated
@@ -147,9 +145,9 @@ struct GNUNET_CLIENT_Connection
{
/**
- * the socket handle, NULL if not live
+ * The connection handle, NULL if not live
*/
- struct GNUNET_CONNECTION_Handle *sock;
+ struct GNUNET_CONNECTION_Handle *connection;
/**
* Our configuration.
@@ -250,6 +248,79 @@ struct GNUNET_CLIENT_Connection
/**
+ * Try connecting to the server using UNIX domain sockets.
+ *
+ * @param service_name name of service to connect to
+ * @param cfg configuration to use
+ * @return NULL on error, connection to UNIX otherwise
+ */
+static struct GNUNET_CONNECTION_Handle *
+try_unixpath (const char *service_name,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+#if AF_UNIX
+ struct GNUNET_CONNECTION_Handle *connection;
+ char *unixpath;
+
+ unixpath = NULL;
+ if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) &&
+ (0 < strlen (unixpath)))
+ {
+ /* We have a non-NULL unixpath, need to validate it */
+ connection = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
+ if (NULL != connection)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n",
+ unixpath);
+ GNUNET_free (unixpath);
+ return connection;
+ }
+ }
+ GNUNET_free_non_null (unixpath);
+#endif
+ return NULL;
+}
+
+
+/**
+ * Try connecting to the server using UNIX domain sockets.
+ *
+ * @param service_name name of service to connect to
+ * @param cfg configuration to use
+ * @return GNUNET_OK if the configuration is valid, GNUNET_SYSERR if not
+ */
+static int
+test_service_configuration (const char *service_name,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ int ret = GNUNET_SYSERR;
+ char *hostname = NULL;
+ unsigned long long port;
+#if AF_UNIX
+ char *unixpath = NULL;
+
+ if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) &&
+ (0 < strlen (unixpath)))
+ ret = GNUNET_OK;
+ GNUNET_free_non_null (unixpath);
+#endif
+
+ if ( (GNUNET_YES ==
+ GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) &&
+ (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) &&
+ (port <= 65535) && (0 != port) &&
+ (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME",
+ &hostname)) &&
+ (0 != strlen (hostname)) )
+ ret = GNUNET_OK;
+ GNUNET_free_non_null (hostname);
+ return ret;
+}
+
+
+/**
* Try to connect to the service.
*
* @param service_name name of service to connect to
@@ -261,34 +332,18 @@ static struct GNUNET_CONNECTION_Handle *
do_connect (const char *service_name,
const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt)
{
- struct GNUNET_CONNECTION_Handle *sock;
+ struct GNUNET_CONNECTION_Handle *connection;
char *hostname;
- char *unixpath;
unsigned long long port;
- sock = NULL;
-#if AF_UNIX
+ connection = NULL;
if (0 == (attempt % 2))
{
- /* on even rounds, try UNIX */
- unixpath = NULL;
- if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */
- {
- sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
- if (sock != NULL)
- {
-#if DEBUG_CLIENT
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n",
- unixpath);
-#endif
- GNUNET_free (unixpath);
- return sock;
- }
- }
- GNUNET_free_non_null (unixpath);
+ /* on even rounds, try UNIX first */
+ connection = try_unixpath (service_name, cfg);
+ if (NULL != connection)
+ return connection;
}
-#endif
-
if (GNUNET_YES ==
GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
{
@@ -319,42 +374,21 @@ do_connect (const char *service_name,
port = 0;
hostname = NULL;
}
- if (port == 0)
+ if (0 == port)
{
-#if AF_UNIX
- if (0 != (attempt % 2))
- {
- /* try UNIX */
- unixpath = NULL;
- if ((GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH",
- &unixpath)) &&
- (0 < strlen (unixpath)))
- {
- sock =
- GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
- if (sock != NULL)
- {
- GNUNET_free (unixpath);
- GNUNET_free_non_null (hostname);
- return sock;
- }
- }
- GNUNET_free_non_null (unixpath);
- }
-#endif
-#if DEBUG_CLIENT
+ /* if port is 0, try UNIX */
+ connection = try_unixpath (service_name, cfg);
+ if (NULL != connection)
+ return connection;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n",
service_name);
-#endif
GNUNET_free_non_null (hostname);
return NULL;
}
-
- sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
+ connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
GNUNET_free (hostname);
- return sock;
+ return connection;
}
@@ -369,17 +403,21 @@ struct GNUNET_CLIENT_Connection *
GNUNET_CLIENT_connect (const char *service_name,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- struct GNUNET_CLIENT_Connection *ret;
- struct GNUNET_CONNECTION_Handle *sock;
-
- sock = do_connect (service_name, cfg, 0);
- ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection));
- ret->attempts = 1;
- ret->sock = sock;
- ret->service_name = GNUNET_strdup (service_name);
- ret->cfg = cfg;
- ret->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
- return ret;
+ struct GNUNET_CLIENT_Connection *client;
+ struct GNUNET_CONNECTION_Handle *connection;
+
+ if (GNUNET_OK !=
+ test_service_configuration (service_name,
+ cfg))
+ return NULL;
+ connection = do_connect (service_name, cfg, 0);
+ client = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection));
+ client->attempts = 1;
+ client->connection = connection;
+ client->service_name = GNUNET_strdup (service_name);
+ client->cfg = cfg;
+ client->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
+ return client;
}
@@ -394,57 +432,57 @@ GNUNET_CLIENT_connect (const char *service_name,
* destroyed (unless, of course, there is an error with the server in
* which case the message may still be lost).
*
- * @param finish_pending_write should a transmission already passed to the
- * handle be completed?
- * @param sock handle to the service connection
+ * @param client handle to the service connection
*/
void
-GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock,
- int finish_pending_write)
+GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client)
{
- if (sock->in_receive == GNUNET_YES)
+ if (GNUNET_YES == client->in_receive)
{
- GNUNET_CONNECTION_receive_cancel (sock->sock);
- sock->in_receive = GNUNET_NO;
+ GNUNET_CONNECTION_receive_cancel (client->connection);
+ client->in_receive = GNUNET_NO;
}
- if (sock->th != NULL)
+ if (NULL != client->th)
{
- GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th);
- sock->th = NULL;
+ GNUNET_CLIENT_notify_transmit_ready_cancel (client->th);
+ client->th = NULL;
}
- if (NULL != sock->sock)
+ if (NULL != client->connection)
{
- GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write);
- sock->sock = NULL;
+ GNUNET_CONNECTION_destroy (client->connection);
+ client->connection = NULL;
}
- if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != client->receive_task)
{
- GNUNET_SCHEDULER_cancel (sock->receive_task);
- sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_SCHEDULER_cancel (client->receive_task);
+ client->receive_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (sock->tag != NULL)
+ if (NULL != client->tag)
{
- GNUNET_free (sock->tag);
- sock->tag = NULL;
+ GNUNET_free (client->tag);
+ client->tag = NULL;
}
- sock->receiver_handler = NULL;
- GNUNET_array_grow (sock->received_buf, sock->received_size, 0);
- GNUNET_free (sock->service_name);
- GNUNET_free (sock);
+ client->receiver_handler = NULL;
+ GNUNET_array_grow (client->received_buf, client->received_size, 0);
+ GNUNET_free (client->service_name);
+ GNUNET_free (client);
}
/**
- * Check if message is complete
+ * Check if message is complete. Sets the "msg_complete" member
+ * in the client struct.
+ *
+ * @param client connection with the buffer to check
*/
static void
-check_complete (struct GNUNET_CLIENT_Connection *conn)
+check_complete (struct GNUNET_CLIENT_Connection *client)
{
- if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
- (conn->received_pos >=
- ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)->
+ if ((client->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
+ (client->received_pos >=
+ ntohs (((const struct GNUNET_MessageHeader *) client->received_buf)->
size)))
- conn->msg_complete = GNUNET_YES;
+ client->msg_complete = GNUNET_YES;
}
@@ -464,54 +502,51 @@ static void
receive_helper (void *cls, const void *buf, size_t available,
const struct sockaddr *addr, socklen_t addrlen, int errCode)
{
- struct GNUNET_CLIENT_Connection *conn = cls;
+ struct GNUNET_CLIENT_Connection *client = cls;
struct GNUNET_TIME_Relative remaining;
GNUNET_CLIENT_MessageHandler receive_handler;
void *receive_handler_cls;
- GNUNET_assert (conn->msg_complete == GNUNET_NO);
- conn->in_receive = GNUNET_NO;
- if ((available == 0) || (conn->sock == NULL) || (errCode != 0))
+ GNUNET_assert (GNUNET_NO == client->msg_complete);
+ GNUNET_assert (GNUNET_YES == client->in_receive);
+ client->in_receive = GNUNET_NO;
+ if ((0 == available) || (NULL == client->connection) || (0 != errCode))
{
/* signal timeout! */
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n",
- (unsigned int) available, conn->sock == NULL ? "NULL" : "non-NULL",
+ "Timeout in receive_helper, available %u, client->connection %s, errCode `%s'\n",
+ (unsigned int) available, NULL == client->connection ? "NULL" : "non-NULL",
STRERROR (errCode));
-#endif
- if (NULL != (receive_handler = conn->receiver_handler))
+ if (NULL != (receive_handler = client->receiver_handler))
{
- receive_handler_cls = conn->receiver_handler_cls;
- conn->receiver_handler = NULL;
+ receive_handler_cls = client->receiver_handler_cls;
+ client->receiver_handler = NULL;
receive_handler (receive_handler_cls, NULL);
}
return;
}
-
/* FIXME: optimize for common fast case where buf contains the
* entire message and we need no copying... */
-
/* slow path: append to array */
- if (conn->received_size < conn->received_pos + available)
- GNUNET_array_grow (conn->received_buf, conn->received_size,
- conn->received_pos + available);
- memcpy (&conn->received_buf[conn->received_pos], buf, available);
- conn->received_pos += available;
- check_complete (conn);
+ if (client->received_size < client->received_pos + available)
+ GNUNET_array_grow (client->received_buf, client->received_size,
+ client->received_pos + available);
+ memcpy (&client->received_buf[client->received_pos], buf, available);
+ client->received_pos += available;
+ check_complete (client);
/* check for timeout */
- remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout);
- if (remaining.rel_value == 0)
+ remaining = GNUNET_TIME_absolute_get_remaining (client->receive_timeout);
+ if (0 == remaining.rel_value)
{
/* signal timeout! */
- if (NULL != conn->receiver_handler)
- conn->receiver_handler (conn->receiver_handler_cls, NULL);
+ if (NULL != client->receiver_handler)
+ client->receiver_handler (client->receiver_handler_cls, NULL);
return;
}
/* back to receive -- either for more data or to call callback! */
- GNUNET_CLIENT_receive (conn, conn->receiver_handler,
- conn->receiver_handler_cls, remaining);
+ GNUNET_CLIENT_receive (client, client->receiver_handler,
+ client->receiver_handler_cls, remaining);
}
@@ -524,30 +559,28 @@ receive_helper (void *cls, const void *buf, size_t available,
static void
receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CLIENT_Connection *sock = cls;
- GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler;
+ struct GNUNET_CLIENT_Connection *client = cls;
+ GNUNET_CLIENT_MessageHandler handler = client->receiver_handler;
const struct GNUNET_MessageHeader *cmsg =
- (const struct GNUNET_MessageHeader *) sock->received_buf;
- void *handler_cls = sock->receiver_handler_cls;
+ (const struct GNUNET_MessageHeader *) client->received_buf;
+ void *handler_cls = client->receiver_handler_cls;
uint16_t msize = ntohs (cmsg->size);
char mbuf[msize];
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf;
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u and size %u\n",
ntohs (cmsg->type), msize);
-#endif
- sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_assert (GNUNET_YES == sock->msg_complete);
- GNUNET_assert (sock->received_pos >= msize);
+ client->receive_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_assert (GNUNET_YES == client->msg_complete);
+ GNUNET_assert (client->received_pos >= msize);
memcpy (msg, cmsg, msize);
- memmove (sock->received_buf, &sock->received_buf[msize],
- sock->received_pos - msize);
- sock->received_pos -= msize;
- sock->msg_complete = GNUNET_NO;
- sock->receiver_handler = NULL;
- check_complete (sock);
- if (handler != NULL)
+ memmove (client->received_buf, &client->received_buf[msize],
+ client->received_pos - msize);
+ client->received_pos -= msize;
+ client->msg_complete = GNUNET_NO;
+ client->receiver_handler = NULL;
+ check_complete (client);
+ if (NULL != handler)
handler (handler_cls, msg);
}
@@ -555,17 +588,17 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
* Read from the service.
*
- * @param sock the service
+ * @param client the service
* @param handler function to call with the message
* @param handler_cls closure for handler
* @param timeout how long to wait until timing out
*/
void
-GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
+GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client,
GNUNET_CLIENT_MessageHandler handler, void *handler_cls,
struct GNUNET_TIME_Relative timeout)
{
- if (sock->sock == NULL)
+ if (NULL == client->connection)
{
/* already disconnected, fail instantly! */
GNUNET_break (0); /* this should not happen in well-written code! */
@@ -573,23 +606,21 @@ GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
handler (handler_cls, NULL);
return;
}
- sock->receiver_handler = handler;
- sock->receiver_handler_cls = handler_cls;
- sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- if (GNUNET_YES == sock->msg_complete)
+ client->receiver_handler = handler;
+ client->receiver_handler_cls = handler_cls;
+ client->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
+ if (GNUNET_YES == client->msg_complete)
{
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task);
- sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->receive_task);
+ client->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, client);
}
else
{
- GNUNET_assert (sock->in_receive == GNUNET_NO);
- sock->in_receive = GNUNET_YES;
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n");
-#endif
- GNUNET_CONNECTION_receive (sock->sock, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
- timeout, &receive_helper, sock);
+ GNUNET_assert (GNUNET_NO == client->in_receive);
+ client->in_receive = GNUNET_YES;
+ GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
+ timeout, &receive_helper, client);
}
}
@@ -614,25 +645,23 @@ service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls)
static void
confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_CLIENT_Connection *conn = cls;
+ struct GNUNET_CLIENT_Connection *client = cls;
/* We may want to consider looking at the reply in more
* detail in the future, for example, is this the
* correct service? FIXME! */
- if (msg != NULL)
+ if (NULL != msg)
{
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received confirmation that service is running.\n");
-#endif
- GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls,
+ GNUNET_SCHEDULER_add_continuation (client->test_cb, client->test_cb_cls,
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
else
{
- service_test_error (conn->test_cb, conn->test_cb_cls);
+ service_test_error (client->test_cb, client->test_cb_cls);
}
- GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
}
@@ -648,27 +677,23 @@ confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
static size_t
write_test (void *cls, size_t size, void *buf)
{
- struct GNUNET_CLIENT_Connection *conn = cls;
+ struct GNUNET_CLIENT_Connection *client = cls;
struct GNUNET_MessageHeader *msg;
if (size < sizeof (struct GNUNET_MessageHeader))
{
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n"));
-#endif
- service_test_error (conn->test_cb, conn->test_cb_cls);
- GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
+ service_test_error (client->test_cb, client->test_cb_cls);
+ GNUNET_CLIENT_disconnect (client);
return 0; /* client disconnected */
}
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST");
-#endif
msg = (struct GNUNET_MessageHeader *) buf;
msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
msg->size = htons (sizeof (struct GNUNET_MessageHeader));
- GNUNET_CLIENT_receive (conn, &confirm_handler, conn,
+ GNUNET_CLIENT_receive (client, &confirm_handler, client,
GNUNET_TIME_absolute_get_remaining
- (conn->test_deadline));
+ (client->test_deadline));
return sizeof (struct GNUNET_MessageHeader);
}
@@ -695,12 +720,10 @@ GNUNET_CLIENT_service_test (const char *service,
char *hostname;
unsigned long long port;
struct GNUNET_NETWORK_Handle *sock;
- struct GNUNET_CLIENT_Connection *conn;
+ struct GNUNET_CLIENT_Connection *client;
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n",
service);
-#endif
#ifdef AF_UNIX
{
/* probe UNIX support */
@@ -720,7 +743,7 @@ GNUNET_CLIENT_service_test (const char *service,
else
{
sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
- if (sock != NULL)
+ if (NULL != sock)
{
memset (&s_un, 0, sizeof (s_un));
s_un.sun_family = AF_UNIX;
@@ -786,7 +809,7 @@ GNUNET_CLIENT_service_test (const char *service,
s_in.sin_port = htons (port);
sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
- if (sock != NULL)
+ if (NULL != sock)
{
if (GNUNET_OK !=
GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in,
@@ -820,7 +843,7 @@ GNUNET_CLIENT_service_test (const char *service,
s_in6.sin6_port = htons (port);
sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
- if (sock != NULL)
+ if (NULL != sock)
{
if (GNUNET_OK !=
GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6,
@@ -852,8 +875,8 @@ GNUNET_CLIENT_service_test (const char *service,
GNUNET_free_non_null (hostname);
/* non-localhost, try 'connect' method */
- conn = GNUNET_CLIENT_connect (service, cfg);
- if (conn == NULL)
+ client = GNUNET_CLIENT_connect (service, cfg);
+ if (NULL == client)
{
LOG (GNUNET_ERROR_TYPE_INFO,
_("Could not connect to service `%s', must not be running.\n"),
@@ -861,20 +884,18 @@ GNUNET_CLIENT_service_test (const char *service,
service_test_error (task, task_cls);
return;
}
- conn->test_cb = task;
- conn->test_cb_cls = task_cls;
- conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
-
- if (NULL ==
- GNUNET_CLIENT_notify_transmit_ready (conn,
- sizeof (struct GNUNET_MessageHeader),
- timeout, GNUNET_YES, &write_test,
- conn))
+ client->test_cb = task;
+ client->test_cb_cls = task_cls;
+ client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
+ if (NULL == GNUNET_CLIENT_notify_transmit_ready (client,
+ sizeof (struct GNUNET_MessageHeader),
+ timeout, GNUNET_YES, &write_test,
+ client))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
_("Failure to transmit request to service `%s'\n"), service);
service_test_error (task, task_cls);
- GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
return;
}
}
@@ -908,47 +929,35 @@ client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
struct GNUNET_TIME_Relative delay;
th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
-#if DEBUG_CLIENT
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n");
-#endif
- th->sock->th = NULL;
- th->notify (th->notify_cls, 0, NULL);
- GNUNET_free (th);
- return;
- }
- th->sock->sock =
- do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++);
- if (NULL == th->sock->sock)
+ th->client->connection =
+ do_connect (th->client->service_name, th->client->cfg, th->client->attempts++);
+ if (NULL == th->client->connection)
{
/* could happen if we're out of sockets */
delay =
GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining
- (th->timeout), th->sock->back_off);
- th->sock->back_off =
+ (th->timeout), th->client->back_off);
+ th->client->back_off =
GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
- (th->sock->back_off, 2),
+ (th->client->back_off, 2),
GNUNET_TIME_UNIT_SECONDS);
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmission failed %u times, trying again in %llums.\n",
MAX_ATTEMPTS - th->attempts_left,
(unsigned long long) delay.rel_value);
-#endif
th->reconnect_task =
GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
return;
}
th->th =
- GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size,
+ GNUNET_CONNECTION_notify_transmit_ready (th->client->connection, th->size,
GNUNET_TIME_absolute_get_remaining
(th->timeout), &client_notify,
th);
- if (th->th == NULL)
+ if (NULL == th->th)
{
GNUNET_break (0);
- th->sock->th = NULL;
+ th->client->th = NULL;
th->notify (th->notify_cls, 0, NULL);
GNUNET_free (th);
return;
@@ -969,49 +978,47 @@ static size_t
client_notify (void *cls, size_t size, void *buf)
{
struct GNUNET_CLIENT_TransmitHandle *th = cls;
+ struct GNUNET_CLIENT_Connection *client = th->client;
size_t ret;
struct GNUNET_TIME_Relative delay;
th->th = NULL;
- th->sock->th = NULL;
- if (buf == NULL)
+ client->th = NULL;
+ if (NULL == buf)
{
delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
delay.rel_value /= 2;
- if ((0 !=
- (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) ||
- (GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) ||
+ if ((GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) ||
(delay.rel_value < 1))
{
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmission failed %u times, giving up.\n",
MAX_ATTEMPTS - th->attempts_left);
-#endif
GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
return 0;
}
/* auto-retry */
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Failed to connect to `%s', automatically trying again.\n",
- th->sock->service_name);
-#endif
- GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO);
- th->sock->sock = NULL;
- delay = GNUNET_TIME_relative_min (delay, th->sock->back_off);
- th->sock->back_off =
+ client->service_name);
+ if (GNUNET_YES == client->in_receive)
+ {
+ GNUNET_CONNECTION_receive_cancel (client->connection);
+ client->in_receive = GNUNET_NO;
+ }
+ GNUNET_CONNECTION_destroy (client->connection);
+ client->connection = NULL;
+ delay = GNUNET_TIME_relative_min (delay, client->back_off);
+ client->back_off =
GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
- (th->sock->back_off, 2),
+ (client->back_off, 2),
GNUNET_TIME_UNIT_SECONDS);
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmission failed %u times, trying again in %llums.\n",
MAX_ATTEMPTS - th->attempts_left,
(unsigned long long) delay.rel_value);
-#endif
- th->sock->th = th;
+ client->th = th;
th->reconnect_task =
GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
return 0;
@@ -1028,7 +1035,7 @@ client_notify (void *cls, size_t size, void *buf)
* are free in the transmission buffer. May call the notify
* method immediately if enough space is available.
*
- * @param sock connection to the service
+ * @param client connection to the service
* @param size number of bytes to send
* @param timeout after how long should we give up (and call
* notify with buf NULL and size 0)?
@@ -1043,7 +1050,7 @@ client_notify (void *cls, size_t size, void *buf)
* a handle if the notify callback was queued (can be used to cancel)
*/
struct GNUNET_CLIENT_TransmitHandle *
-GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
+GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
size_t size,
struct GNUNET_TIME_Relative timeout,
int auto_retry,
@@ -1052,7 +1059,7 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
{
struct GNUNET_CLIENT_TransmitHandle *th;
- if (NULL != sock->th)
+ if (NULL != client->th)
{
/* If this breaks, you most likley called this function twice without waiting
* for completion or canceling the request */
@@ -1060,31 +1067,31 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
return NULL;
}
th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
- th->sock = sock;
+ th->client = client;
th->size = size;
th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
th->auto_retry = auto_retry;
th->notify = notify;
th->notify_cls = notify_cls;
th->attempts_left = MAX_ATTEMPTS;
- sock->th = th;
- if (sock->sock == NULL)
+ client->th = th;
+ if (NULL == client->connection)
{
th->reconnect_task =
- GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry,
+ GNUNET_SCHEDULER_add_delayed (client->back_off, &client_delayed_retry,
th);
}
else
{
th->th =
- GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout,
+ GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, timeout,
&client_notify, th);
if (NULL == th->th)
{
GNUNET_break (0);
GNUNET_free (th);
- sock->th = NULL;
+ client->th = NULL;
return NULL;
}
}
@@ -1101,7 +1108,7 @@ void
GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
*th)
{
- if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != th->reconnect_task)
{
GNUNET_assert (NULL == th->th);
GNUNET_SCHEDULER_cancel (th->reconnect_task);
@@ -1112,7 +1119,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
GNUNET_assert (NULL != th->th);
GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th);
}
- th->sock->th = NULL;
+ th->client->th = NULL;
GNUNET_free (th);
}
@@ -1134,14 +1141,12 @@ transmit_for_response (void *cls, size_t size, void *buf)
struct TransmitGetResponseContext *tc = cls;
uint16_t msize;
- tc->sock->tag = NULL;
+ tc->client->tag = NULL;
msize = ntohs (tc->hdr->size);
if (NULL == buf)
{
-#if DEBUG_CLIENT
LOG (GNUNET_ERROR_TYPE_DEBUG,
_("Could not submit request, not expecting to receive a response.\n"));
-#endif
if (NULL != tc->rn)
tc->rn (tc->rn_cls, NULL);
GNUNET_free (tc);
@@ -1149,7 +1154,7 @@ transmit_for_response (void *cls, size_t size, void *buf)
}
GNUNET_assert (size >= msize);
memcpy (buf, tc->hdr, msize);
- GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls,
+ GNUNET_CLIENT_receive (tc->client, tc->rn, tc->rn_cls,
GNUNET_TIME_absolute_get_remaining (tc->timeout));
GNUNET_free (tc);
return msize;
@@ -1163,7 +1168,7 @@ transmit_for_response (void *cls, size_t size, void *buf)
* will be called with a "NULL" response (in which
* case the connection should probably be destroyed).
*
- * @param sock connection to use
+ * @param client connection to use
* @param hdr message to transmit
* @param timeout when to give up (for both transmission
* and for waiting for a response)
@@ -1178,7 +1183,7 @@ transmit_for_response (void *cls, size_t size, void *buf)
* is already pending
*/
int
-GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
+GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client,
const struct GNUNET_MessageHeader *hdr,
struct GNUNET_TIME_Relative timeout,
int auto_retry,
@@ -1188,26 +1193,26 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
struct TransmitGetResponseContext *tc;
uint16_t msize;
- if (NULL != sock->th)
+ if (NULL != client->th)
return GNUNET_SYSERR;
- GNUNET_assert (sock->tag == NULL);
+ GNUNET_assert (NULL == client->tag);
msize = ntohs (hdr->size);
tc = GNUNET_malloc (sizeof (struct TransmitGetResponseContext) + msize);
- tc->sock = sock;
+ tc->client = client;
tc->hdr = (const struct GNUNET_MessageHeader *) &tc[1];
memcpy (&tc[1], hdr, msize);
tc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
tc->rn = rn;
tc->rn_cls = rn_cls;
if (NULL ==
- GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry,
+ GNUNET_CLIENT_notify_transmit_ready (client, msize, timeout, auto_retry,
&transmit_for_response, tc))
{
GNUNET_break (0);
GNUNET_free (tc);
return GNUNET_SYSERR;
}
- sock->tag = tc;
+ client->tag = tc;
return GNUNET_OK;
}
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index e19aa8c..2c0fd57 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -530,6 +530,8 @@ parse_all_definitions ()
gnunet_force_log_parsed = GNUNET_YES;
}
#endif
+
+
/**
* Setup logging.
*
@@ -569,30 +571,29 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
if (NULL == fn)
return GNUNET_SYSERR;
dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
- altlog_fd = OPEN (fn, O_APPEND |
#if WINDOWS
+ altlog_fd = OPEN (fn, O_APPEND |
O_BINARY |
-#endif
O_WRONLY | O_CREAT,
-#if WINDOWS
- _S_IREAD | _S_IWRITE
+ _S_IREAD | _S_IWRITE);
#else
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+ altlog_fd = OPEN (fn, O_APPEND |
+ O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
- );
if (altlog_fd != -1)
{
int dup_return;
if (GNUNET_stderr != NULL)
fclose (GNUNET_stderr);
dup_return = dup2 (altlog_fd, 2);
- close (altlog_fd);
+ (void) close (altlog_fd);
if (dup_return != -1)
{
altlog = fdopen (2, "ab");
if (altlog == NULL)
{
- close (2);
+ (void) close (2);
altlog_fd = -1;
}
}
diff --git a/src/util/configuration.c b/src/util/configuration.c
index f24b2c2..308672f 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -21,7 +21,6 @@
/**
* @file src/util/configuration.c
* @brief configuration management
- *
* @author Christian Grothoff
*/
@@ -197,19 +196,19 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
for (i = strlen (line) - 1; (i >= 0) && (isspace ((unsigned char) line[i]));
i--)
line[i] = '\0';
- if (1 == sscanf (line, "@INLINE@ %191[^\n]", value))
+ if (1 == SSCANF (line, "@INLINE@ %191[^\n]", value))
{
/* @INLINE@ value */
if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value))
ret = GNUNET_SYSERR; /* failed to parse included config */
}
- else if (1 == sscanf (line, "[%99[^]]]", value))
+ else if (1 == SSCANF (line, "[%99[^]]]", value))
{
/* [value] */
GNUNET_free (section);
section = GNUNET_strdup (value);
}
- else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))
+ else if (2 == SSCANF (line, " %63[^= ] = %191[^\n]", tag, value))
{
/* tag = value */
/* Strip LF */
@@ -233,7 +232,7 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
}
GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]);
}
- else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))
+ else if (1 == SSCANF (line, " %63[^= ] =[^\n]", tag))
{
/* tag = */
GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
@@ -1228,14 +1227,42 @@ static int
parse_configuration_file (void *cls, const char *filename)
{
struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ char * ext;
int ret;
+ /* Examine file extension */
+ ext = strrchr (filename, '.');
+ if ((NULL == ext) || (0 != strcmp (ext, ".conf")))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename);
+ return GNUNET_OK;
+ }
+
ret = GNUNET_CONFIGURATION_parse (cfg, filename);
return ret;
}
/**
+ * Load default configuration. This function will parse the
+ * defaults from the given defaults_d directory.
+ *
+ * @param cfg configuration to update
+ * @param defaults_d directory with the defaults
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *defaults_d)
+{
+ if (GNUNET_SYSERR ==
+ GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg))
+ return GNUNET_SYSERR; /* no configuration at all found */
+ return GNUNET_OK;
+}
+
+
+/**
* Load configuration (starts with defaults, then loads
* system-specific configuration).
*
diff --git a/src/util/connection.c b/src/util/connection.c
index 8224479..31e6399 100644
--- a/src/util/connection.c
+++ b/src/util/connection.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -44,32 +44,6 @@
#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
-/**
- * Possible functions to call after connect failed or succeeded.
- */
-enum ConnectContinuations
-{
- /**
- * Call nothing.
- */
- COCO_NONE = 0,
-
- /**
- * Call "receive_again".
- */
- COCO_RECEIVE_AGAIN = 1,
-
- /**
- * Call "transmit_ready".
- */
- COCO_TRANSMIT_READY = 2,
-
- /**
- * Call "destroy_continuation".
- */
- COCO_DESTROY_CONTINUATION = 4
-};
-
/**
* Transmission handle. There can only be one for each connection.
@@ -89,9 +63,9 @@ struct GNUNET_CONNECTION_TransmitHandle
void *notify_ready_cls;
/**
- * Our socket handle.
+ * Our connection handle.
*/
- struct GNUNET_CONNECTION_Handle *sh;
+ struct GNUNET_CONNECTION_Handle *connection;
/**
* Timeout for receiving (in absolute time).
@@ -142,7 +116,7 @@ struct AddressProbe
/**
* Connection for which we are probing.
*/
- struct GNUNET_CONNECTION_Handle *h;
+ struct GNUNET_CONNECTION_Handle *connection;
/**
* Lenth of addr.
@@ -150,14 +124,14 @@ struct AddressProbe
socklen_t addrlen;
/**
- * Task waiting for the socket to finish connecting.
+ * Task waiting for the connection to finish connecting.
*/
GNUNET_SCHEDULER_TaskIdentifier task;
};
/**
- * @brief handle for a network socket
+ * @brief handle for a network connection
*/
struct GNUNET_CONNECTION_Handle
{
@@ -185,7 +159,7 @@ struct GNUNET_CONNECTION_Handle
struct sockaddr *addr;
/**
- * Pointer to the hostname if socket was
+ * Pointer to the hostname if connection was
* created using DNS lookup, otherwise NULL.
*/
char *hostname;
@@ -243,11 +217,6 @@ struct GNUNET_CONNECTION_Handle
GNUNET_SCHEDULER_TaskIdentifier write_task;
/**
- * Destroy task (if already scheduled).
- */
- GNUNET_SCHEDULER_TaskIdentifier destroy_task;
-
- /**
* Handle to a pending DNS lookup request.
*/
struct GNUNET_RESOLVER_RequestHandle *dns_active;
@@ -263,21 +232,11 @@ struct GNUNET_CONNECTION_Handle
struct GNUNET_TIME_Absolute receive_timeout;
/**
- * Functions to call after connect failed or succeeded.
- */
- enum ConnectContinuations ccs;
-
- /**
* Maximum number of bytes to read (for receiving).
*/
size_t max;
/**
- * Ignore GNUNET_SCHEDULER_REASON_SHUTDOWN for this socket.
- */
- int ignore_shutdown;
-
- /**
* Port to connect to.
*/
uint16_t port;
@@ -292,73 +251,75 @@ struct GNUNET_CONNECTION_Handle
};
+
/**
* Set the persist option on this connection handle. Indicates
* that the underlying socket or fd should never really be closed.
* Used for indicating process death.
*
- * @param sock the connection to set persistent
+ * @param connection the connection to set persistent
*/
void
-GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *sock)
+GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
{
- sock->persist = GNUNET_YES;
+ connection->persist = GNUNET_YES;
}
/**
- * Disable the "CORK" feature for communication with the given socket,
+ * Disable the "CORK" feature for communication with the given connection,
* forcing the OS to immediately flush the buffer on transmission
* instead of potentially buffering multiple messages. Essentially
* reduces the OS send buffers to zero.
* Used to make sure that the last messages sent through the connection
* reach the other side before the process is terminated.
*
- * @param sock the connection to make flushing and blocking
+ * @param connection the connection to make flushing and blocking
* @return GNUNET_OK on success
*/
int
-GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock)
+GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
{
- return GNUNET_NETWORK_socket_disable_corking (sock->sock);
+ return GNUNET_NETWORK_socket_disable_corking (connection->sock);
}
+
/**
- * Create a socket handle by boxing an existing OS socket. The OS
+ * Create a connection handle by boxing an existing OS socket. The OS
* socket should henceforth be no longer used directly.
- * GNUNET_socket_destroy will close it.
+ * GNUNET_connection_destroy will close it.
*
* @param osSocket existing socket to box
- * @return the boxed socket handle
+ * @return the boxed connection handle
*/
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
{
- struct GNUNET_CONNECTION_Handle *ret;
+ struct GNUNET_CONNECTION_Handle *connection;
- ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
- ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
- ret->write_buffer = GNUNET_malloc (ret->write_buffer_size);
- ret->sock = osSocket;
- return ret;
+ connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
+ connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+ connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+ connection->sock = osSocket;
+ return connection;
}
/**
- * Create a socket handle by accepting on a listen socket. This
+ * Create a connection handle by accepting on a listen socket. This
* function may block if the listen socket has no connection ready.
*
* @param access function to use to check if access is allowed
* @param access_cls closure for access
* @param lsock listen socket
- * @return the socket handle, NULL on error
+ * @return the connection handle, NULL on error
*/
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
void *access_cls,
struct GNUNET_NETWORK_Handle *lsock)
{
- struct GNUNET_CONNECTION_Handle *ret;
+ struct GNUNET_CONNECTION_Handle *connection;
char addr[128];
socklen_t addrlen;
struct GNUNET_NETWORK_Handle *sock;
@@ -369,7 +330,6 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
void *uaddr;
struct GNUNET_CONNECTION_Credentials *gcp;
struct GNUNET_CONNECTION_Credentials gc;
-
#ifdef SO_PEERCRED
struct ucred uc;
socklen_t olen;
@@ -392,7 +352,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
sa = (struct sockaddr *) addr;
v6 = (struct sockaddr_in6 *) addr;
- if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
+ if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
{
/* convert to V4 address */
v4 = GNUNET_malloc (sizeof (struct sockaddr_in));
@@ -417,7 +377,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
gcp = NULL;
gc.uid = 0;
gc.gid = 0;
- if (sa->sa_family == AF_UNIX)
+ if (AF_UNIX == sa->sa_family)
{
#if HAVE_GETPEEREID
/* most BSDs */
@@ -453,10 +413,10 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
#endif
}
- if ((access != NULL) &&
+ if ((NULL != access) &&
(GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen))))
{
- if (aret == GNUNET_NO)
+ if (GNUNET_NO == aret)
LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"),
GNUNET_a2s (uaddr, addrlen));
GNUNET_break (GNUNET_OK ==
@@ -465,147 +425,151 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
GNUNET_free (uaddr);
return NULL;
}
- ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
- ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
- ret->write_buffer = GNUNET_malloc (ret->write_buffer_size);
- ret->addr = uaddr;
- ret->addrlen = addrlen;
- ret->sock = sock;
+ connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
+ connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+ connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+ connection->addr = uaddr;
+ connection->addrlen = addrlen;
+ connection->sock = sock;
LOG (GNUNET_ERROR_TYPE_INFO,
_("Accepting connection from `%s': %p\n"),
- GNUNET_a2s (uaddr, addrlen), ret);
- return ret;
+ GNUNET_a2s (uaddr, addrlen), connection);
+ return connection;
}
+
/**
* Obtain the network address of the other party.
*
- * @param sock the client to get the address for
+ * @param connection the client to get the address for
* @param addr where to store the address
* @param addrlen where to store the length of the address
* @return GNUNET_OK on success
*/
int
-GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *sock,
+GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
void **addr, size_t * addrlen)
{
- if ((sock->addr == NULL) || (sock->addrlen == 0))
+ if ((NULL == connection->addr) || (0 == connection->addrlen))
return GNUNET_NO;
- *addr = GNUNET_malloc (sock->addrlen);
- memcpy (*addr, sock->addr, sock->addrlen);
- *addrlen = sock->addrlen;
+ *addr = GNUNET_malloc (connection->addrlen);
+ memcpy (*addr, connection->addr, connection->addrlen);
+ *addrlen = connection->addrlen;
return GNUNET_OK;
}
/**
- * This function is called after establishing a connection either has
- * succeeded or timed out. Note that it is possible that the attempt
- * timed out and that we're immediately retrying. If we are retrying,
- * we need to wait again (or timeout); if we succeeded, we need to
- * wait for data (or timeout).
+ * Tell the receiver callback that we had an IO error.
*
- * @param cls our connection handle
- * @param tc task context describing why we are here
+ * @param connection connection to signal error
+ * @param errcode error code to send
*/
static void
-receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode)
+{
+ GNUNET_CONNECTION_Receiver receiver;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Receive encounters error (%s), connection closed (%p)\n",
+ STRERROR (errcode),
+ connection);
+ GNUNET_assert (NULL != (receiver = connection->receiver));
+ connection->receiver = NULL;
+ receiver (connection->receiver_cls, NULL, 0, connection->addr, connection->addrlen, errcode);
+}
/**
- * Scheduler let us know that the connect task is finished (or was
- * cancelled due to shutdown). Now really clean up.
+ * Tell the receiver callback that a timeout was reached.
*
- * @param cls our "struct GNUNET_CONNECTION_Handle *"
- * @param tc unused
+ * @param connection connection to signal for
+ */
+static void
+signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
+{
+ GNUNET_CONNECTION_Receiver receiver;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection signals timeout to receiver (%p)!\n",
+ connection);
+ GNUNET_assert (NULL != (receiver = connection->receiver));
+ connection->receiver = NULL;
+ receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
+}
+
+
+/**
+ * We failed to transmit data to the service, signal the error.
+ *
+ * @param connection handle that had trouble
+ * @param ecode error code (errno)
*/
static void
-destroy_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
+ int ecode)
{
- struct GNUNET_CONNECTION_Handle *sock = cls;
GNUNET_CONNECTION_TransmitReadyNotify notify;
- struct AddressProbe *pos;
- sock->destroy_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_assert (sock->dns_active == NULL);
- if (0 != (sock->ccs & COCO_TRANSMIT_READY))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy waits for CCS-TR to be done (%p)\n",
- sock);
- sock->ccs |= COCO_DESTROY_CONTINUATION;
- return;
- }
- if (sock->write_task != GNUNET_SCHEDULER_NO_TASK)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroy waits for write_task to be done (%p)\n", sock);
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task);
- sock->destroy_task =
- GNUNET_SCHEDULER_add_after (sock->write_task, &destroy_continuation,
- sock);
- return;
- }
- if (0 != (sock->ccs & COCO_RECEIVE_AGAIN))
- {
- sock->ccs |= COCO_DESTROY_CONTINUATION;
- return;
- }
- if (sock->sock != NULL)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Transmission encounterd error (%s), connection closed (%p)\n",
+ STRERROR (ecode),
+ connection);
+ if (NULL != connection->sock)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket (%p)\n", sock);
- if (sock->persist != GNUNET_YES)
- {
- if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR))
- && (errno != ENOTCONN) && (errno != ECONNRESET))
- LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown");
- }
+ GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR);
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
+ connection->sock = NULL;
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
}
- if (sock->read_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != connection->read_task)
{
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task);
- sock->destroy_task =
- GNUNET_SCHEDULER_add_after (sock->read_task, &destroy_continuation,
- sock);
+ /* send errors trigger read errors... */
+ GNUNET_SCHEDULER_cancel (connection->read_task);
+ connection->read_task = GNUNET_SCHEDULER_NO_TASK;
+ signal_receive_timeout (connection);
return;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", sock);
- while (NULL != (pos = sock->ap_head))
- {
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
- GNUNET_SCHEDULER_cancel (pos->task);
- GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos);
- GNUNET_free (pos);
- }
- GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK);
- GNUNET_assert (sock->ccs == COCO_NONE);
- if (NULL != (notify = sock->nth.notify_ready))
- {
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
- }
+ if (NULL == connection->nth.notify_ready)
+ return; /* nobody to tell about it */
+ notify = connection->nth.notify_ready;
+ connection->nth.notify_ready = NULL;
+ notify (connection->nth.notify_ready_cls, 0, NULL);
+}
- if (sock->sock != NULL)
+
+/**
+ * We've failed for good to establish a connection (timeout or
+ * no more addresses to try).
+ *
+ * @param connection the connection we tried to establish
+ */
+static void
+connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
+{
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"),
+ connection->hostname, connection->port);
+ GNUNET_break (NULL == connection->ap_head);
+ GNUNET_break (NULL == connection->ap_tail);
+ GNUNET_break (GNUNET_NO == connection->dns_active);
+ GNUNET_break (NULL == connection->sock);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
+
+ /* signal errors for jobs that used to wait on the connection */
+ if (NULL != connection->receiver)
+ signal_receive_error (connection, ECONNREFUSED);
+ if (NULL != connection->nth.notify_ready)
{
- if (sock->persist != GNUNET_YES)
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock));
- else
- GNUNET_free (sock->sock); /* at least no memory leak (we deliberately
- * leak the socket in this special case) ... */
+ GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+ connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ signal_transmit_error (connection, ECONNREFUSED);
}
- GNUNET_free_non_null (sock->addr);
- GNUNET_free_non_null (sock->hostname);
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing memory of connection %p.\n", sock);
- GNUNET_free (sock->write_buffer);
- GNUNET_free (sock);
}
-
/**
- * See if we are now connected. If not, wait longer for
- * connect to succeed. If connected, we should be able
- * to write now as well, unless we timed out.
+ * We are ready to transmit (or got a timeout).
*
* @param cls our connection handle
* @param tc task context describing why we are here
@@ -615,98 +579,52 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
/**
- * We've failed for good to establish a connection.
+ * This function is called once we either timeout or have data ready
+ * to read.
*
- * @param h the connection we tried to establish
+ * @param cls connection to read from
+ * @param tc scheduler context
*/
static void
-connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h)
-{
- LOG ((0 !=
- strncmp (h->hostname, "localhost:",
- 10)) ? GNUNET_ERROR_TYPE_INFO : GNUNET_ERROR_TYPE_WARNING,
- _
- ("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"),
- h->hostname, h->port);
- /* connect failed / timed out */
- GNUNET_break (h->ap_head == NULL);
- GNUNET_break (h->ap_tail == NULL);
- GNUNET_break (h->dns_active == GNUNET_NO);
- GNUNET_break (h->sock == NULL);
-
- /* trigger jobs that used to wait on "connect_task" */
- if (0 != (h->ccs & COCO_RECEIVE_AGAIN))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_fail_continuation triggers receive_again (%p)\n", h);
- h->ccs -= COCO_RECEIVE_AGAIN;
- h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h);
- }
- if (0 != (h->ccs & COCO_TRANSMIT_READY))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n",
- h);
- GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK);
- GNUNET_SCHEDULER_cancel (h->nth.timeout_task);
- h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
- h->ccs -= COCO_TRANSMIT_READY;
- GNUNET_assert (h->nth.notify_ready != NULL);
- GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK);
- h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h);
- }
- if (0 != (h->ccs & COCO_DESTROY_CONTINUATION))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_fail_continuation runs destroy_continuation (%p)\n", h);
- h->ccs -= COCO_DESTROY_CONTINUATION;
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task);
- h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h);
- }
-}
+receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
/**
* We've succeeded in establishing a connection.
*
- * @param h the connection we tried to establish
+ * @param connection the connection we tried to establish
*/
static void
-connect_success_continuation (struct GNUNET_CONNECTION_Handle *h)
+connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection to `%s' succeeded! (%p)\n",
- GNUNET_a2s (h->addr, h->addrlen), h);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Connection to `%s' succeeded! (%p)\n",
+ GNUNET_a2s (connection->addr, connection->addrlen), connection);
/* trigger jobs that waited for the connection */
- if (0 != (h->ccs & COCO_RECEIVE_AGAIN))
+ if (NULL != connection->receiver)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_success_continuation runs receive_again (%p)\n", h);
- h->ccs -= COCO_RECEIVE_AGAIN;
- h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h);
+ "Connection succeeded, starting with receiving data (%p)\n",
+ connection);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->read_task);
+ connection->read_task =
+ GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
+ (connection->receive_timeout), connection->sock,
+ &receive_ready, connection);
}
- if (0 != (h->ccs & COCO_TRANSMIT_READY))
+ if (NULL != connection->nth.notify_ready)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n",
- h);
- GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK);
- GNUNET_SCHEDULER_cancel (h->nth.timeout_task);
- h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
- h->ccs -= COCO_TRANSMIT_READY;
- GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK);
- GNUNET_assert (h->nth.notify_ready != NULL);
- h->write_task =
+ "Connection succeeded, starting with sending data (%p)\n",
+ connection);
+ GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+ connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_assert (connection->write_task == GNUNET_SCHEDULER_NO_TASK);
+ connection->write_task =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
- (h->nth.transmit_timeout), h->sock,
- &transmit_ready, h);
- }
- if (0 != (h->ccs & COCO_DESTROY_CONTINUATION))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "connect_success_continuation runs destroy_continuation (%p)\n", h);
- h->ccs -= COCO_DESTROY_CONTINUATION;
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task);
- h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h);
+ (connection->nth.transmit_timeout), connection->sock,
+ &transmit_ready, connection);
}
}
@@ -723,48 +641,48 @@ connect_probe_continuation (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct AddressProbe *ap = cls;
- struct GNUNET_CONNECTION_Handle *h = ap->h;
+ struct GNUNET_CONNECTION_Handle *connection = ap->connection;
struct AddressProbe *pos;
int error;
socklen_t len;
- GNUNET_assert (ap->sock != NULL);
- GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, ap);
+ GNUNET_assert (NULL != ap->sock);
+ GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, ap);
len = sizeof (error);
errno = 0;
error = 0;
if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
(GNUNET_OK !=
GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, &error,
- &len)) || (error != 0))
+ &len)) || (0 != error))
{
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
GNUNET_free (ap);
- if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO))
- connect_fail_continuation (h);
+ if ((NULL == connection->ap_head) && (GNUNET_NO == connection->dns_active))
+ connect_fail_continuation (connection);
return;
}
- GNUNET_assert (h->sock == NULL);
- h->sock = ap->sock;
- GNUNET_assert (h->addr == NULL);
- h->addr = GNUNET_malloc (ap->addrlen);
- memcpy (h->addr, ap->addr, ap->addrlen);
- h->addrlen = ap->addrlen;
+ GNUNET_assert (NULL == connection->sock);
+ connection->sock = ap->sock;
+ GNUNET_assert (NULL == connection->addr);
+ connection->addr = GNUNET_malloc (ap->addrlen);
+ memcpy (connection->addr, ap->addr, ap->addrlen);
+ connection->addrlen = ap->addrlen;
GNUNET_free (ap);
/* cancel all other attempts */
- while (NULL != (pos = h->ap_head))
+ while (NULL != (pos = connection->ap_head))
{
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
GNUNET_SCHEDULER_cancel (pos->task);
- GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos);
+ GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
GNUNET_free (pos);
}
- connect_success_continuation (h);
+ connect_success_continuation (connection);
}
/**
- * Try to establish a socket connection given the specified address.
+ * Try to establish a connection given the specified address.
* This function is called by the resolver once we have a DNS reply.
*
* @param cls our "struct GNUNET_CONNECTION_Handle *"
@@ -775,37 +693,37 @@ static void
try_connect_using_address (void *cls, const struct sockaddr *addr,
socklen_t addrlen)
{
- struct GNUNET_CONNECTION_Handle *h = cls;
+ struct GNUNET_CONNECTION_Handle *connection = cls;
struct AddressProbe *ap;
struct GNUNET_TIME_Relative delay;
- if (addr == NULL)
+ if (NULL == addr)
{
- h->dns_active = NULL;
- if ((NULL == h->ap_head) && (NULL == h->sock))
- connect_fail_continuation (h);
+ connection->dns_active = NULL;
+ if ((NULL == connection->ap_head) && (NULL == connection->sock))
+ connect_fail_continuation (connection);
return;
}
- if (h->sock != NULL)
+ if (NULL != connection->sock)
return; /* already connected */
- GNUNET_assert (h->addr == NULL);
+ GNUNET_assert (NULL == connection->addr);
/* try to connect */
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Trying to connect using address `%s:%u/%s:%u'\n", h->hostname, h->port,
- GNUNET_a2s (addr, addrlen), h->port);
+ "Trying to connect using address `%s:%u/%s:%u'\n", connection->hostname, connection->port,
+ GNUNET_a2s (addr, addrlen), connection->port);
ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
ap->addr = (const struct sockaddr *) &ap[1];
memcpy (&ap[1], addr, addrlen);
ap->addrlen = addrlen;
- ap->h = h;
+ ap->connection = connection;
switch (ap->addr->sa_family)
{
case AF_INET:
- ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port);
+ ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
break;
case AF_INET6:
- ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port);
+ ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
break;
default:
GNUNET_break (0);
@@ -813,39 +731,39 @@ try_connect_using_address (void *cls, const struct sockaddr *addr,
return; /* not supported by us */
}
ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0);
- if (ap->sock == NULL)
+ if (NULL == ap->sock)
{
GNUNET_free (ap);
return; /* not supported by OS */
}
LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"),
- GNUNET_a2s (ap->addr, ap->addrlen), h);
+ GNUNET_a2s (ap->addr, ap->addrlen), connection);
if ((GNUNET_OK !=
GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) &&
- (errno != EINPROGRESS))
+ (EINPROGRESS != errno))
{
/* maybe refused / unsupported address, try next */
LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
#if 0
LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%s' (%p)\n"),
- GNUNET_a2s (ap->addr, ap->addrlen), h);
+ GNUNET_a2s (ap->addr, ap->addrlen), connection);
#endif
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
GNUNET_free (ap);
return;
}
- GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap);
+ GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT;
- if (h->nth.notify_ready != NULL)
+ if (NULL != connection->nth.notify_ready)
delay =
GNUNET_TIME_relative_min (delay,
- GNUNET_TIME_absolute_get_remaining (h->
+ GNUNET_TIME_absolute_get_remaining (connection->
nth.transmit_timeout));
- if (h->receiver != NULL)
+ if (NULL != connection->receiver)
delay =
GNUNET_TIME_relative_min (delay,
GNUNET_TIME_absolute_get_remaining
- (h->receive_timeout));
+ (connection->receive_timeout));
ap->task =
GNUNET_SCHEDULER_add_write_net (delay, ap->sock,
&connect_probe_continuation, ap);
@@ -853,45 +771,45 @@ try_connect_using_address (void *cls, const struct sockaddr *addr,
/**
- * Create a socket handle by (asynchronously) connecting to a host.
+ * Create a connection handle by (asynchronously) connecting to a host.
* This function returns immediately, even if the connection has not
* yet been established. This function only creates TCP connections.
*
* @param cfg configuration to use
* @param hostname name of the host to connect to
* @param port port to connect to
- * @return the socket handle
+ * @return the connection handle
*/
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle
*cfg, const char *hostname,
uint16_t port)
{
- struct GNUNET_CONNECTION_Handle *ret;
+ struct GNUNET_CONNECTION_Handle *connection;
GNUNET_assert (0 < strlen (hostname)); /* sanity check */
- ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
- ret->cfg = cfg;
- ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
- ret->write_buffer = GNUNET_malloc (ret->write_buffer_size);
- ret->port = port;
- ret->hostname = GNUNET_strdup (hostname);
- ret->dns_active =
- GNUNET_RESOLVER_ip_get (ret->hostname, AF_UNSPEC,
+ connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
+ connection->cfg = cfg;
+ connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+ connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+ connection->port = port;
+ connection->hostname = GNUNET_strdup (hostname);
+ connection->dns_active =
+ GNUNET_RESOLVER_ip_get (connection->hostname, AF_UNSPEC,
GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
- &try_connect_using_address, ret);
- return ret;
+ &try_connect_using_address, connection);
+ return connection;
}
/**
- * Create a socket handle by connecting to a UNIX domain service.
+ * Create a connection handle by connecting to a UNIX domain service.
* This function returns immediately, even if the connection has not
* yet been established. This function only creates UNIX connections.
*
* @param cfg configuration to use
* @param unixpath path to connect to
- * @return the socket handle, NULL on systems without UNIX support
+ * @return the connection handle, NULL on systems without UNIX support
*/
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
@@ -899,7 +817,7 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
*cfg, const char *unixpath)
{
#ifdef AF_UNIX
- struct GNUNET_CONNECTION_Handle *ret;
+ struct GNUNET_CONNECTION_Handle *connection;
struct sockaddr_un *un;
size_t slen;
@@ -918,32 +836,32 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
#if LINUX
un->sun_path[0] = '\0';
#endif
- ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
- ret->cfg = cfg;
- ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
- ret->write_buffer = GNUNET_malloc (ret->write_buffer_size);
- ret->port = 0;
- ret->hostname = NULL;
- ret->addr = (struct sockaddr *) un;
- ret->addrlen = slen;
- ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
- if (NULL == ret->sock)
+ connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
+ connection->cfg = cfg;
+ connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+ connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+ connection->port = 0;
+ connection->hostname = NULL;
+ connection->addr = (struct sockaddr *) un;
+ connection->addrlen = slen;
+ connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
+ if (NULL == connection->sock)
{
- GNUNET_free (ret->addr);
- GNUNET_free (ret->write_buffer);
- GNUNET_free (ret);
+ GNUNET_free (connection->addr);
+ GNUNET_free (connection->write_buffer);
+ GNUNET_free (connection);
return NULL;
}
if (GNUNET_OK !=
- GNUNET_NETWORK_socket_connect (ret->sock, ret->addr, ret->addrlen))
+ GNUNET_NETWORK_socket_connect (connection->sock, connection->addr, connection->addrlen))
{
/* Just return; we expect everything to work eventually so don't fail HARD */
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock));
- ret->sock = NULL;
- return ret;
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
+ connection->sock = NULL;
+ return connection;
}
- connect_success_continuation (ret);
- return ret;
+ connect_success_continuation (connection);
+ return connection;
#else
return NULL;
#endif
@@ -951,14 +869,14 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
/**
- * Create a socket handle by (asynchronously) connecting to a host.
+ * Create a connection handle by (asynchronously) connecting to a host.
* This function returns immediately, even if the connection has not
* yet been established. This function only creates TCP connections.
*
* @param af_family address family to use
* @param serv_addr server address
* @param addrlen length of server address
- * @return the socket handle
+ * @return the connection handle
*/
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_sockaddr (int af_family,
@@ -966,17 +884,16 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family,
socklen_t addrlen)
{
struct GNUNET_NETWORK_Handle *s;
- struct GNUNET_CONNECTION_Handle *ret;
-
+ struct GNUNET_CONNECTION_Handle *connection;
s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
- if (s == NULL)
+ if (NULL == s)
{
LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket");
return NULL;
}
if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
- (errno != EINPROGRESS))
+ (EINPROGRESS != errno))
{
/* maybe refused / unsupported address, try next */
LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
@@ -985,293 +902,221 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family,
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
return NULL;
}
- ret = GNUNET_CONNECTION_create_from_existing (s);
- ret->addr = GNUNET_malloc (addrlen);
- memcpy (ret->addr, serv_addr, addrlen);
- ret->addrlen = addrlen;
+ connection = GNUNET_CONNECTION_create_from_existing (s);
+ connection->addr = GNUNET_malloc (addrlen);
+ memcpy (connection->addr, serv_addr, addrlen);
+ connection->addrlen = addrlen;
LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"),
- GNUNET_a2s (serv_addr, addrlen), ret);
- return ret;
+ GNUNET_a2s (serv_addr, addrlen), connection);
+ return connection;
}
/**
- * Check if socket is valid (no fatal errors have happened so far).
- * Note that a socket that is still trying to connect is considered
+ * Check if connection is valid (no fatal errors have happened so far).
+ * Note that a connection that is still trying to connect is considered
* valid.
*
- * @param sock socket to check
+ * @param connection connection to check
* @return GNUNET_YES if valid, GNUNET_NO otherwise
*/
int
-GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock)
+GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
{
- if ((sock->ap_head != NULL) || (sock->dns_active != NULL))
+ if ((NULL != connection->ap_head) || (NULL != connection->dns_active))
return GNUNET_YES; /* still trying to connect */
- return (sock->sock == NULL) ? GNUNET_NO : GNUNET_YES;
+ return (NULL == connection->sock) ? GNUNET_NO : GNUNET_YES;
}
/**
- * Close the socket and free associated resources. Pending
- * transmissions may be completed or dropped depending on the
- * arguments. If a receive call is pending and should
- * NOT be completed, 'GNUNET_CONNECTION_receive_cancel'
- * should be called explicitly first.
+ * Close the connection and free associated resources. There must
+ * not be any pending requests for reading or writing to the
+ * connection at this time.
*
- * @param sock socket to destroy
- * @param finish_pending_write should pending writes be completed or aborted?
- * (this applies to transmissions where the data has already been
- * read from the application; all other transmissions should be
- * aborted using 'GNUNET_CONNECTION_notify_transmit_ready_cancel').
+ * @param connection connection to destroy
*/
void
-GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock,
- int finish_pending_write)
+GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
{
- if (GNUNET_NO == finish_pending_write)
+ struct AddressProbe *pos;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
+ GNUNET_assert (NULL == connection->nth.notify_ready);
+ GNUNET_assert (NULL == connection->receiver);
+ if (GNUNET_SCHEDULER_NO_TASK != connection->write_task)
{
- if (sock->write_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (sock->write_task);
- sock->write_task = GNUNET_SCHEDULER_NO_TASK;
- sock->write_buffer_off = 0;
- }
- sock->nth.notify_ready = NULL;
+ GNUNET_SCHEDULER_cancel (connection->write_task);
+ connection->write_task = GNUNET_SCHEDULER_NO_TASK;
+ connection->write_buffer_off = 0;
}
- if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL))
+ if (GNUNET_SCHEDULER_NO_TASK != connection->read_task)
{
- GNUNET_RESOLVER_request_cancel (sock->dns_active);
- sock->dns_active = NULL;
+ GNUNET_SCHEDULER_cancel (connection->read_task);
+ connection->read_task = GNUNET_SCHEDULER_NO_TASK;
}
-
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task);
- sock->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock);
-}
-
-
-/**
- * Tell the receiver callback that a timeout was reached.
- */
-static void
-signal_timeout (struct GNUNET_CONNECTION_Handle *sh)
-{
- GNUNET_CONNECTION_Receiver receiver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Network signals time out to receiver (%p)!\n",
- sh);
- GNUNET_assert (NULL != (receiver = sh->receiver));
- sh->receiver = NULL;
- receiver (sh->receiver_cls, NULL, 0, NULL, 0, 0);
-}
-
-
-/**
- * Tell the receiver callback that we had an IO error.
- */
-static void
-signal_error (struct GNUNET_CONNECTION_Handle *sh, int errcode)
-{
- GNUNET_CONNECTION_Receiver receiver;
-
- GNUNET_assert (NULL != (receiver = sh->receiver));
- sh->receiver = NULL;
- receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode);
+ if (GNUNET_SCHEDULER_NO_TASK != connection->nth.timeout_task)
+ {
+ GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+ connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ connection->nth.notify_ready = NULL;
+ if (NULL != connection->dns_active)
+ {
+ GNUNET_RESOLVER_request_cancel (connection->dns_active);
+ connection->dns_active = NULL;
+ }
+ while (NULL != (pos = connection->ap_head))
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
+ GNUNET_SCHEDULER_cancel (pos->task);
+ GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
+ GNUNET_free (pos);
+ }
+ if ( (NULL != connection->sock) &&
+ (GNUNET_YES != connection->persist) )
+ {
+ if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) &&
+ (ENOTCONN != errno) &&
+ (ECONNRESET != errno) )
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown");
+ }
+ if (NULL != connection->sock)
+ {
+ if (GNUNET_YES != connection->persist)
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
+ else
+ GNUNET_free (connection->sock); /* at least no memory leak (we deliberately
+ * leak the socket in this special case) ... */
+ }
+ GNUNET_free_non_null (connection->addr);
+ GNUNET_free_non_null (connection->hostname);
+ GNUNET_free (connection->write_buffer);
+ GNUNET_free (connection);
}
/**
* This function is called once we either timeout
* or have data ready to read.
+ *
+ * @param cls connection to read from
+ * @param tc scheduler context
*/
static void
receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CONNECTION_Handle *sh = cls;
- struct GNUNET_TIME_Absolute now;
- char buffer[sh->max];
+ struct GNUNET_CONNECTION_Handle *connection = cls;
+ char buffer[connection->max];
ssize_t ret;
GNUNET_CONNECTION_Receiver receiver;
- sh->read_task = GNUNET_SCHEDULER_NO_TASK;
- if ((GNUNET_YES == sh->ignore_shutdown) &&
- (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
+ connection->read_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
/* ignore shutdown request, go again immediately */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Ignoring shutdown signal per configuration\n");
- sh->read_task =
+ connection->read_task =
GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
- (sh->receive_timeout), sh->sock,
- &receive_ready, sh);
+ (connection->receive_timeout), connection->sock,
+ &receive_ready, connection);
return;
}
- now = GNUNET_TIME_absolute_get ();
- if ((now.abs_value > sh->receive_timeout.abs_value) ||
- (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) ||
- (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
{
- if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Receive from `%s' encounters error: time out by %llums... (%p)\n",
- GNUNET_a2s (sh->addr, sh->addrlen),
- GNUNET_TIME_absolute_get_duration (sh->receive_timeout).rel_value,
- sh);
- signal_timeout (sh);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Receive from `%s' encounters error: timeout (%p)\n",
+ GNUNET_a2s (connection->addr, connection->addrlen),
+ GNUNET_TIME_absolute_get_duration (connection->receive_timeout).rel_value,
+ connection);
+ signal_receive_timeout (connection);
return;
}
- if (sh->sock == NULL)
+ if (NULL == connection->sock)
{
/* connect failed for good */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Receive encounters error, socket closed... (%p)\n", sh);
- signal_error (sh, ECONNREFUSED);
+ signal_receive_error (connection, ECONNREFUSED);
return;
}
- GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock));
+ GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock));
RETRY:
- ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max);
- if (ret == -1)
+ ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max);
+ if (-1 == ret)
{
- if (errno == EINTR)
+ if (EINTR == errno)
goto RETRY;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving: %s\n", STRERROR (errno));
- signal_error (sh, errno);
+ signal_receive_error (connection, errno);
return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG,
"receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret,
- sh->max, GNUNET_a2s (sh->addr, sh->addrlen), sh);
- GNUNET_assert (NULL != (receiver = sh->receiver));
- sh->receiver = NULL;
- receiver (sh->receiver_cls, buffer, ret, sh->addr, sh->addrlen, 0);
+ connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection);
+ GNUNET_assert (NULL != (receiver = connection->receiver));
+ connection->receiver = NULL;
+ receiver (connection->receiver_cls, buffer, ret, connection->addr, connection->addrlen, 0);
}
/**
- * This function is called after establishing a connection either has
- * succeeded or timed out. Note that it is possible that the attempt
- * timed out and that we're immediately retrying. If we are retrying,
- * we need to wait again (or timeout); if we succeeded, we need to
- * wait for data (or timeout).
- *
- * @param cls our connection handle
- * @param tc task context describing why we are here
- */
-static void
-receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_CONNECTION_Handle *sh = cls;
- struct GNUNET_TIME_Absolute now;
-
- sh->read_task = GNUNET_SCHEDULER_NO_TASK;
- if (sh->sock == NULL)
- {
- /* not connected and no longer trying */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Receive encounters error, socket closed (%p)...\n", sh);
- signal_error (sh, ECONNREFUSED);
- return;
- }
- now = GNUNET_TIME_absolute_get ();
- if ((now.abs_value > sh->receive_timeout.abs_value) ||
- (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Receive encounters error: time out (%p)...\n", sh);
- signal_timeout (sh);
- return;
- }
- GNUNET_assert (sh->sock != NULL);
- /* connect succeeded, wait for data! */
- sh->read_task =
- GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
- (sh->receive_timeout), sh->sock,
- &receive_ready, sh);
-}
-
-
-/**
- * Receive data from the given socket. Note that this function will
+ * Receive data from the given connection. Note that this function will
* call "receiver" asynchronously using the scheduler. It will
* "immediately" return. Note that there MUST only be one active
- * receive call per socket at any given point in time (so do not
+ * receive call per connection at any given point in time (so do not
* call receive again until the receiver callback has been invoked).
*
- * @param sock socket handle
+ * @param connection connection handle
* @param max maximum number of bytes to read
- * @param timeout maximum amount of time to wait (use -1 for "forever")
+ * @param timeout maximum amount of time to wait
* @param receiver function to call with received data
* @param receiver_cls closure for receiver
*/
void
-GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max,
+GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max,
struct GNUNET_TIME_Relative timeout,
GNUNET_CONNECTION_Receiver receiver,
void *receiver_cls)
{
- struct GNUNET_SCHEDULER_TaskContext tc;
-
- GNUNET_assert ((sock->read_task == GNUNET_SCHEDULER_NO_TASK) &&
- (0 == (sock->ccs & COCO_RECEIVE_AGAIN)) &&
- (sock->receiver == NULL));
- sock->receiver = receiver;
- sock->receiver_cls = receiver_cls;
- sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- sock->max = max;
- if (sock->sock != NULL)
+ GNUNET_assert ((GNUNET_SCHEDULER_NO_TASK == connection->read_task) &&
+ (NULL == connection->receiver));
+ GNUNET_assert (NULL != receiver);
+ connection->receiver = receiver;
+ connection->receiver_cls = receiver_cls;
+ connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
+ connection->max = max;
+ if (NULL != connection->sock)
{
- memset (&tc, 0, sizeof (tc));
- tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE;
- receive_again (sock, &tc);
+ connection->read_task =
+ GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
+ (connection->receive_timeout), connection->sock,
+ &receive_ready, connection);
return;
}
- if ((sock->dns_active == NULL) && (sock->ap_head == NULL))
+ if ((NULL == connection->dns_active) && (NULL == connection->ap_head))
{
+ connection->receiver = NULL;
receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT);
return;
}
- sock->ccs += COCO_RECEIVE_AGAIN;
-}
-
-
-/**
- * Configure this connection to ignore shutdown signals.
- *
- * @param sock socket handle
- * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default
- */
-void
-GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock,
- int do_ignore)
-{
- sock->ignore_shutdown = do_ignore;
}
/**
- * Cancel receive job on the given socket. Note that the
+ * Cancel receive job on the given connection. Note that the
* receiver callback must not have been called yet in order
* for the cancellation to be valid.
*
- * @param sock socket handle
+ * @param connection connection handle
* @return closure of the original receiver callback closure
*/
void *
-GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock)
+GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
{
- if (sock->read_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task));
- sock->read_task = GNUNET_SCHEDULER_NO_TASK;
- }
- else
+ if (GNUNET_SCHEDULER_NO_TASK != connection->read_task)
{
- GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN));
- sock->ccs -= COCO_RECEIVE_AGAIN;
+ GNUNET_assert (connection == GNUNET_SCHEDULER_cancel (connection->read_task));
+ connection->read_task = GNUNET_SCHEDULER_NO_TASK;
}
- sock->receiver = NULL;
- return sock->receiver_cls;
+ connection->receiver = NULL;
+ return connection->receiver_cls;
}
@@ -1279,41 +1124,42 @@ GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock)
* Try to call the transmit notify method (check if we do
* have enough space available first)!
*
- * @param sock socket for which we should do this processing
+ * @param connection connection for which we should do this processing
* @return GNUNET_YES if we were able to call notify
*/
static int
-process_notify (struct GNUNET_CONNECTION_Handle *sock)
+process_notify (struct GNUNET_CONNECTION_Handle *connection)
{
size_t used;
size_t avail;
size_t size;
GNUNET_CONNECTION_TransmitReadyNotify notify;
- GNUNET_assert (sock->write_task == GNUNET_SCHEDULER_NO_TASK);
- if (NULL == (notify = sock->nth.notify_ready))
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
+ if (NULL == (notify = connection->nth.notify_ready))
return GNUNET_NO;
- used = sock->write_buffer_off - sock->write_buffer_pos;
- avail = sock->write_buffer_size - used;
- size = sock->nth.notify_size;
+ used = connection->write_buffer_off - connection->write_buffer_pos;
+ avail = connection->write_buffer_size - used;
+ size = connection->nth.notify_size;
if (size > avail)
return GNUNET_NO;
- sock->nth.notify_ready = NULL;
- if (sock->write_buffer_size - sock->write_buffer_off < size)
+ connection->nth.notify_ready = NULL;
+ if (connection->write_buffer_size - connection->write_buffer_off < size)
{
/* need to compact */
- memmove (sock->write_buffer, &sock->write_buffer[sock->write_buffer_pos],
+ memmove (connection->write_buffer, &connection->write_buffer[connection->write_buffer_pos],
used);
- sock->write_buffer_off -= sock->write_buffer_pos;
- sock->write_buffer_pos = 0;
+ connection->write_buffer_off -= connection->write_buffer_pos;
+ connection->write_buffer_pos = 0;
}
- avail = sock->write_buffer_size - sock->write_buffer_off;
+ avail = connection->write_buffer_size - connection->write_buffer_off;
GNUNET_assert (avail >= size);
size =
- notify (sock->nth.notify_ready_cls, avail,
- &sock->write_buffer[sock->write_buffer_off]);
+ notify (connection->nth.notify_ready_cls, avail,
+ &connection->write_buffer[connection->write_buffer_off]);
GNUNET_assert (size <= avail);
- sock->write_buffer_off += size;
+ if (0 != size)
+ connection->write_buffer_off += size;
return GNUNET_YES;
}
@@ -1332,19 +1178,18 @@ process_notify (struct GNUNET_CONNECTION_Handle *sock)
static void
transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CONNECTION_Handle *sock = cls;
+ struct GNUNET_CONNECTION_Handle *connection = cls;
GNUNET_CONNECTION_TransmitReadyNotify notify;
- sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
- sock->hostname,
- sock->port, GNUNET_a2s (sock->addr, sock->addrlen), sock);
- GNUNET_assert (0 != (sock->ccs & COCO_TRANSMIT_READY));
- sock->ccs -= COCO_TRANSMIT_READY; /* remove request */
- notify = sock->nth.notify_ready;
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
+ connection->hostname,
+ connection->port, GNUNET_a2s (connection->addr, connection->addrlen), connection);
+ notify = connection->nth.notify_ready;
+ GNUNET_assert (NULL != notify);
+ connection->nth.notify_ready = NULL;
+ notify (connection->nth.notify_ready_cls, 0, NULL);
}
@@ -1360,54 +1205,21 @@ transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static void
connect_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CONNECTION_Handle *sock = cls;
+ struct GNUNET_CONNECTION_Handle *connection = cls;
GNUNET_CONNECTION_TransmitReadyNotify notify;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
- sock->nth.notify_size, sock->hostname, sock->port, sock);
- sock->write_task = GNUNET_SCHEDULER_NO_TASK;
- notify = sock->nth.notify_ready;
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
-}
-
-
-/**
- * FIXME
- *
- * @param sock FIXME
- */
-static void
-transmit_error (struct GNUNET_CONNECTION_Handle *sock)
-{
- GNUNET_CONNECTION_TransmitReadyNotify notify;
-
- if (NULL != sock->sock)
- {
- GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR);
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock));
- sock->sock = NULL;
- }
- if (sock->read_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (sock->read_task);
- sock->read_task = GNUNET_SCHEDULER_NO_TASK;
- signal_timeout (sock);
- return;
- }
- if (sock->nth.notify_ready == NULL)
- return; /* nobody to tell about it */
- notify = sock->nth.notify_ready;
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
+ connection->nth.notify_size, connection->hostname, connection->port, connection);
+ connection->write_task = GNUNET_SCHEDULER_NO_TASK;
+ notify = connection->nth.notify_ready;
+ connection->nth.notify_ready = NULL;
+ notify (connection->nth.notify_ready_cls, 0, NULL);
}
/**
- * See if we are now connected. If not, wait longer for
- * connect to succeed. If connected, we should be able
- * to write now as well, unless we timed out.
+ * We are ready to transmit (or got a timeout).
*
* @param cls our connection handle
* @param tc task context describing why we are here
@@ -1415,27 +1227,27 @@ transmit_error (struct GNUNET_CONNECTION_Handle *sock)
static void
transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CONNECTION_Handle *sock = cls;
+ struct GNUNET_CONNECTION_Handle *connection = cls;
GNUNET_CONNECTION_TransmitReadyNotify notify;
ssize_t ret;
size_t have;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", sock);
- GNUNET_assert (sock->write_task != GNUNET_SCHEDULER_NO_TASK);
- sock->write_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != connection->write_task);
+ connection->write_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task);
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
- if ((sock->ignore_shutdown == GNUNET_YES) && (NULL != sock->sock))
+ if (NULL != connection->sock)
goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmit to `%s' fails, shutdown happened (%p).\n",
- GNUNET_a2s (sock->addr, sock->addrlen), sock);
- notify = sock->nth.notify_ready;
+ GNUNET_a2s (connection->addr, connection->addrlen), connection);
+ notify = connection->nth.notify_ready;
if (NULL != notify)
{
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
+ connection->nth.notify_ready = NULL;
+ notify (connection->nth.notify_ready_cls, 0, NULL);
}
return;
}
@@ -1443,95 +1255,97 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmit to `%s' fails, time out reached (%p).\n",
- GNUNET_a2s (sock->addr, sock->addrlen), sock);
- notify = sock->nth.notify_ready;
+ GNUNET_a2s (connection->addr, connection->addrlen), connection);
+ notify = connection->nth.notify_ready;
GNUNET_assert (NULL != notify);
- sock->nth.notify_ready = NULL;
- notify (sock->nth.notify_ready_cls, 0, NULL);
+ connection->nth.notify_ready = NULL;
+ notify (connection->nth.notify_ready_cls, 0, NULL);
return;
}
- GNUNET_assert (NULL != sock->sock);
- if (tc->write_ready == NULL)
+ GNUNET_assert (NULL != connection->sock);
+ if (NULL == tc->write_ready)
{
- /* special circumstances (in particular,
- * PREREQ_DONE after connect): not yet ready to write,
- * but no "fatal" error either. Hence retry. */
+ /* special circumstances (in particular, PREREQ_DONE after
+ * connect): not yet ready to write, but no "fatal" error either.
+ * Hence retry. */
goto SCHEDULE_WRITE;
}
- if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock))
+ if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, connection->sock))
{
- LOG (GNUNET_ERROR_TYPE_INFO,
- _
- ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"),
- sock);
- transmit_error (sock);
- return; /* connect failed for good, we're finished */
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
+ /* special circumstances (in particular, shutdown): not yet ready
+ * to write, but no "fatal" error either. Hence retry. */
+ goto SCHEDULE_WRITE;
}
- GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos);
- if ((sock->nth.notify_ready != NULL) &&
- (sock->write_buffer_size < sock->nth.notify_size))
+ GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
+ if ((NULL != connection->nth.notify_ready) &&
+ (connection->write_buffer_size < connection->nth.notify_size))
{
- sock->write_buffer =
- GNUNET_realloc (sock->write_buffer, sock->nth.notify_size);
- sock->write_buffer_size = sock->nth.notify_size;
+ connection->write_buffer =
+ GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
+ connection->write_buffer_size = connection->nth.notify_size;
}
- process_notify (sock);
- have = sock->write_buffer_off - sock->write_buffer_pos;
- if (have == 0)
+ process_notify (connection);
+ have = connection->write_buffer_off - connection->write_buffer_pos;
+ if (0 == have)
{
/* no data ready for writing, terminate write loop */
return;
}
- GNUNET_assert (have <= sock->write_buffer_size);
- GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size);
- GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
+ GNUNET_assert (have <= connection->write_buffer_size);
+ GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
+ GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
RETRY:
ret =
- GNUNET_NETWORK_socket_send (sock->sock,
- &sock->write_buffer[sock->write_buffer_pos],
- have);
- if (ret == -1)
+ GNUNET_NETWORK_socket_send (connection->sock,
+ &connection->write_buffer[connection->write_buffer_pos],
+ have);
+ if (-1 == ret)
{
- if (errno == EINTR)
+ if (EINTR == errno)
goto RETRY;
- LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "send");
- transmit_error (sock);
+ if (GNUNET_SCHEDULER_NO_TASK != connection->write_task)
+ {
+ GNUNET_SCHEDULER_cancel (connection->write_task);
+ connection->write_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ signal_transmit_error (connection, errno);
return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n",
- (unsigned int) ret, have, GNUNET_a2s (sock->addr, sock->addrlen), sock);
- sock->write_buffer_pos += ret;
- if (sock->write_buffer_pos == sock->write_buffer_off)
+ "Connection transmitted %u/%u bytes to `%s' (%p)\n",
+ (unsigned int) ret, have, GNUNET_a2s (connection->addr, connection->addrlen), connection);
+ connection->write_buffer_pos += ret;
+ if (connection->write_buffer_pos == connection->write_buffer_off)
{
/* transmitted all pending data */
- sock->write_buffer_pos = 0;
- sock->write_buffer_off = 0;
+ connection->write_buffer_pos = 0;
+ connection->write_buffer_off = 0;
}
- if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready))
+ if ((0 == connection->write_buffer_off) && (NULL == connection->nth.notify_ready))
return; /* all data sent! */
/* not done writing, schedule more */
SCHEDULE_WRITE:
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Re-scheduling transmit_ready (more to do) (%p).\n", sock);
- have = sock->write_buffer_off - sock->write_buffer_pos;
- GNUNET_assert ((sock->nth.notify_ready != NULL) || (have > 0));
- if (sock->write_task == GNUNET_SCHEDULER_NO_TASK)
- sock->write_task =
- GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready ==
+ "Re-scheduling transmit_ready (more to do) (%p).\n", connection);
+ have = connection->write_buffer_off - connection->write_buffer_pos;
+ GNUNET_assert ((NULL != connection->nth.notify_ready) || (have > 0));
+ if (GNUNET_SCHEDULER_NO_TASK == connection->write_task)
+ connection->write_task =
+ GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready ==
NULL) ? GNUNET_TIME_UNIT_FOREVER_REL :
GNUNET_TIME_absolute_get_remaining
- (sock->nth.transmit_timeout),
- sock->sock, &transmit_ready, sock);
+ (connection->nth.transmit_timeout),
+ connection->sock, &transmit_ready, connection);
}
/**
- * Ask the socket to call us once the specified number of bytes
+ * Ask the connection to call us once the specified number of bytes
* are free in the transmission buffer. May call the notify
* method immediately if enough space is available.
*
- * @param sock socket
+ * @param connection connection
* @param size number of bytes to send
* @param timeout after how long should we give up (and call
* notify with buf NULL and size 0)?
@@ -1541,55 +1355,55 @@ SCHEDULE_WRITE:
* NULL if we are already going to notify someone else (busy)
*/
struct GNUNET_CONNECTION_TransmitHandle *
-GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *sock,
+GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
size_t size,
struct GNUNET_TIME_Relative timeout,
GNUNET_CONNECTION_TransmitReadyNotify
notify, void *notify_cls)
{
- if (sock->nth.notify_ready != NULL)
+ if (NULL != connection->nth.notify_ready)
{
GNUNET_assert (0);
return NULL;
}
- GNUNET_assert (notify != NULL);
+ GNUNET_assert (NULL != notify);
GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
- GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size);
- GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
- GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_off);
- sock->nth.notify_ready = notify;
- sock->nth.notify_ready_cls = notify_cls;
- sock->nth.sh = sock;
- sock->nth.notify_size = size;
- sock->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task);
- if ((sock->sock == NULL) && (sock->ap_head == NULL) &&
- (sock->dns_active == NULL))
+ GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
+ GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
+ GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
+ connection->nth.notify_ready = notify;
+ connection->nth.notify_ready_cls = notify_cls;
+ connection->nth.connection = connection;
+ connection->nth.notify_size = size;
+ connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task);
+ if ((NULL == connection->sock) &&
+ (NULL == connection->ap_head) &&
+ (NULL == connection->dns_active))
{
- if (sock->write_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (sock->write_task);
- sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock);
- return &sock->nth;
+ if (GNUNET_SCHEDULER_NO_TASK != connection->write_task)
+ GNUNET_SCHEDULER_cancel (connection->write_task);
+ connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, connection);
+ return &connection->nth;
}
- if (GNUNET_SCHEDULER_NO_TASK != sock->write_task)
- return &sock->nth;
- if (sock->sock != NULL)
+ if (GNUNET_SCHEDULER_NO_TASK != connection->write_task)
+ return &connection->nth; /* previous transmission still in progress */
+ if (NULL != connection->sock)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmit_ready (%p).\n", sock);
- sock->write_task =
+ /* connected, try to transmit now */
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmission (%p).\n", connection);
+ connection->write_task =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
- (sock->nth.transmit_timeout),
- sock->sock, &transmit_ready, sock);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", sock);
- sock->ccs |= COCO_TRANSMIT_READY;
- sock->nth.timeout_task =
- GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, sock);
+ (connection->nth.transmit_timeout),
+ connection->sock, &transmit_ready, connection);
+ return &connection->nth;
}
- return &sock->nth;
+ /* not yet connected, wait for connection */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Need to wait to schedule transmission for connection, adding timeout task (%p).\n", connection);
+ connection->nth.timeout_task =
+ GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, connection);
+ return &connection->nth;
}
@@ -1603,24 +1417,18 @@ GNUNET_CONNECTION_notify_transmit_ready_cancel (struct
GNUNET_CONNECTION_TransmitHandle
*th)
{
- GNUNET_assert (th->notify_ready != NULL);
- if (0 != (th->sh->ccs & COCO_TRANSMIT_READY))
+ GNUNET_assert (NULL != th->notify_ready);
+ th->notify_ready = NULL;
+ if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "notify_transmit_ready_cancel cancels timeout_task (%p)\n", th);
GNUNET_SCHEDULER_cancel (th->timeout_task);
th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- th->sh->ccs -= COCO_TRANSMIT_READY;
}
- else
+ if (GNUNET_SCHEDULER_NO_TASK != th->connection->write_task)
{
- if (th->sh->write_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (th->sh->write_task);
- th->sh->write_task = GNUNET_SCHEDULER_NO_TASK;
- }
+ GNUNET_SCHEDULER_cancel (th->connection->write_task);
+ th->connection->write_task = GNUNET_SCHEDULER_NO_TASK;
}
- th->notify_ready = NULL;
}
/* end of connection.c */
diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c
index 84aab6b..8c226f6 100644
--- a/src/util/container_bloomfilter.c
+++ b/src/util/container_bloomfilter.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2006, 2008, 2011 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2003, 2004, 2006, 2008, 2011, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -350,14 +350,16 @@ iterateBits (const struct GNUNET_CONTAINER_BloomFilter *bf,
bitCount = bf->addressesPerElement;
tmp[0] = *key;
round = 0;
+ GNUNET_assert (bf->bitArraySize > 0);
+ GNUNET_assert (bf->bitArraySize * 8LL > bf->bitArraySize);
while (bitCount > 0)
{
while (slot < (sizeof (GNUNET_HashCode) / sizeof (uint32_t)))
{
if (GNUNET_YES !=
callback (arg, bf,
- (((uint32_t *) & tmp[round & 1])[slot]) &
- ((bf->bitArraySize * 8) - 1)))
+ (((uint32_t *) & tmp[round & 1])[slot]) %
+ ((bf->bitArraySize * 8LL))))
return;
slot++;
bitCount--;
@@ -442,7 +444,8 @@ testBitCallback (void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf,
*
* @param filename the name of the file (or the prefix)
* @param size the size of the bloom-filter (number of
- * bytes of storage space to use)
+ * bytes of storage space to use); will be rounded up
+ * to next power of 2
* @param k the number of GNUNET_CRYPTO_hash-functions to apply per
* element (number of bits set per element in the set)
* @return the bloomfilter
@@ -549,8 +552,6 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size,
}
bf->bitArraySize = size;
bf->addressesPerElement = k;
- memset (bf->bitArray, 0, bf->bitArraySize);
-
if (GNUNET_YES != must_read)
return bf; /* already done! */
/* Read from the file what bits we can */
@@ -606,33 +607,22 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, size_t size,
unsigned int k)
{
struct GNUNET_CONTAINER_BloomFilter *bf;
- size_t ui;
- if ((k == 0) || (size == 0))
- return NULL;
- ui = 1;
- while (ui < size)
- ui *= 2;
- if (size != ui)
- {
- GNUNET_break (0);
+ if ((0 == k) || (0 == size))
return NULL;
- }
bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter));
bf->filename = NULL;
bf->fh = NULL;
bf->bitArray = GNUNET_malloc_large (size);
- if (bf->bitArray == NULL)
+ if (NULL == bf->bitArray)
{
GNUNET_free (bf);
return NULL;
}
bf->bitArraySize = size;
bf->addressesPerElement = k;
- if (data != NULL)
+ if (NULL != data)
memcpy (bf->bitArray, data, size);
- else
- memset (bf->bitArray, 0, bf->bitArraySize);
return bf;
}
@@ -848,7 +838,6 @@ GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
bf->bitArraySize = size;
bf->bitArray = GNUNET_malloc (size);
- memset (bf->bitArray, 0, bf->bitArraySize);
if (bf->filename != NULL)
make_empty_file (bf->fh, bf->bitArraySize * 4LL);
while (GNUNET_YES == iterator (iterator_cls, &hc))
diff --git a/src/util/container_heap.c b/src/util/container_heap.c
index c34e220..b9cab1e 100644
--- a/src/util/container_heap.c
+++ b/src/util/container_heap.c
@@ -30,7 +30,7 @@
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
-#define DEBUG 0
+#define EXTRA_CHECKS 0
/**
* Node in the heap.
@@ -104,7 +104,7 @@ struct GNUNET_CONTAINER_Heap
};
-#if DEBUG
+#if EXTRA_CHECKS
/**
* Check if internal invariants hold for the given node.
*
@@ -401,7 +401,7 @@ GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap)
insert_node (heap, heap->root, root->right_child);
}
GNUNET_free (root);
-#if DEBUG
+#if EXTRA_CHECKS
GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) ||
(heap->size == heap->root->tree_size + 1));
CHECK (heap->root);
@@ -502,7 +502,7 @@ GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node)
if (heap->walk_pos == node)
heap->walk_pos = NULL;
GNUNET_free (node);
-#if DEBUG
+#if EXTRA_CHECKS
CHECK (heap->root);
GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) ||
(heap->size == heap->root->tree_size + 1));
@@ -523,13 +523,13 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
struct GNUNET_CONTAINER_HeapNode *node,
GNUNET_CONTAINER_HeapCostType new_cost)
{
-#if DEBUG
+#if EXTRA_CHECKS
GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) ||
(heap->size == heap->root->tree_size + 1));
CHECK (heap->root);
#endif
remove_node (node);
-#if DEBUG
+#if EXTRA_CHECKS
CHECK (heap->root);
GNUNET_assert (((heap->size == 1) && (heap->root == NULL)) ||
(heap->size == heap->root->tree_size + 2));
@@ -539,7 +539,7 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
heap->root = node;
else
insert_node (heap, heap->root, node);
-#if DEBUG
+#if EXTRA_CHECKS
CHECK (heap->root);
GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) ||
(heap->size == heap->root->tree_size + 1));
diff --git a/src/util/container_slist.c b/src/util/container_slist.c
index 7b85dc8..6b58325 100644
--- a/src/util/container_slist.c
+++ b/src/util/container_slist.c
@@ -250,10 +250,11 @@ GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l)
/**
* Check if a list contains a certain element
- *
* @param l list
* @param buf payload buffer to find
* @param len length of the payload (number of bytes in buf)
+ *
+ * @return GNUNET_YES if found, GNUNET_NO otherwise
*/
int
GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l,
@@ -267,6 +268,32 @@ GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l,
return GNUNET_NO;
}
+typedef int (*Comparator)(const void *, size_t, const void *, size_t);
+
+/**
+ * Check if a list contains a certain element
+ *
+ * @param l list
+ * @param buf payload buffer to find
+ * @param len length of the payload (number of bytes in buf)
+ * @param compare comparison function, should return 0 if compared elements match
+ *
+ * @return NULL if the 'buf' could not be found, pointer to the
+ * list element, if found
+ */
+void *
+GNUNET_CONTAINER_slist_contains2 (const struct GNUNET_CONTAINER_SList *l,
+ const void *buf, size_t len,
+ Comparator compare)
+{
+ struct GNUNET_CONTAINER_SList_Elem *e;
+
+ for (e = l->head; e != NULL; e = e->next)
+ if ((e->len == len) && (*compare)(buf, len, e->elem, e->len) == 0)
+ return e->elem;
+ return NULL;
+}
+
/**
* Count the elements of a list
diff --git a/src/util/crypto_aes.c b/src/util/crypto_aes.c
index 8b031f3..d5c36d7 100644
--- a/src/util/crypto_aes.c
+++ b/src/util/crypto_aes.c
@@ -34,6 +34,8 @@
/**
* Create a new SessionKey (for AES-256).
+ *
+ * @param key session key to initialize
*/
void
GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key)
@@ -44,6 +46,7 @@ GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key)
htonl (GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH));
}
+
/**
* Check that a new session key is well-formed.
*
@@ -56,16 +59,55 @@ GNUNET_CRYPTO_aes_check_session_key (const struct GNUNET_CRYPTO_AesSessionKey
uint32_t crc;
crc = GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH);
- if (ntohl (key->crc32) == crc)
- return GNUNET_OK;
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ if (ntohl (key->crc32) != crc)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Initialize AES cipher.
+ *
+ * @param handle handle to initialize
+ * @param sessionkey session key to use
+ * @param iv initialization vector to use
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+static int
+setup_cipher (gcry_cipher_hd_t *handle,
+ const struct GNUNET_CRYPTO_AesSessionKey *
+ sessionkey,
+ const struct GNUNET_CRYPTO_AesInitializationVector *
+ iv)
+{
+ int rc;
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_aes_check_session_key (sessionkey))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_assert (0 ==
+ gcry_cipher_open (handle, GCRY_CIPHER_AES256,
+ GCRY_CIPHER_MODE_CFB, 0));
+ rc = gcry_cipher_setkey (*handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH);
+ GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
+ rc = gcry_cipher_setiv (*handle, iv,
+ sizeof (struct
+ GNUNET_CRYPTO_AesInitializationVector));
+ GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
+ return GNUNET_OK;
}
/**
* Encrypt a block with the public key of another
* host that uses the same cyper.
+ *
* @param block the block to encrypt
* @param len the size of the block
* @param sessionkey the key used to encrypt
@@ -82,28 +124,15 @@ GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len,
iv, void *result)
{
gcry_cipher_hd_t handle;
- int rc;
- if (sessionkey->crc32 !=
- htonl (GNUNET_CRYPTO_crc32_n (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH)))
- {
- GNUNET_break (0);
+ if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv))
return -1;
- }
- GNUNET_assert (0 ==
- gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
- GCRY_CIPHER_MODE_CFB, 0));
- rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH);
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
- rc = gcry_cipher_setiv (handle, iv,
- sizeof (struct
- GNUNET_CRYPTO_AesInitializationVector));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, len, block, len));
gcry_cipher_close (handle);
return len;
}
+
/**
* Decrypt a given block with the sessionkey.
*
@@ -123,30 +152,18 @@ GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size,
iv, void *result)
{
gcry_cipher_hd_t handle;
- int rc;
- if (sessionkey->crc32 !=
- htonl (GNUNET_CRYPTO_crc32_n (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH)))
- {
- GNUNET_break (0);
+ if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv))
return -1;
- }
- GNUNET_assert (0 ==
- gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
- GCRY_CIPHER_MODE_CFB, 0));
- rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH);
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
- rc = gcry_cipher_setiv (handle, iv,
- sizeof (struct
- GNUNET_CRYPTO_AesInitializationVector));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size));
gcry_cipher_close (handle);
return size;
}
+
/**
* @brief Derive an IV
+ *
* @param iv initialization vector
* @param skey session key
* @param salt salt for the derivation
@@ -165,8 +182,10 @@ GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
va_end (argp);
}
+
/**
* @brief Derive an IV
+ *
* @param iv initialization vector
* @param skey session key
* @param salt salt for the derivation
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index 63d9654..4d957c0 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -34,6 +34,7 @@
#include "gnunet_common.h"
#include "gnunet_crypto_lib.h"
#include "gnunet_disk_lib.h"
+#include "gnunet_strings_lib.h"
#include <gcrypt.h>
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -55,6 +56,21 @@ GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret)
/**
+ * Compute short (256-bit) hash of a given block.
+ *
+ * @param block the data to GNUNET_CRYPTO_hash, length is given as a second argument
+ * @param size the length of the data to GNUNET_CRYPTO_hash
+ * @param ret pointer to where to write the hashcode
+ */
+void
+GNUNET_CRYPTO_short_hash (const void *block, size_t size,
+ struct GNUNET_CRYPTO_ShortHashCode * ret)
+{
+ gcry_md_hash_buffer (GCRY_MD_SHA256, ret, block, size);
+}
+
+
+/**
* Context used when hashing a file.
*/
struct GNUNET_CRYPTO_FileHashContext
@@ -204,7 +220,7 @@ GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority,
return NULL;
}
fhc->bsize = blocksize;
- if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO))
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO, GNUNET_YES))
{
GNUNET_free (fhc->filename);
GNUNET_free (fhc);
@@ -241,25 +257,8 @@ GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc)
}
-
/* ***************** binary-ASCII encoding *************** */
-/**
- * Get the numeric value corresponding to a character.
- *
- * @param a a character
- * @return corresponding numeric value
- */
-static unsigned int
-getValue__ (unsigned char a)
-{
- if ((a >= '0') && (a <= '9'))
- return a - '0';
- if ((a >= 'A') && (a <= 'V'))
- return (a - 'A' + 10);
- return -1;
-}
-
/**
* Convert GNUNET_CRYPTO_hash to ASCII encoding. The ASCII encoding is rather
@@ -276,88 +275,37 @@ void
GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
struct GNUNET_CRYPTO_HashAsciiEncoded *result)
{
- /**
- * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters)
- */
- static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
- unsigned int wpos;
- unsigned int rpos;
- unsigned int bits;
- unsigned int vbit;
-
- GNUNET_assert (block != NULL);
- GNUNET_assert (result != NULL);
- vbit = 0;
- wpos = 0;
- rpos = 0;
- bits = 0;
- while ((rpos < sizeof (GNUNET_HashCode)) || (vbit > 0))
- {
- if ((rpos < sizeof (GNUNET_HashCode)) && (vbit < 5))
- {
- bits = (bits << 8) | ((unsigned char *) block)[rpos++]; /* eat 8 more bits */
- vbit += 8;
- }
- if (vbit < 5)
- {
- bits <<= (5 - vbit); /* zero-padding */
- GNUNET_assert (vbit == 2); /* padding by 3: 512+3 mod 5 == 0 */
- vbit = 5;
- }
- GNUNET_assert (wpos < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
- result->encoding[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
- vbit -= 5;
- }
- GNUNET_assert (wpos == sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
- GNUNET_assert (vbit == 0);
- result->encoding[wpos] = '\0';
+ char *np;
+
+ np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block,
+ sizeof (struct GNUNET_HashCode),
+ (char*) result,
+ sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
+ GNUNET_assert (NULL != np);
+ *np = '\0';
}
/**
- * Convert ASCII encoding back to GNUNET_CRYPTO_hash
+ * Convert ASCII encoding back to hash code.
*
* @param enc the encoding
* @param enclen number of characters in 'enc' (without 0-terminator, which can be missing)
- * @param result where to store the GNUNET_CRYPTO_hash code
+ * @param result where to store the hash code
* @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
*/
int
GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen,
GNUNET_HashCode * result)
{
- unsigned int rpos;
- unsigned int wpos;
- unsigned int bits;
- unsigned int vbit;
- int ret;
+ char upper_enc[enclen];
+ char* up_ptr = upper_enc;
- if (enclen != sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1)
- return GNUNET_SYSERR;
+ GNUNET_STRINGS_utf8_toupper(enc, &up_ptr);
- vbit = 2; /* padding! */
- wpos = sizeof (GNUNET_HashCode);
- rpos = sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1;
- bits = (ret = getValue__ (enc[--rpos])) >> 3;
- if (-1 == ret)
- return GNUNET_SYSERR;
- while (wpos > 0)
- {
- GNUNET_assert (rpos > 0);
- bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
- if (-1 == ret)
- return GNUNET_SYSERR;
- vbit += 5;
- if (vbit >= 8)
- {
- ((unsigned char *) result)[--wpos] = (unsigned char) bits;
- bits >>= 8;
- vbit -= 8;
- }
- }
- GNUNET_assert (rpos == 0);
- GNUNET_assert (vbit == 0);
- return GNUNET_OK;
+ return GNUNET_STRINGS_string_to_data (upper_enc, enclen,
+ (unsigned char*) result,
+ sizeof (struct GNUNET_HashCode));
}
@@ -644,4 +592,119 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
}
+
+/**
+ * Double short (256-bit) hash to create a long hash.
+ *
+ * @param sh short hash to double
+ * @param dh where to store the (doubled) long hash (not really a hash)
+ */
+void
+GNUNET_CRYPTO_short_hash_double (const struct GNUNET_CRYPTO_ShortHashCode *sh,
+ struct GNUNET_HashCode *dh)
+{
+ char *ptr;
+
+ ptr = (char*) dh;
+ memcpy (ptr, sh, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ memcpy (&ptr[sizeof (struct GNUNET_CRYPTO_ShortHashCode)], sh, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+}
+
+
+/**
+ * Truncate doubled short hash back to a short hash.
+ *
+ * @param dh doubled short hash to reduce again
+ * @param sh where to store the short hash
+ * @return GNUNET_OK on success, GNUNET_SYSERR if this was not a
+ * doubled short hash
+ */
+int
+GNUNET_CRYPTO_short_hash_from_truncation (const struct GNUNET_HashCode *dh,
+ struct GNUNET_CRYPTO_ShortHashCode *sh)
+{
+ const struct GNUNET_CRYPTO_ShortHashCode *s;
+
+ s = (const struct GNUNET_CRYPTO_ShortHashCode *) dh;
+ if (0 != memcmp (&s[0],
+ &s[1],
+ sizeof (struct GNUNET_CRYPTO_ShortHashCode)))
+ return GNUNET_SYSERR;
+ *sh = *s;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash'
+ *
+ * @param enc the encoding
+ * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing)
+ * @param result where to store the GNUNET_CRYPTO_hash code
+ * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
+ */
+int
+GNUNET_CRYPTO_short_hash_from_string2 (const char *enc, size_t enclen,
+ struct GNUNET_CRYPTO_ShortHashCode * result)
+{
+
+ char upper_enc[enclen];
+ char* up_ptr = upper_enc;
+
+ GNUNET_STRINGS_utf8_toupper(enc, &up_ptr);
+ return GNUNET_STRINGS_string_to_data (upper_enc, enclen,
+ (unsigned char*) result,
+ sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+}
+
+
+/**
+ * Convert short hash to ASCII encoding.
+ *
+ * @param block the hash code
+ * @param result where to store the encoding (struct GNUNET_CRYPTO_ShortHashAsciiEncoded can be
+ * safely cast to char*, a '\\0' termination is set).
+ */
+void
+GNUNET_CRYPTO_short_hash_to_enc (const struct GNUNET_CRYPTO_ShortHashCode * block,
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded *result)
+{
+ char *np;
+
+ np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block,
+ sizeof (struct GNUNET_CRYPTO_ShortHashCode),
+ (char*) result,
+ sizeof (struct GNUNET_CRYPTO_ShortHashAsciiEncoded) - 1);
+ GNUNET_assert (NULL != np);
+ *np = '\0';
+}
+
+/**
+ * Compare function for ShortHashCodes, producing a total ordering
+ * of all hashcodes.
+ *
+ * @param h1 some hash code
+ * @param h2 some hash code
+ * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2.
+ */
+int
+GNUNET_CRYPTO_short_hash_cmp (const struct GNUNET_CRYPTO_ShortHashCode * h1,
+ const struct GNUNET_CRYPTO_ShortHashCode * h2)
+{
+ unsigned int *i1;
+ unsigned int *i2;
+ int i;
+
+ i1 = (unsigned int *) h1;
+ i2 = (unsigned int *) h2;
+ for (i = (sizeof (struct GNUNET_CRYPTO_ShortHashCode) / sizeof (unsigned int)) - 1; i >= 0; i--)
+ {
+ if (i1[i] > i2[i])
+ return 1;
+ if (i1[i] < i2[i])
+ return -1;
+ }
+ return 0;
+}
+
/* end of crypto_hash.c */
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c
index 40bfa67..c2b9677 100644
--- a/src/util/crypto_hkdf.c
+++ b/src/util/crypto_hkdf.c
@@ -49,6 +49,7 @@
#define DEBUG_HKDF 0
+
#if GNUNET_BUILD
#include "platform.h"
#include "gnunet_crypto_lib.h"
diff --git a/src/util/crypto_ksk.c b/src/util/crypto_ksk.c
index 0f5a295..274457b 100644
--- a/src/util/crypto_ksk.c
+++ b/src/util/crypto_ksk.c
@@ -557,202 +557,65 @@ makeKblockKeyInternal (const GNUNET_HashCode * hc)
/**
- * Decode the internal format into the format used
- * by libgcrypt.
+ * Entry in the KSK cache.
*/
-static struct GNUNET_CRYPTO_RsaPrivateKey *
-ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
-{
- struct GNUNET_CRYPTO_RsaPrivateKey *ret;
- gcry_sexp_t res;
- gcry_mpi_t n, e, d, p, q, u;
- int rc;
- size_t size;
- int pos;
-
- pos = 0;
- size = ntohs (encoding->sizen);
- rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizen);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- return NULL;
- }
- size = ntohs (encoding->sizee);
- rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizee);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- return NULL;
- }
- size = ntohs (encoding->sized);
- rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sized);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- return NULL;
- }
- /* swap p and q! */
- size = ntohs (encoding->sizep);
- if (size > 0)
- {
- rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizep);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- return NULL;
- }
- }
- else
- q = NULL;
- size = ntohs (encoding->sizeq);
- if (size > 0)
- {
- rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizeq);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (q != NULL)
- gcry_mpi_release (q);
- return NULL;
- }
- }
- else
- p = NULL;
- pos += ntohs (encoding->sizedmp1);
- pos += ntohs (encoding->sizedmq1);
- size =
- ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
- pos;
- if (size > 0)
- {
- rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (p != NULL)
- gcry_mpi_release (p);
- if (q != NULL)
- gcry_mpi_release (q);
- return NULL;
- }
- }
- else
- u = NULL;
-
- if ((p != NULL) && (q != NULL) && (u != NULL))
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
- n, e, d, p, q, u);
- }
- else
- {
- if ((p != NULL) && (q != NULL))
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
- n, e, d, p, q);
- }
- else
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
- }
- }
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (p != NULL)
- gcry_mpi_release (p);
- if (q != NULL)
- gcry_mpi_release (q);
- if (u != NULL)
- gcry_mpi_release (u);
-
- if (rc)
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
-#if EXTRA_CHECKS
- if (gcry_pk_testkey (res))
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
- return NULL;
- }
-#endif
- ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
- ret->sexp = res;
- return ret;
-}
-
-
struct KBlockKeyCacheLine
{
+ /**
+ * Hash from which the key was generated.
+ */
GNUNET_HashCode hc;
+
+ /**
+ * The encoded key.
+ */
struct KskRsaPrivateKeyBinaryEncoded *pke;
};
+
+/**
+ * Cached KSK keys so that we don't have to recompute them
+ * all the time.
+ */
static struct KBlockKeyCacheLine **cache;
+
+/**
+ * Size of the 'cache' array.
+ */
static unsigned int cacheSize;
+
/**
* Deterministically (!) create a hostkey using only the
* given HashCode as input to the PRNG.
+ *
+ * @param hc hash code to generate the key from
+ * @return corresponding private key; must not be freed!
*/
struct GNUNET_CRYPTO_RsaPrivateKey *
GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
{
- struct GNUNET_CRYPTO_RsaPrivateKey *ret;
struct KBlockKeyCacheLine *line;
unsigned int i;
- for (i = 0; i < cacheSize; i++)
- {
+ for (i = 0; i < cacheSize; i++)
if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
- {
- ret = ksk_decode_key (cache[i]->pke);
- return ret;
- }
- }
-
+ return GNUNET_CRYPTO_rsa_decode_key ((const char*) cache[i]->pke,
+ ntohs (cache[i]->pke->len));
line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
line->hc = *hc;
line->pke = makeKblockKeyInternal (hc);
GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
cache[cacheSize - 1] = line;
- return ksk_decode_key (line->pke);
+ return GNUNET_CRYPTO_rsa_decode_key ((const char*) line->pke,
+ ntohs (line->pke->len));
}
+/**
+ * Destructor that frees the KSK cache.
+ */
void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
{
unsigned int i;
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index 25226a3..35d3c41 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -256,7 +256,7 @@ entropy_generator (void *cls, const char *what, int printchar, int current,
if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill");
GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
- GNUNET_OS_process_close (genproc);
+ GNUNET_OS_process_destroy (genproc);
genproc = NULL;
}
return;
@@ -274,7 +274,7 @@ entropy_generator (void *cls, const char *what, int printchar, int current,
if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill");
GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
- GNUNET_OS_process_close (genproc);
+ GNUNET_OS_process_destroy (genproc);
genproc = NULL;
}
LOG (GNUNET_ERROR_TYPE_INFO, _("Starting `%s' process to generate entropy\n"),
@@ -293,7 +293,7 @@ killfind ()
if (genproc != NULL)
{
GNUNET_OS_process_kill (genproc, SIGKILL);
- GNUNET_OS_process_close (genproc);
+ GNUNET_OS_process_destroy (genproc);
genproc = NULL;
}
}
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index 418fe83..0106f43 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -36,6 +36,7 @@
#include "gnunet_common.h"
#include "gnunet_crypto_lib.h"
#include "gnunet_disk_lib.h"
+#include "gnunet_strings_lib.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -53,32 +54,6 @@ struct GNUNET_CRYPTO_RsaPrivateKey
};
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * GNUnet mandates a certain format for the encoding
- * of private RSA key information that is provided
- * by the RSA implementations. This format is used
- * to serialize a private RSA key (typically when
- * writing it to disk).
- */
-struct RsaPrivateKeyBinaryEncoded
-{
- /**
- * Total size of the structure, in bytes, in big-endian!
- */
- uint16_t len GNUNET_PACKED;
- uint16_t sizen GNUNET_PACKED; /* in big-endian! */
- uint16_t sizee GNUNET_PACKED; /* in big-endian! */
- uint16_t sized GNUNET_PACKED; /* in big-endian! */
- uint16_t sizep GNUNET_PACKED; /* in big-endian! */
- uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
- uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
- uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
- /* followed by the actual values */
-};
-GNUNET_NETWORK_STRUCT_END
-
#define HOSTKEY_LEN 2048
#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
@@ -107,7 +82,9 @@ adjust (unsigned char *buf, size_t size, size_t target)
}
/**
- * This HostKey implementation uses RSA.
+ * Create a new private key. Caller must free return value.
+ *
+ * @return fresh private key
*/
struct GNUNET_CRYPTO_RsaPrivateKey *
GNUNET_CRYPTO_rsa_key_create ()
@@ -132,6 +109,7 @@ GNUNET_CRYPTO_rsa_key_create ()
/**
* Free memory occupied by hostkey
+ * @param hostkey pointer to the memory to free
*/
void
GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
@@ -238,6 +216,70 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
/**
+ * Convert a public key to a string.
+ *
+ * @param pub key to convert
+ * @return string representing 'pub'
+ */
+char *
+GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
+{
+ char *pubkeybuf;
+ size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8;
+ char *end;
+
+ if (keylen % 5 > 0)
+ keylen += 5 - keylen % 5;
+ keylen /= 5;
+ pubkeybuf = GNUNET_malloc (keylen + 1);
+ end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
+ sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ pubkeybuf,
+ keylen);
+ if (NULL == end)
+ {
+ GNUNET_free (pubkeybuf);
+ return NULL;
+ }
+ *end = '\0';
+ return pubkeybuf;
+}
+
+
+/**
+ * Convert a string representing a public key to a public key.
+ *
+ * @param enc encoded public key
+ * @param enclen number of bytes in enc (without 0-terminator)
+ * @param pub where to store the public key
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc,
+ size_t enclen,
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
+{
+ size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8;
+
+ if (keylen % 5 > 0)
+ keylen += 5 - keylen % 5;
+ keylen /= 5;
+ if (enclen != keylen)
+ return GNUNET_SYSERR;
+
+ if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
+ (unsigned char*) pub,
+ sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ return GNUNET_SYSERR;
+ if ( (ntohs (pub->len) != sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) ||
+ (ntohs (pub->padding) != 0) ||
+ (ntohs (pub->sizen) != GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH) )
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+}
+
+
+/**
* Internal: publicKey => RSA-Key.
*
* Note that the return type is not actually a private
@@ -301,10 +343,10 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
* @returns encoding of the private key.
* The first 4 bytes give the size of the array, as usual.
*/
-static struct RsaPrivateKeyBinaryEncoded *
-rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
+struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *
+GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
{
- struct RsaPrivateKeyBinaryEncoded *retval;
+ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *retval;
gcry_mpi_t pkv[6];
void *pbu[6];
size_t sizes[6];
@@ -333,7 +375,7 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned");
GNUNET_assert (0 == rc);
- size = sizeof (struct RsaPrivateKeyBinaryEncoded);
+ size = sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded);
for (i = 0; i < 6; i++)
{
if (pkv[i] != NULL)
@@ -383,6 +425,7 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
return retval;
}
+
/**
* Decode the private key from the file-format back
* to the "normal", internal format.
@@ -394,8 +437,8 @@ struct GNUNET_CRYPTO_RsaPrivateKey *
GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
{
struct GNUNET_CRYPTO_RsaPrivateKey *ret;
- const struct RsaPrivateKeyBinaryEncoded *encoding =
- (const struct RsaPrivateKeyBinaryEncoded *) buf;
+ const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *encoding =
+ (const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *) buf;
gcry_sexp_t res;
gcry_mpi_t n, e, d, p, q, u;
int rc;
@@ -483,7 +526,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
pos += ntohs (encoding->sizedmp1);
pos += ntohs (encoding->sizedmq1);
size =
- ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos;
+ ntohs (encoding->len) - sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded) - pos;
if (size > 0)
{
rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
@@ -567,7 +610,7 @@ struct GNUNET_CRYPTO_RsaPrivateKey *
GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
{
struct GNUNET_CRYPTO_RsaPrivateKey *ret;
- struct RsaPrivateKeyBinaryEncoded *enc;
+ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc;
uint16_t len;
struct GNUNET_DISK_FileHandle *fd;
unsigned int cnt;
@@ -607,7 +650,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
while (GNUNET_YES !=
GNUNET_DISK_file_lock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded),
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
GNUNET_YES))
{
sleep (1);
@@ -623,7 +666,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
_("Creating a new private key. This may take a while.\n"));
ret = GNUNET_CRYPTO_rsa_key_create ();
GNUNET_assert (ret != NULL);
- enc = rsa_encode_key (ret);
+ enc = GNUNET_CRYPTO_rsa_encode_key (ret);
GNUNET_assert (enc != NULL);
GNUNET_assert (ntohs (enc->len) ==
GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
@@ -632,7 +675,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
GNUNET_DISK_file_sync (fd);
if (GNUNET_YES !=
GNUNET_DISK_file_unlock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded)))
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
@@ -655,7 +698,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
{
if (GNUNET_YES !=
GNUNET_DISK_file_lock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded),
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
GNUNET_NO))
{
if (0 == ++cnt % 60)
@@ -677,21 +720,21 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
if (GNUNET_YES !=
GNUNET_DISK_file_unlock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded)))
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
return NULL;
}
- if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES))
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
fs = 0;
- if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded))
+ if (fs < sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))
{
/* maybe we got the read lock before the hostkey generating
* process had a chance to get the write lock; give it up! */
if (GNUNET_YES !=
GNUNET_DISK_file_unlock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded)))
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
if (0 == ++cnt % 10)
{
@@ -699,7 +742,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
_
("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"),
filename, (unsigned int) fs,
- (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded));
+ (unsigned int) sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded));
LOG (GNUNET_ERROR_TYPE_ERROR,
_
("This may be ok if someone is currently generating a hostkey.\n"));
@@ -727,7 +770,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
GNUNET_free (enc);
if (GNUNET_YES !=
GNUNET_DISK_file_unlock (fd, 0,
- sizeof (struct RsaPrivateKeyBinaryEncoded)))
+ sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
if (ret != NULL)
@@ -743,6 +786,35 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
/**
+ * Setup a hostkey file for a peer given the name of the
+ * configuration file (!). This function is used so that
+ * at a later point code can be certain that reading a
+ * hostkey is fast (for example in time-dependent testcases).
+ *
+ * @param cfg_name name of the configuration file to use
+ */
+void
+GNUNET_CRYPTO_setup_hostkey (const char *cfg_name)
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+ char *fn;
+
+ cfg = GNUNET_CONFIGURATION_create ();
+ (void) GNUNET_CONFIGURATION_load (cfg, cfg_name);
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", &fn))
+ {
+ pk = GNUNET_CRYPTO_rsa_key_create_from_file (fn);
+ if (NULL != pk)
+ GNUNET_CRYPTO_rsa_key_free (pk);
+ GNUNET_free (fn);
+ }
+ GNUNET_CONFIGURATION_destroy (cfg);
+}
+
+
+/**
* Encrypt a block with the public key of another host that uses the
* same cipher.
*
@@ -793,6 +865,7 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size,
return GNUNET_OK;
}
+
/**
* Decrypt a given block with the hostkey.
*
diff --git a/src/util/disk.c b/src/util/disk.c
index b6b458f..cba0d44 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -40,10 +40,6 @@
#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
-#define DEBUG_NPIPE GNUNET_EXTRA_LOGGING
-
-#define DEBUG_PIPE GNUNET_EXTRA_LOGGING
-
/**
* Block size for IO for copying files.
*/
@@ -112,9 +108,22 @@ struct GetFileSizeData
* GNUNET_YES if symbolic links should be included.
*/
int include_sym_links;
+
+ /**
+ * GNUNET_YES if mode is file-only (return total == -1 for directories).
+ */
+ int single_file_mode;
};
+#ifndef MINGW
+/**
+ * Translate GNUnet-internal permission bitmap to UNIX file
+ * access permission bitmap.
+ *
+ * @param perm file permissions, GNUnet style
+ * @return file permissions, UNIX style
+ */
static int
translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm)
{
@@ -142,6 +151,7 @@ translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm)
return mode;
}
+#endif
/**
@@ -166,16 +176,21 @@ getSizeRec (void *cls, const char *fn)
#ifdef HAVE_STAT64
if (0 != STAT64 (fn, &buf))
{
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat64", fn);
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat64", fn);
return GNUNET_SYSERR;
}
#else
if (0 != STAT (fn, &buf))
{
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fn);
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", fn);
return GNUNET_SYSERR;
}
#endif
+ if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES))
+ {
+ errno = EISDIR;
+ return GNUNET_SYSERR;
+ }
if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
gfsd->total += buf.st_size;
if ((S_ISDIR (buf.st_mode)) && (0 == ACCESS (fn, X_OK)) &&
@@ -255,7 +270,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset,
}
#ifdef MINGW
- LARGE_INTEGER li, new_pos;
+ LARGE_INTEGER li;
+ LARGE_INTEGER new_pos;
BOOL b;
static DWORD t[] = {[GNUNET_DISK_SEEK_SET] = FILE_BEGIN,
@@ -290,11 +306,13 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset,
* of all sizes of files in the directory)
* @param includeSymLinks should symbolic links be
* included?
+ * @param singleFileMode GNUNET_YES to only get size of one file
+ * and return GNUNET_SYSERR for directories.
* @return GNUNET_SYSERR on error, GNUNET_OK on success
*/
int
GNUNET_DISK_file_size (const char *filename, uint64_t * size,
- int includeSymLinks)
+ int includeSymLinks, int singleFileMode)
{
struct GetFileSizeData gfsd;
int ret;
@@ -302,6 +320,7 @@ GNUNET_DISK_file_size (const char *filename, uint64_t * size,
GNUNET_assert (size != NULL);
gfsd.total = 0;
gfsd.include_sym_links = includeSymLinks;
+ gfsd.single_file_mode = singleFileMode;
ret = getSizeRec (&gfsd, filename);
*size = gfsd.total;
return ret;
@@ -719,27 +738,18 @@ GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result,
}
else
{
-#if DEBUG_PIPE
- LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to read\n");
-#endif
if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead))
{
if (GetLastError () != ERROR_IO_PENDING)
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ());
-#endif
SetErrnoFromWinError (GetLastError ());
return GNUNET_SYSERR;
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
-#endif
GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE);
}
-#if DEBUG_PIPE
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead);
-#endif
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes from pipe\n", bytesRead);
}
return bytesRead;
#else
@@ -781,33 +791,24 @@ GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle * h,
}
else
{
-#if DEBUG_PIPE
- LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe, trying to read\n");
-#endif
if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead))
{
if (GetLastError () != ERROR_IO_PENDING)
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ());
-#endif
SetErrnoFromWinError (GetLastError ());
return GNUNET_SYSERR;
}
else
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"ReadFile() queued a read, cancelling\n");
-#endif
CancelIo (h->h);
errno = EAGAIN;
return GNUNET_SYSERR;
}
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead);
-#endif
}
return bytesRead;
#else
@@ -880,31 +881,23 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
}
else
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write %u bytes\n", n);
-#endif
if (!WriteFile (h->h, buffer, n, &bytesWritten, h->oOverlapWrite))
{
if (GetLastError () != ERROR_IO_PENDING)
{
SetErrnoFromWinError (GetLastError ());
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n",
GetLastError ());
-#endif
return GNUNET_SYSERR;
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
-#endif
if (!GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE))
{
SetErrnoFromWinError (GetLastError ());
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Error getting overlapped result while writing to pipe: %u\n",
GetLastError ());
-#endif
return GNUNET_SYSERR;
}
}
@@ -913,35 +906,27 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
DWORD ovr;
if (!GetOverlappedResult (h->h, h->oOverlapWrite, &ovr, TRUE))
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Error getting control overlapped result while writing to pipe: %u\n",
GetLastError ());
-#endif
}
else
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Wrote %u bytes (ovr says %u), picking the greatest\n",
bytesWritten, ovr);
-#endif
}
}
if (bytesWritten == 0)
{
if (n > 0)
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes, returning -1 with EAGAIN\n", bytesWritten);
-#endif
errno = EAGAIN;
return GNUNET_SYSERR;
}
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten);
-#endif
}
return bytesWritten;
#else
@@ -970,37 +955,27 @@ GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle * h,
#ifdef MINGW
DWORD bytesWritten;
/* We do a non-overlapped write, which is as blocking as it gets */
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing %u bytes\n", n);
-#endif
if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL))
{
SetErrnoFromWinError (GetLastError ());
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n",
GetLastError ());
-#endif
return GNUNET_SYSERR;
}
if (bytesWritten == 0 && n > 0)
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for pipe to clean\n");
-#endif
WaitForSingleObject (h->h, INFINITE);
if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL))
{
SetErrnoFromWinError (GetLastError ());
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n",
GetLastError ());
-#endif
return GNUNET_SYSERR;
}
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten);
-#endif
return bytesWritten;
#else
int flags;
@@ -1350,7 +1325,7 @@ GNUNET_DISK_file_copy (const char *src, const char *dst)
struct GNUNET_DISK_FileHandle *in;
struct GNUNET_DISK_FileHandle *out;
- if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES))
+ if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES, GNUNET_YES))
return GNUNET_SYSERR;
pos = 0;
in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ,
@@ -2008,10 +1983,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld",
getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id));
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe: name = %s, size = %lu\n",
pipename, psize);
-#endif
/* Use CreateNamedPipe instead of CreatePipe, because the latter
* returns a write handle that does not permit FILE_READ_ATTRIBUTES
* access, on versions of win32 earlier than WinXP SP2.
@@ -2028,9 +2001,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
if (read_pipe != INVALID_HANDLE_VALUE)
{
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe);
-#endif
break;
}
@@ -2041,33 +2012,24 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
case ERROR_PIPE_BUSY:
/* The pipe is already open with compatible parameters.
* Pick a new name and retry. */
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n");
-#endif
continue;
case ERROR_ACCESS_DENIED:
/* The pipe is already open with incompatible parameters.
* Pick a new name and retry. */
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n");
-#endif
continue;
case ERROR_CALL_NOT_IMPLEMENTED:
/* We are on an older Win9x platform without named pipes.
* Return an anonymous pipe as the best approximation. */
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"CreateNamedPipe not implemented, resorting to "
"CreatePipe: size = %lu\n", psize);
-#endif
if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
{
-#if DEBUG_PIPE
- LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n",
- *read_pipe_ptr);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p, write handle = %p\n",
+ *read_pipe_ptr,
*write_pipe_ptr);
-#endif
return GNUNET_OK;
}
err = GetLastError ();
@@ -2079,9 +2041,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
}
/* NOTREACHED */
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename);
-#endif
/* Open the named pipe for writing.
* Be sure to permit FILE_READ_ATTRIBUTES access. */
@@ -2094,15 +2054,11 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
/* Failure. */
DWORD err = GetLastError ();
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err);
-#endif
CloseHandle (read_pipe);
return err;
}
-#if DEBUG_PIPE
LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe);
-#endif
/* Success. */
*read_pipe_ptr = read_pipe;
*write_pipe_ptr = write_pipe;
diff --git a/src/util/getopt.c b/src/util/getopt.c
index 1699498..572e534 100644
--- a/src/util/getopt.c
+++ b/src/util/getopt.c
@@ -202,9 +202,8 @@ char *
getenv ();
static char *
-my_index (str, chr)
- const char *str;
- int chr;
+my_index (const char *str,
+ int chr)
{
while (*str)
{
@@ -294,8 +293,7 @@ exchange (char **);
#endif
static void
-exchange (argv)
- char **argv;
+exchange (char **argv)
{
int bottom = first_nonopt;
int middle = last_nonopt;
@@ -381,10 +379,9 @@ static const char *
_getopt_initialize (int, char *const *, const char *);
#endif
static const char *
-_getopt_initialize (argc, argv, optstring)
- int argc;
- char *const *argv;
- const char *optstring;
+_getopt_initialize (int argc,
+ char *const *argv,
+ const char *optstring)
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
* is the program name); the sequence of previously skipped
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c
index 8fb3673..a31080f 100644
--- a/src/util/getopt_helpers.c
+++ b/src/util/getopt_helpers.c
@@ -79,9 +79,12 @@ GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext
const char *trans;
const struct GNUNET_GETOPT_CommandLineOption *opt;
- printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
- printf (_
- ("Arguments mandatory for long options are also mandatory for short options.\n"));
+ if (NULL != about)
+ {
+ printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
+ printf (_
+ ("Arguments mandatory for long options are also mandatory for short options.\n"));
+ }
i = 0;
opt = ctx->allOptions;
while (opt[i].description != NULL)
diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c
new file mode 100644
index 0000000..f3cd83a
--- /dev/null
+++ b/src/util/gnunet-rsa.c
@@ -0,0 +1,128 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/gnunet-rsa.c
+ * @brief tool to manipulate RSA key files
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+
+
+/**
+ * Flag for printing public key.
+ */
+static int print_public_key;
+
+/**
+ * Flag for printing hash of public key.
+ */
+static int print_peer_identity;
+
+/**
+ * Flag for printing short hash of public key.
+ */
+static int print_short_identity;
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ struct GNUNET_PeerIdentity pid;
+
+ if (NULL == args[0])
+ {
+ fprintf (stderr, _("No hostkey file specified on command line\n"));
+ return;
+ }
+ pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]);
+ if (print_public_key)
+ {
+ char *s;
+
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
+ s = GNUNET_CRYPTO_rsa_public_key_to_string (&pub);
+ fprintf (stdout, "%s\n", s);
+ GNUNET_free (s);
+ }
+ if (print_peer_identity)
+ {
+ struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
+ GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
+ GNUNET_CRYPTO_hash_to_enc (&pid.hashPubKey, &enc);
+ fprintf (stdout, "%s\n", enc.encoding);
+ }
+ if (print_short_identity)
+ {
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
+ struct GNUNET_CRYPTO_ShortHashCode sh;
+
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
+ GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &sh);
+ GNUNET_CRYPTO_short_hash_to_enc (&sh, &enc);
+ fprintf (stdout, "%s\n", enc.short_encoding);
+ }
+ GNUNET_CRYPTO_rsa_key_free (pk);
+}
+
+
+/**
+ * The main function to obtain statistics in GNUnet.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc, char *const *argv)
+{
+ static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ { 'p', "print-public-key", NULL,
+ gettext_noop ("print the public key in ASCII format"),
+ 0, &GNUNET_GETOPT_set_one, &print_public_key },
+ { 'P', "print-peer-identity", NULL,
+ gettext_noop ("print the hash of the public key in ASCII format"),
+ 0, &GNUNET_GETOPT_set_one, &print_peer_identity },
+ { 's', "print-short-identity", NULL,
+ gettext_noop ("print the short hash of the public key in ASCII format"),
+ 0, &GNUNET_GETOPT_set_one, &print_short_identity },
+ GNUNET_GETOPT_OPTION_END
+ };
+ return (GNUNET_OK ==
+ GNUNET_PROGRAM_run (argc, argv, "gnunet-rsa [OPTIONS] keyfile",
+ gettext_noop ("Manipulate GNUnet private RSA key files"),
+ options, &run, NULL)) ? 0 : 1;
+}
+
+/* end of gnunet-rsa.c */
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index f20666a..97eba6d 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -490,10 +490,8 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver asked to look up `%s'.\n"),
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Resolver asked to look up `%s'.\n",
hostname);
-#endif
get_ip_from_hostname (client, hostname, af);
return;
}
@@ -521,15 +519,13 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
-#if DEBUG_RESOLVER
{
char buf[INET6_ADDRSTRLEN];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver asked to look up IP address `%s'.\n"),
+ "Resolver asked to look up IP address `%s'.\n",
inet_ntop (af, ip, buf, sizeof (buf)));
}
-#endif
get_ip_as_string (client, af, ip);
}
diff --git a/src/util/helper.c b/src/util/helper.c
index 43ec23a..6a84ff3 100644
--- a/src/util/helper.c
+++ b/src/util/helper.c
@@ -31,24 +31,29 @@
/**
* Entry in the queue of messages we need to transmit to the helper.
*/
-struct HelperMessageQueueEntry
+struct GNUNET_HELPER_SendHandle
{
/**
* This is an entry in a DLL.
*/
- struct HelperMessageQueueEntry *next;
+ struct GNUNET_HELPER_SendHandle *next;
/**
* This is an entry in a DLL.
*/
- struct HelperMessageQueueEntry *prev;
+ struct GNUNET_HELPER_SendHandle *prev;
/**
* Message to transmit (allocated at the end of this struct)
*/
const struct GNUNET_MessageHeader *msg;
-
+
+ /**
+ * The handle to a helper process.
+ */
+ struct GNUNET_HELPER_Handle *h;
+
/**
* Function to call upon completion.
*/
@@ -106,12 +111,12 @@ struct GNUNET_HELPER_Handle
/**
* First message queued for transmission to helper.
*/
- struct HelperMessageQueueEntry *mq_head;
+ struct GNUNET_HELPER_SendHandle *sh_head;
/**
* Last message queued for transmission to helper.
*/
- struct HelperMessageQueueEntry *mq_tail;
+ struct GNUNET_HELPER_SendHandle *sh_tail;
/**
* Binary to run.
@@ -148,13 +153,13 @@ struct GNUNET_HELPER_Handle
static void
stop_helper (struct GNUNET_HELPER_Handle *h)
{
- struct HelperMessageQueueEntry *qe;
+ struct GNUNET_HELPER_SendHandle *sh;
if (NULL != h->helper_proc)
{
GNUNET_break (0 == GNUNET_OS_process_kill (h->helper_proc, SIGTERM));
GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (h->helper_proc));
- GNUNET_OS_process_close (h->helper_proc);
+ GNUNET_OS_process_destroy (h->helper_proc);
h->helper_proc = NULL;
}
if (GNUNET_SCHEDULER_NO_TASK != h->restart_task)
@@ -184,14 +189,14 @@ stop_helper (struct GNUNET_HELPER_Handle *h)
h->helper_out = NULL;
h->fh_from_helper = NULL;
}
- while (NULL != (qe = h->mq_head))
+ while (NULL != (sh = h->sh_head))
{
- GNUNET_CONTAINER_DLL_remove (h->mq_head,
- h->mq_tail,
- qe);
- if (NULL != qe->cont)
- qe->cont (qe->cont_cls, GNUNET_NO);
- GNUNET_free (qe);
+ GNUNET_CONTAINER_DLL_remove (h->sh_head,
+ h->sh_tail,
+ sh);
+ if (NULL != sh->cont)
+ sh->cont (sh->cont_cls, GNUNET_NO);
+ GNUNET_free (sh);
}
/* purge MST buffer */
(void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO);
@@ -220,7 +225,7 @@ helper_read (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_HELPER_Handle *h = cls;
- char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE];
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE] GNUNET_ALIGN;
ssize_t t;
h->read_task = GNUNET_SCHEDULER_NO_TASK;
@@ -301,6 +306,9 @@ start_helper (struct GNUNET_HELPER_Handle *h)
&restart_task, h);
return;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Starting HELPER process `%s'\n"),
+ h->binary_name);
h->fh_from_helper =
GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ);
h->fh_to_helper =
@@ -380,17 +388,17 @@ GNUNET_HELPER_start (const char *binary_name,
void
GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h)
{
- struct HelperMessageQueueEntry *qe;
+ struct GNUNET_HELPER_SendHandle *sh;
/* signal pending writes that we were stopped */
- while (NULL != (qe = h->mq_head))
+ while (NULL != (sh = h->sh_head))
{
- GNUNET_CONTAINER_DLL_remove (h->mq_head,
- h->mq_tail,
- qe);
- if (NULL != qe->cont)
- qe->cont (qe->cont_cls, GNUNET_SYSERR);
- GNUNET_free (qe);
+ GNUNET_CONTAINER_DLL_remove (h->sh_head,
+ h->sh_tail,
+ sh);
+ if (NULL != sh->cont)
+ sh->cont (sh->cont_cls, GNUNET_SYSERR);
+ GNUNET_free (sh);
}
stop_helper (h);
GNUNET_SERVER_mst_destroy (h->mst);
@@ -409,7 +417,7 @@ helper_write (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_HELPER_Handle *h = cls;
- struct HelperMessageQueueEntry *qe;
+ struct GNUNET_HELPER_SendHandle *sh;
const char *buf;
ssize_t t;
@@ -421,10 +429,10 @@ helper_write (void *cls,
h->fh_to_helper, &helper_write, h);
return;
}
- if (NULL == (qe = h->mq_head))
+ if (NULL == (sh = h->sh_head))
return; /* how did this happen? */
- buf = (const char*) qe->msg;
- t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[qe->wpos], ntohs (qe->msg->size) - qe->wpos);
+ buf = (const char*) sh->msg;
+ t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[sh->wpos], ntohs (sh->msg->size) - sh->wpos);
if (t <= 0)
{
/* On write-error, restart the helper */
@@ -439,17 +447,17 @@ helper_write (void *cls,
&restart_task, h);
return;
}
- qe->wpos += t;
- if (qe->wpos == ntohs (qe->msg->size))
+ sh->wpos += t;
+ if (sh->wpos == ntohs (sh->msg->size))
{
- GNUNET_CONTAINER_DLL_remove (h->mq_head,
- h->mq_tail,
- qe);
- if (NULL != qe->cont)
- qe->cont (qe->cont_cls, GNUNET_YES);
- GNUNET_free (qe);
+ GNUNET_CONTAINER_DLL_remove (h->sh_head,
+ h->sh_tail,
+ sh);
+ if (NULL != sh->cont)
+ sh->cont (sh->cont_cls, GNUNET_YES);
+ GNUNET_free (sh);
}
- if (NULL != h->mq_head)
+ if (NULL != h->sh_head)
h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
h->fh_to_helper,
&helper_write,
@@ -466,40 +474,68 @@ helper_write (void *cls,
* @param cont continuation to run once the message is out (PREREQ_DONE on succees, CANCEL
* if the helper process died, NULL during GNUNET_HELPER_stop).
* @param cont_cls closure for 'cont'
- * @return GNUNET_YES if the message will be sent
- * GNUNET_NO if the message was dropped
+ * @return NULL if the message was dropped,
+ * otherwise handle to cancel *cont* (actual transmission may
+ * not be abortable)
*/
-int
+struct GNUNET_HELPER_SendHandle *
GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
const struct GNUNET_MessageHeader *msg,
int can_drop,
GNUNET_HELPER_Continuation cont,
void *cont_cls)
{
- struct HelperMessageQueueEntry *qe;
+ struct GNUNET_HELPER_SendHandle *sh;
uint16_t mlen;
if (NULL == h->fh_to_helper)
- return GNUNET_NO;
+ return NULL;
if ( (GNUNET_YES == can_drop) &&
- (h->mq_head != NULL) )
- return GNUNET_NO;
+ (NULL != h->sh_head) )
+ return NULL;
mlen = ntohs (msg->size);
- qe = GNUNET_malloc (sizeof (struct HelperMessageQueueEntry) + mlen);
- qe->msg = (const struct GNUNET_MessageHeader*) &qe[1];
- memcpy (&qe[1], msg, mlen);
- qe->cont = cont;
- qe->cont_cls = cont_cls;
- GNUNET_CONTAINER_DLL_insert_tail (h->mq_head,
- h->mq_tail,
- qe);
+ sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen);
+ sh->msg = (const struct GNUNET_MessageHeader*) &sh[1];
+ memcpy (&sh[1], msg, mlen);
+ sh->h = h;
+ sh->cont = cont;
+ sh->cont_cls = cont_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->sh_head,
+ h->sh_tail,
+ sh);
if (GNUNET_SCHEDULER_NO_TASK == h->write_task)
h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
h->fh_to_helper,
&helper_write,
h);
- return GNUNET_YES;
+ return sh;
+}
+
+/**
+ * Cancel a 'send' operation. If possible, transmitting the
+ * message is also aborted, but at least 'cont' won't be
+ * called.
+ *
+ * @param sh operation to cancel
+ */
+void
+GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh)
+{
+ struct GNUNET_HELPER_Handle *h = sh->h;
+
+ sh->cont = NULL;
+ sh->cont_cls = NULL;
+ if (0 == sh->wpos)
+ {
+ GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
+ if (NULL == h->sh_head)
+ {
+ GNUNET_SCHEDULER_cancel (h->write_task);
+ h->write_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_free (sh);
+ }
}
diff --git a/src/util/load.c b/src/util/load.c
index e978a95..146e850 100644
--- a/src/util/load.c
+++ b/src/util/load.c
@@ -26,7 +26,6 @@
#include "platform.h"
#include "gnunet_load_lib.h"
-#define DEBUG_LOAD GNUNET_EXTRA_LOGGING
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
diff --git a/src/util/network.c b/src/util/network.c
index e530ab7..972f938 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -193,6 +193,61 @@ socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
/**
+ * Perform proper canonical initialization for a network handle.
+ * Set it to non-blocking, make it non-inheritable to child
+ * processes, disable SIGPIPE, enable "nodelay" (if non-UNIX
+ * stream socket) and check that it is smaller than FS_SETSIZE.
+ *
+ * @param h socket to initialize
+ * @param af address family of the socket
+ * @param type socket type
+ * @return GNUNET_OK on success, GNUNET_SYSERR if initialization
+ * failed and the handle was destroyed
+ */
+static int
+initialize_network_handle (struct GNUNET_NETWORK_Handle *h,
+ int af, int type)
+{
+ h->af = af;
+ if (h->fd == INVALID_SOCKET)
+ {
+#ifdef MINGW
+ SetErrnoFromWinsockError (WSAGetLastError ());
+#endif
+ GNUNET_free (h);
+ return GNUNET_SYSERR;
+ }
+#ifndef MINGW
+ if (h->fd >= FD_SETSIZE)
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
+ errno = EMFILE;
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != socket_set_inheritable (h))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "socket_set_inheritable");
+#endif
+ if (GNUNET_SYSERR == socket_set_blocking (h, GNUNET_NO))
+ {
+ GNUNET_break (0);
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
+ return GNUNET_SYSERR;
+ }
+#ifdef DARWIN
+ socket_set_nosigpipe (h);
+#endif
+ if ( (type == SOCK_STREAM)
+#ifdef AF_UNIX
+ && (af != AF_UNIX)
+#endif
+ )
+ socket_set_nodelay (h);
+ return GNUNET_OK;
+}
+
+
+/**
* accept a new connection on a socket
*
* @param desc bound socket
@@ -219,49 +274,10 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
}
#endif
ret->fd = accept (desc->fd, address, address_len);
- if (address != NULL)
- ret->af = address->sa_family;
- else
- ret->af = desc->af;
- if (ret->fd == INVALID_SOCKET)
- {
-#ifdef MINGW
- SetErrnoFromWinsockError (WSAGetLastError ());
-#endif
- GNUNET_free (ret);
- return NULL;
- }
-#ifndef MINGW
- if (ret->fd >= FD_SETSIZE)
- {
- GNUNET_break (0 == close (ret->fd));
- GNUNET_free (ret);
- errno = EMFILE;
- return NULL;
- }
-#endif
- if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))
-
- {
-
- /* we might want to treat this one as fatal... */
- GNUNET_break (0);
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));
+ if (GNUNET_OK != initialize_network_handle (ret,
+ (NULL != address) ? address->sa_family : desc->af,
+ SOCK_STREAM))
return NULL;
- }
-
-#ifndef MINGW
- if (GNUNET_OK != socket_set_inheritable (ret))
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
- "socket_set_inheritable");
-#endif
-#ifdef DARWIN
- socket_set_nosigpipe (ret);
-#endif
-#ifdef AF_UNIX
- if (ret->af != AF_UNIX)
-#endif
- socket_set_nodelay (ret);
return ret;
}
@@ -492,15 +508,16 @@ GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle *
error = ioctl (desc->fd, FIONREAD, &pending);
if (error == 0)
+ return (ssize_t) pending;
+ return GNUNET_NO;
#else
u_long pending;
error = ioctlsocket (desc->fd, FIONREAD, &pending);
if (error != SOCKET_ERROR)
+ return (ssize_t) pending;
+ return GNUNET_NO;
#endif
- return pending;
- else
- return GNUNET_NO;
}
@@ -677,49 +694,10 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
struct GNUNET_NETWORK_Handle *ret;
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
- ret->af = domain;
ret->fd = socket (domain, type, protocol);
- if (INVALID_SOCKET == ret->fd)
- {
-#ifdef MINGW
- SetErrnoFromWinsockError (WSAGetLastError ());
-#endif
- GNUNET_free (ret);
- return NULL;
- }
-
-#ifndef MINGW
- if (ret->fd >= FD_SETSIZE)
- {
- GNUNET_break (0 == close (ret->fd));
- GNUNET_free (ret);
- errno = EMFILE;
- return NULL;
- }
-
-#endif
- if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))
- {
- /* we might want to treat this one as fatal... */
- GNUNET_break (0);
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));
+ if (GNUNET_OK !=
+ initialize_network_handle (ret, domain, type))
return NULL;
- }
-
-#ifndef MINGW
- if (GNUNET_OK != socket_set_inheritable (ret))
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
- "socket_set_inheritable");
-#endif
-#ifdef DARWIN
- socket_set_nosigpipe (ret);
-#endif
- if ((type == SOCK_STREAM)
-#ifdef AF_UNIX
- && (domain != AF_UNIX)
-#endif
- )
- socket_set_nodelay (ret);
return ret;
}
@@ -887,8 +865,30 @@ GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc)
return desc->fd;
}
+/**
+ * Return sockaddr for this network handle
+ *
+ * @param desc wrapper to process
+ * @return sockaddr
+ */
+struct sockaddr*
+GNUNET_NETWORK_get_addr (struct GNUNET_NETWORK_Handle *desc)
+{
+ return desc->addr;
+}
/**
+ * Return sockaddr length for this network handle
+ *
+ * @param desc wrapper to process
+ * @return socklen_t for sockaddr
+ */
+socklen_t
+GNUNET_NETWORK_get_addrlen (struct GNUNET_NETWORK_Handle *desc)
+{
+ return desc->addrlen;
+}
+/**
* Copy a native fd set
*
* @param to destination
@@ -1047,9 +1047,6 @@ GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
if (GNUNET_CONTAINER_slist_contains
(fds2->handles, h, sizeof (struct GNUNET_DISK_FileHandle)))
{
-#if DEBUG_NETWORK
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Match!\n");
-#endif
return GNUNET_YES;
}
GNUNET_CONTAINER_slist_next (&it);
@@ -1105,7 +1102,6 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
const struct GNUNET_TIME_Relative timeout)
{
int nfds = 0;
-
#ifdef MINGW
int handles = 0;
int ex_handles = 0;
@@ -1116,7 +1112,9 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
int retcode = 0;
DWORD ms_total = 0;
- int nsock = 0, nhandles = 0, nSockEvents = 0;
+ int nsock = 0;
+ int nhandles = 0;
+ int nSockEvents = 0;
static HANDLE hEventRead = 0;
static HANDLE hEventWrite = 0;
@@ -1132,12 +1130,18 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
DWORD newretcode = 0;
int returnedpos = 0;
- struct GNUNET_CONTAINER_SList *handles_read, *handles_write, *handles_except;
+ struct GNUNET_CONTAINER_SList *handles_read;
+ struct GNUNET_CONTAINER_SList *handles_write;
+ struct GNUNET_CONTAINER_SList *handles_except;
- fd_set aread, awrite, aexcept;
+ fd_set aread;
+ fd_set awrite;
+ fd_set aexcept;
#if DEBUG_NETWORK
- fd_set bread, bwrite, bexcept;
+ fd_set bread;
+ fd_set bwrite;
+ fd_set bexcept;
#endif
/* TODO: Make this growable */
@@ -1421,21 +1425,14 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
}
handle_array[nhandles] = NULL;
-
-#if DEBUG_NETWORK
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Number nfds : %d\n", nfds);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Number of handles : %d\n", nhandles);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "retcode : %d\n", newretcode);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Will wait : %d\n", ms_total);
-#endif
-
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Number nfds: %d, handles: %d, return code: %u will wait: %d ms\n",
+ nfds, nhandles, newretcode, ms_total);
if (nhandles)
returncode =
WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_total);
-#if DEBUG_NETWORK
LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n",
returncode);
-#endif
returnedpos = returncode - WAIT_OBJECT_0;
LOG (GNUNET_ERROR_TYPE_DEBUG, "return pos is : %d\n", returnedpos);
@@ -1455,7 +1452,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
struct timeval tvslice;
tvslice.tv_sec = 0;
- tvslice.tv_usec = 10;
+ tvslice.tv_usec = 0;
retcode = select (nfds, &aread, &awrite, &aexcept, &tvslice);
if (retcode == -1)
retcode = 0;
@@ -1546,10 +1543,8 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
}
}
}
-#if DEBUG_NETWORK
if (!nhandles || (returnedpos >= nhandles))
LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning from _select() with nothing!\n");
-#endif
if (rfds)
{
struct GNUNET_CONTAINER_SList_Iterator t;
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
index b82813d..e790ce1 100644
--- a/src/util/os_installation.c
+++ b/src/util/os_installation.c
@@ -62,7 +62,7 @@ get_path_from_proc_maps ()
while (NULL != fgets (line, sizeof (line), f))
{
if ((1 ==
- sscanf (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) &&
+ SSCANF (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) &&
(NULL != (lgu = strstr (dir, "libgnunetutil"))))
{
lgu[0] = '\0';
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index a1f173a..b8b1ba1 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -31,6 +31,7 @@
#include "gnunet_strings_lib.h"
#include "gnunet_crypto_lib.h"
#include "disk.h"
+#include <unistr.h>
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -299,7 +300,7 @@ npipe_open (const char *fn,
}
if (-1 == fd)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
(flags == GNUNET_DISK_OPEN_READ)
? _("Failed to open named pipe `%s' for reading: %s\n")
: _("Failed to open named pipe `%s' for writing: %s\n"),
@@ -325,29 +326,32 @@ parent_control_handler (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_DISK_FileHandle *control_pipe = cls;
- int sig;
-
+ char sig;
+ ssize_t ret;
+
LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' invoked because of %d\n", __FUNCTION__,
tc->reason);
- if (tc->reason &
- (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT |
- GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+ if (0 != (tc->reason &
+ (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT)))
{
GNUNET_DISK_file_close (control_pipe);
+ control_pipe = NULL;
return;
}
- if (GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)) !=
- sizeof (sig))
+ ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig));
+ if (sizeof (sig) != ret)
{
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
+ if (-1 == ret)
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
GNUNET_DISK_file_close (control_pipe);
+ control_pipe = NULL;
return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d from parent\n", sig);
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
control_pipe, &parent_control_handler,
control_pipe);
- raise (sig);
+ raise ((int) sig);
}
@@ -425,27 +429,22 @@ int
GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
{
int ret;
+ char csig;
+ csig = (char) sig;
#if !WINDOWS
if ( (NULL == proc->control_pipe) &&
(NULL != proc->childpipename) )
proc->control_pipe = npipe_open (proc->childpipename,
GNUNET_DISK_OPEN_WRITE);
#endif
- if (NULL == proc->control_pipe)
+ if (NULL != proc->control_pipe)
{
-#if WINDOWS
- /* no pipe and windows? can't do this */
- errno = EINVAL;
- return -1;
-#else
- return kill (proc->pid, sig);
-#endif
+ ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig));
+ if (ret == sizeof (csig))
+ return 0;
}
- ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig));
- if (ret == sizeof (sig))
- return 0;
- /* pipe failed, try other methods */
+ /* pipe failed or non-existent, try other methods */
switch (sig)
{
#if !WINDOWS
@@ -469,7 +468,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
errno = EINVAL;
return -1;
#else
- return kill (proc->pid, sig);
+ return PLIBC_KILL (proc->pid, sig);
#endif
}
}
@@ -488,13 +487,16 @@ GNUNET_OS_process_get_pid (struct GNUNET_OS_Process * proc)
}
+/**
+ * Cleans up process structure contents (OS-dependent) and deallocates it
+ *
+ * @param proc pointer to process structure
+ */
void
-GNUNET_OS_process_close (struct GNUNET_OS_Process *proc)
+GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc)
{
-#if ENABLE_WINDOWS_WORKAROUNDS
- if (proc->control_pipe)
+ if (NULL != proc->control_pipe)
GNUNET_DISK_file_close (proc->control_pipe);
-#endif
// FIXME NILS
#ifdef WINDOWS
if (proc->handle != NULL)
@@ -648,10 +650,15 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
static char *
CreateCustomEnvTable (char **vars)
{
- char *win32_env_table, *ptr, **var_ptr, *result, *result_ptr;
+ char *win32_env_table;
+ char *ptr;
+ char **var_ptr;
+ char *result;
+ char *result_ptr;
size_t tablesize = 0;
size_t items_count = 0;
- size_t n_found = 0, n_var;
+ size_t n_found = 0;
+ size_t n_var;
char *index = NULL;
size_t c;
size_t var_len;
@@ -804,8 +811,11 @@ GNUNET_OS_start_process_vap (int pipe_control,
ret = fork ();
if (-1 == ret)
{
+ int eno = errno;
+
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
GNUNET_free_non_null (childpipename);
+ errno = eno;
return NULL;
}
if (0 != ret)
@@ -863,7 +873,10 @@ GNUNET_OS_start_process_vap (int pipe_control,
char *libdir;
char *ptr;
char *non_const_filename;
- wchar_t wpath[MAX_PATH + 1], wcmd[32768];
+ char win_path[MAX_PATH + 1];
+ wchar_t *wpath, *wcmd;
+ size_t wpath_len, wcmd_len;
+ long lRet;
/* Search in prefix dir (hopefully - the directory from which
* the current module was loaded), bindir and libdir, then in PATH
@@ -895,7 +908,22 @@ GNUNET_OS_start_process_vap (int pipe_control,
else
GNUNET_asprintf (&non_const_filename, "%s", filename);
+ /* It could be in POSIX form, convert it to a DOS path early on */
+ if (ERROR_SUCCESS != (lRet = plibc_conv_to_win_path (non_const_filename, win_path)))
+ {
+ SetErrnoFromWinError (lRet);
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path",
+ non_const_filename);
+ GNUNET_free (non_const_filename);
+ GNUNET_free (pathbuf);
+ return NULL;
+ }
+ GNUNET_free (non_const_filename);
+ non_const_filename = GNUNET_strdup (win_path);
/* Check that this is the full path. If it isn't, search. */
+ /* FIXME: convert it to wchar_t and use SearchPathW?
+ * Remember: arguments to _start_process() are technically in UTF-8...
+ */
if (non_const_filename[1] == ':')
snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
else if (!SearchPathA
@@ -972,6 +1000,8 @@ GNUNET_OS_start_process_vap (int pipe_control,
return NULL;
}
}
+ else
+ control_pipe = NULL;
if (NULL != childpipename)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n",
@@ -985,19 +1015,39 @@ GNUNET_OS_start_process_vap (int pipe_control,
our_env[0] = NULL;
}
env_block = CreateCustomEnvTable (our_env);
- GNUNET_free (our_env[0]);
- GNUNET_free (our_env[1]);
+ GNUNET_free_non_null (our_env[0]);
+ GNUNET_free_non_null (our_env[1]);
+
+ wpath_len = 0;
+ if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ return NULL;
+ }
+
+ wcmd_len = 0;
+ if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ free (wpath);
+ return NULL;
+ }
- if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)
- || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd)
- || !CreateProcessW
- (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
- env_block, NULL, &start, &proc))
+ if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE,
+ DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc))
{
SetErrnoFromWinError (GetLastError ());
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
GNUNET_free (env_block);
GNUNET_free (cmd);
+ free (wpath);
+ free (wcmd);
return NULL;
}
@@ -1014,7 +1064,8 @@ GNUNET_OS_start_process_vap (int pipe_control,
CloseHandle (proc.hThread);
GNUNET_free (cmd);
-
+ free (wpath);
+ free (wcmd);
return gnunet_proc;
#endif
}
@@ -1136,9 +1187,12 @@ GNUNET_OS_start_process_v (int pipe_control,
ret = fork ();
if (-1 == ret)
{
+ int eno = errno;
+
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
GNUNET_free_non_null (childpipename);
GNUNET_array_grow (lscp, ls, 0);
+ errno = eno;
return NULL;
}
if (0 != ret)
@@ -1220,13 +1274,16 @@ GNUNET_OS_start_process_v (int pipe_control,
char *libdir;
char *ptr;
char *non_const_filename;
+ char win_path[MAX_PATH + 1];
struct GNUNET_DISK_PipeHandle *lsocks_pipe;
const struct GNUNET_DISK_FileHandle *lsocks_write_fd;
HANDLE lsocks_read;
HANDLE lsocks_write;
- wchar_t wpath[MAX_PATH + 1], wcmd[32768];
+ wchar_t *wpath, *wcmd;
+ size_t wpath_len, wcmd_len;
int env_off;
int fail;
+ long lRet;
/* Search in prefix dir (hopefully - the directory from which
* the current module was loaded), bindir and libdir, then in PATH
@@ -1263,7 +1320,22 @@ GNUNET_OS_start_process_v (int pipe_control,
else
GNUNET_asprintf (&non_const_filename, "%s", filename);
- /* Check that this is the full path. If it isn't, search. */
+ /* It could be in POSIX form, convert it to a DOS path early on */
+ if (ERROR_SUCCESS != (lRet = plibc_conv_to_win_path (non_const_filename, win_path)))
+ {
+ SetErrnoFromWinError (lRet);
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path",
+ non_const_filename);
+ GNUNET_free (non_const_filename);
+ GNUNET_free (pathbuf);
+ return NULL;
+ }
+ GNUNET_free (non_const_filename);
+ non_const_filename = GNUNET_strdup (win_path);
+ /* Check that this is the full path. If it isn't, search. */
+ /* FIXME: convert it to wchar_t and use SearchPathW?
+ * Remember: arguments to _start_process() are technically in UTF-8...
+ */
if (non_const_filename[1] == ':')
snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
else if (!SearchPathA
@@ -1345,6 +1417,8 @@ GNUNET_OS_start_process_v (int pipe_control,
return NULL;
}
}
+ else
+ control_pipe = NULL;
if (lsocks != NULL && lsocks[0] != INVALID_SOCKET)
{
lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
@@ -1384,11 +1458,30 @@ GNUNET_OS_start_process_v (int pipe_control,
env_block = CreateCustomEnvTable (our_env);
while (0 > env_off)
GNUNET_free_non_null (our_env[--env_off]);
- if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)
- || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd)
- || !CreateProcessW
- (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
- env_block, NULL, &start, &proc))
+
+ wpath_len = 0;
+ if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ return NULL;
+ }
+
+ wcmd_len = 0;
+ if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno);
+ GNUNET_free (env_block);
+ GNUNET_free (cmd);
+ free (wpath);
+ return NULL;
+ }
+
+ if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE,
+ DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc))
{
SetErrnoFromWinError (GetLastError ());
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
@@ -1398,6 +1491,8 @@ GNUNET_OS_start_process_v (int pipe_control,
GNUNET_DISK_pipe_close (lsocks_pipe);
GNUNET_free (env_block);
GNUNET_free (cmd);
+ free (wpath);
+ free (wcmd);
return NULL;
}
@@ -1413,6 +1508,8 @@ GNUNET_OS_start_process_v (int pipe_control,
ResumeThread (proc.hThread);
CloseHandle (proc.hThread);
GNUNET_free (cmd);
+ free (wpath);
+ free (wcmd);
if (lsocks == NULL || lsocks[0] == INVALID_SOCKET)
return gnunet_proc;
@@ -1499,7 +1596,9 @@ GNUNET_OS_start_process_v (int pipe_control,
/**
- * Retrieve the status of a process
+ * Retrieve the status of a process, waiting on him if dead.
+ * Nonblocking version.
+ *
* @param proc process ID
* @param type status type
* @param code return code/signal number
@@ -1716,7 +1815,7 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
}
(void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip));
- GNUNET_OS_process_close (cmd->eip);
+ GNUNET_OS_process_destroy (cmd->eip);
GNUNET_DISK_pipe_close (cmd->opipe);
GNUNET_free (cmd);
}
diff --git a/src/util/program.c b/src/util/program.c
index 6a0e5a5..9e1a83d 100644
--- a/src/util/program.c
+++ b/src/util/program.c
@@ -72,6 +72,11 @@ struct CommandContext
};
+int
+GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+int
+GNUNET_SPEEDUP_stop_ (void);
/**
* Initial task called by the scheduler for each
@@ -81,6 +86,7 @@ static void
program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct CommandContext *cc = cls;
+ GNUNET_SPEEDUP_start_(cc->cfg);
GNUNET_RESOLVER_connect (cc->cfg);
cc->task (cc->task_cls, cc->args, cc->cfgfile, cc->cfg);
@@ -95,10 +101,10 @@ program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
* @param a2 second command line option
*/
static int
-cmd_sorter (__const void *a1, __const void *a2)
+cmd_sorter (const void *a1, const void *a2)
{
- __const struct GNUNET_GETOPT_CommandLineOption *c1 = a1;
- __const struct GNUNET_GETOPT_CommandLineOption *c2 = a2;
+ const struct GNUNET_GETOPT_CommandLineOption *c1 = a1;
+ const struct GNUNET_GETOPT_CommandLineOption *c2 = a2;
if (toupper ((unsigned char) c1->shortName) >
toupper ((unsigned char) c2->shortName))
@@ -125,13 +131,16 @@ cmd_sorter (__const void *a1, __const void *a2)
* @param options command line options
* @param task main function to run
* @param task_cls closure for task
+ * @param run_without_scheduler GNUNET_NO start the scheduler, GNUNET_YES do not
+ * start the scheduler just run the main task
* @return GNUNET_SYSERR on error, GNUNET_OK on success
*/
int
-GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName,
+GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
const char *binaryHelp,
const struct GNUNET_GETOPT_CommandLineOption *options,
- GNUNET_PROGRAM_Main task, void *task_cls)
+ GNUNET_PROGRAM_Main task, void *task_cls,
+ int run_without_scheduler)
{
struct CommandContext cc;
char *path;
@@ -247,9 +256,17 @@ GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName,
}
/* run */
cc.args = &argv[ret];
- GNUNET_SCHEDULER_run (&program_main, &cc);
-
+ if (GNUNET_NO == run_without_scheduler)
+ {
+ GNUNET_SCHEDULER_run (&program_main, &cc);
+ }
+ else
+ {
+ GNUNET_RESOLVER_connect (cc.cfg);
+ cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg);
+ }
/* clean up */
+ GNUNET_SPEEDUP_stop_ ();
GNUNET_CONFIGURATION_destroy (cfg);
GNUNET_free_non_null (cc.cfgfile);
GNUNET_free_non_null (loglev);
@@ -257,5 +274,28 @@ GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName,
return GNUNET_OK;
}
+/**
+ * Run a standard GNUnet command startup sequence (initialize loggers
+ * and configuration, parse options).
+ *
+ * @param argc number of command line arguments
+ * @param argv command line arguments
+ * @param binaryName our expected name
+ * @param binaryHelp help text for the program
+ * @param options command line options
+ * @param task main function to run
+ * @param task_cls closure for task
+ * @return GNUNET_SYSERR on error, GNUNET_OK on success
+ */
+int
+GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName,
+ const char *binaryHelp,
+ const struct GNUNET_GETOPT_CommandLineOption *options,
+ GNUNET_PROGRAM_Main task, void *task_cls)
+{
+ return GNUNET_PROGRAM_run2 (argc, argv, binaryName, binaryHelp, options, task, task_cls, GNUNET_NO);
+}
+
+
/* end of program.c */
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c
index 782a405..0165738 100644
--- a/src/util/pseudonym.c
+++ b/src/util/pseudonym.c
@@ -96,7 +96,7 @@ internal_notify (const GNUNET_HashCode * id,
pos = head;
while (pos != NULL)
{
- pos->callback (pos->closure, id, md, rating);
+ pos->callback (pos->closure, id, NULL, NULL, md, rating);
pos = pos->next;
}
}
@@ -104,6 +104,9 @@ internal_notify (const GNUNET_HashCode * id,
/**
* Register callback to be invoked whenever we discover
* a new pseudonym.
+ * Will immediately call provided iterator callback for all
+ * already discovered pseudonyms.
+ *
* @param cfg configuration to use
* @param iterator iterator over pseudonym
* @param closure point to a closure
@@ -185,7 +188,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
* @param nsid hash code of a pseudonym
* @param meta meta data to be written into a file
* @param ranking ranking of a pseudonym
- * @param ns_name name of a pseudonym
+ * @param ns_name non-unique name of a pseudonym
*/
static void
write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -219,9 +222,9 @@ write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
}
GNUNET_free (fn);
/* create entry for pseudonym name in names */
- /* FIXME: 90% of what this call does is not needed
- * here => refactor code to only create the entry! */
- GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid));
+ if (ns_name != NULL)
+ GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name,
+ NULL));
}
@@ -286,63 +289,38 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
}
-
/**
- * Return the unique, human readable name for the given namespace.
+ * Return unique variant of the namespace name.
+ * Use it after GNUNET_PSEUDONYM_get_info() to make sure
+ * that name is unique.
*
* @param cfg configuration
* @param nsid cryptographic ID of the namespace
- * @return NULL on failure (should never happen)
+ * @param name name to uniquify
+ * @param suffix if not NULL, filled with the suffix value
+ * @return NULL on failure (should never happen), name on success.
+ * Free the name with GNUNET_free().
*/
char *
-GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const GNUNET_HashCode * nsid)
+GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix)
{
- struct GNUNET_CONTAINER_MetaData *meta;
- char *name;
GNUNET_HashCode nh;
- char *fn;
uint64_t len;
+ char *fn;
struct GNUNET_DISK_FileHandle *fh;
unsigned int i;
unsigned int idx;
char *ret;
struct stat sbuf;
- int32_t temp = 0;
- int32_t *rank = &temp;
- meta = NULL;
- name = NULL;
- if (GNUNET_OK == read_info (cfg, nsid, &meta, rank, &name))
- {
- if ((meta != NULL) && (name == NULL))
- name =
- GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
- EXTRACTOR_METATYPE_TITLE,
- EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
- EXTRACTOR_METATYPE_FILENAME,
- EXTRACTOR_METATYPE_DESCRIPTION,
- EXTRACTOR_METATYPE_SUBJECT,
- EXTRACTOR_METATYPE_PUBLISHER,
- EXTRACTOR_METATYPE_AUTHOR_NAME,
- EXTRACTOR_METATYPE_COMMENT,
- EXTRACTOR_METATYPE_SUMMARY,
- -1);
- if (meta != NULL)
- {
- GNUNET_CONTAINER_meta_data_destroy (meta);
- meta = NULL;
- }
- }
- if (name == NULL)
- name = GNUNET_strdup (_("no-name"));
GNUNET_CRYPTO_hash (name, strlen (name), &nh);
fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
GNUNET_assert (fn != NULL);
len = 0;
if (0 == STAT (fn, &sbuf))
- GNUNET_DISK_file_size (fn, &len, GNUNET_YES);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES));
fh = GNUNET_DISK_file_open (fn,
GNUNET_DISK_OPEN_CREATE |
GNUNET_DISK_OPEN_READWRITE,
@@ -372,22 +350,107 @@ GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg,
GNUNET_DISK_file_close (fh);
ret = GNUNET_malloc (strlen (name) + 32);
GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
- GNUNET_free (name);
+ if (suffix != NULL)
+ *suffix = idx;
GNUNET_free (fn);
return ret;
}
/**
+ * Get namespace name, metadata and rank
+ * This is a wrapper around internal read_info() call, and ensures that
+ * returned data is not invalid (not NULL).
+ *
+ * @param cfg configuration
+ * @param nsid cryptographic ID of the namespace
+ * @param ret_meta a location to store metadata pointer. NULL, if metadata
+ * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
+ * @param ret_rank a location to store rank. NULL, if rank not needed.
+ * @param ret_name a location to store human-readable name. Name is not unique.
+ * NULL, if name is not needed. Free with GNUNET_free().
+ * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
+ * a duplicate of a "no-name" placeholder
+ * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
+ * unobtainable (in that case ret_* are filled with placeholders -
+ * empty metadata container, rank -1 and a "no-name" name).
+ */
+int
+GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta,
+ int32_t *ret_rank, char **ret_name, int *name_is_a_dup)
+{
+ struct GNUNET_CONTAINER_MetaData *meta;
+ char *name;
+ int32_t rank = -1;
+
+ meta = NULL;
+ name = NULL;
+ if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name))
+ {
+ if ((meta != NULL) && (name == NULL))
+ name =
+ GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
+ EXTRACTOR_METATYPE_TITLE,
+ EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
+ EXTRACTOR_METATYPE_FILENAME,
+ EXTRACTOR_METATYPE_DESCRIPTION,
+ EXTRACTOR_METATYPE_SUBJECT,
+ EXTRACTOR_METATYPE_PUBLISHER,
+ EXTRACTOR_METATYPE_AUTHOR_NAME,
+ EXTRACTOR_METATYPE_COMMENT,
+ EXTRACTOR_METATYPE_SUMMARY,
+ -1);
+ if (ret_name != NULL)
+ {
+ if (name == NULL)
+ {
+ name = GNUNET_strdup (_("no-name"));
+ if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_YES;
+ }
+ else if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_NO;
+ *ret_name = name;
+ }
+ else if (name != NULL)
+ GNUNET_free (name);
+
+ if (ret_meta != NULL)
+ {
+ if (meta == NULL)
+ meta = GNUNET_CONTAINER_meta_data_create ();
+ *ret_meta = meta;
+ }
+ else if (meta != NULL)
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+
+ if (ret_rank != NULL)
+ *ret_rank = rank;
+
+ return GNUNET_OK;
+ }
+ if (ret_name != NULL)
+ *ret_name = GNUNET_strdup (_("no-name"));
+ if (ret_meta != NULL)
+ *ret_meta = GNUNET_CONTAINER_meta_data_create ();
+ if (ret_rank != NULL)
+ *ret_rank = -1;
+ if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_YES;
+ return GNUNET_SYSERR;
+}
+
+/**
* Get the namespace ID belonging to the given namespace name.
*
* @param cfg configuration to use
- * @param ns_uname human-readable name for the namespace
+ * @param ns_uname unique (!) human-readable name for the namespace
* @param nsid set to namespace ID based on 'ns_uname'
- * @return GNUNET_OK on success
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
*/
int
GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *ns_uname, GNUNET_HashCode * nsid)
+ const char *ns_uname, GNUNET_HashCode * nsid)
{
size_t slen;
uint64_t len;
@@ -399,19 +462,20 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
idx = -1;
slen = strlen (ns_uname);
- while ((slen > 0) && (1 != sscanf (&ns_uname[slen - 1], "-%u", &idx)))
+ while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx)))
slen--;
if (slen == 0)
return GNUNET_SYSERR;
name = GNUNET_strdup (ns_uname);
name[slen - 1] = '\0';
+
GNUNET_CRYPTO_hash (name, strlen (name), &nh);
GNUNET_free (name);
fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
GNUNET_assert (fn != NULL);
if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
- (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES))) ||
+ (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) ||
((idx + 1) * sizeof (GNUNET_HashCode) > len))
{
GNUNET_free (fn);
@@ -472,10 +536,11 @@ list_pseudonym_helper (void *cls, const char *fullname)
struct ListPseudonymClosure *c = cls;
int ret;
GNUNET_HashCode id;
- int rating;
+ int32_t rating;
struct GNUNET_CONTAINER_MetaData *meta;
const char *fn;
char *str;
+ char *name_unique;
if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
return GNUNET_OK;
@@ -487,11 +552,22 @@ list_pseudonym_helper (void *cls, const char *fullname)
if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id))
return GNUNET_OK; /* invalid name */
str = NULL;
- if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, &str))
- return GNUNET_OK; /* ignore entry */
- GNUNET_free_non_null (str);
+ if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating,
+ &str, NULL))
+ {
+ /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason
+ * to ignore it... So yeah, it will have placeholders instead of name,
+ * empty metadata container and a default rank == -1, so what? We know
+ * its nsid - that's all we really need. Right? */
+ GNUNET_free (str);
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ return GNUNET_OK;
+ }
+ name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL);
if (c->iterator != NULL)
- ret = c->iterator (c->closure, &id, meta, rating);
+ ret = c->iterator (c->closure, &id, str, name_unique, meta, rating);
+ GNUNET_free_non_null (str);
+ GNUNET_free_non_null (name_unique);
GNUNET_CONTAINER_meta_data_destroy (meta);
return ret;
}
@@ -559,6 +635,31 @@ GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
/**
+ * Set the pseudonym metadata, rank and name.
+ *
+ * @param cfg overall configuration
+ * @param nsid id of the pseudonym
+ * @param name name to set. Must be the non-unique version of it.
+ * May be NULL, in which case it erases pseudonym's name!
+ * @param md metadata to set
+ * May be NULL, in which case it erases pseudonym's metadata!
+ * @param rank rank to assign
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const GNUNET_HashCode * nsid, const char *name,
+ const struct GNUNET_CONTAINER_MetaData *md, int rank)
+{
+ GNUNET_assert (cfg != NULL);
+ GNUNET_assert (nsid != NULL);
+
+ write_pseudonym_info (cfg, nsid, md, rank, name);
+ return GNUNET_OK;
+}
+
+
+/**
* Add a pseudonym to the set of known pseudonyms.
* For all pseudonym advertisements that we discover
* FS should automatically call this function.
diff --git a/src/util/resolver.conf.in b/src/util/resolver.conf.in
index 671ea0e..7abe1c9 100644
--- a/src/util/resolver.conf.in
+++ b/src/util/resolver.conf.in
@@ -1,6 +1,6 @@
[resolver]
AUTOSTART = YES
-@UNIXONLY@ PORT = 2089
+@JAVAPORT@PORT = 2089
HOSTNAME = localhost
HOME = $SERVICEHOME
CONFIG = $DEFAULTCONFIG
diff --git a/src/util/resolver.h b/src/util/resolver.h
index 2c0de99..b77c199 100644
--- a/src/util/resolver.h
+++ b/src/util/resolver.h
@@ -27,8 +27,6 @@
#include "gnunet_common.h"
-#define DEBUG_RESOLVER GNUNET_EXTRA_LOGGING
-
GNUNET_NETWORK_STRUCT_BEGIN
/**
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index 9d5ae6c..87b76f1 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -250,10 +250,8 @@ GNUNET_RESOLVER_disconnect ()
GNUNET_assert (NULL == req_tail);
if (NULL != client)
{
-#if DEBUG_RESOLVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DNS service\n");
-#endif
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
}
if (r_task != GNUNET_SCHEDULER_NO_TASK)
@@ -339,9 +337,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
struct GNUNET_RESOLVER_RequestHandle *rh = cls;
uint16_t size;
-#if DEBUG_RESOLVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n");
-#endif
if (msg == NULL)
{
char buf[INET6_ADDRSTRLEN];
@@ -374,7 +370,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
}
GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
GNUNET_free (rh);
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
reconnect ();
return;
@@ -382,7 +378,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
{
GNUNET_break (0);
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
reconnect ();
return;
@@ -417,15 +413,13 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
rh->name_callback (rh->cls, NULL);
GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
GNUNET_free (rh);
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
reconnect ();
return;
}
-#if DEBUG_RESOLVER
- LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s' for IP `%s'.\n"),
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s' for IP `%s'.\n",
hostname, GNUNET_a2s ((const void *) &rh[1], rh->data_len));
-#endif
if (rh->was_transmitted != GNUNET_SYSERR)
rh->name_callback (rh->cls, hostname);
rh->received_response = GNUNET_YES;
@@ -473,7 +467,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
rh->addr_callback (rh->cls, NULL, 0);
GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
GNUNET_free (rh);
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
reconnect ();
return;
@@ -606,7 +600,7 @@ static void
process_requests ()
{
struct GNUNET_RESOLVER_GetMessage *msg;
- char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
struct GNUNET_RESOLVER_RequestHandle *rh;
if (NULL == client)
@@ -633,17 +627,15 @@ process_requests ()
msg->direction = htonl (rh->direction);
msg->af = htonl (rh->af);
memcpy (&msg[1], &rh[1], rh->data_len);
-#if DEBUG_RESOLVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmitting DNS resolution request to DNS service\n");
-#endif
if (GNUNET_OK !=
GNUNET_CLIENT_transmit_and_get_response (client, &msg->header,
GNUNET_TIME_absolute_get_remaining
(rh->timeout), GNUNET_YES,
&handle_response, rh))
{
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
reconnect ();
return;
@@ -666,9 +658,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
return; /* no work pending */
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
-#if DEBUG_RESOLVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to DNS service\n");
-#endif
client = GNUNET_CLIENT_connect ("resolver", resolver_cfg);
if (NULL == client)
{
@@ -712,11 +702,9 @@ reconnect ()
break;
}
}
-#if DEBUG_RESOLVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Will try to connect to DNS service in %llu ms\n",
(unsigned long long) backoff.rel_value);
-#endif
GNUNET_assert (NULL != resolver_cfg);
r_task = GNUNET_SCHEDULER_add_delayed (backoff, &reconnect_task, NULL);
backoff = GNUNET_TIME_relative_multiply (backoff, 2);
@@ -803,9 +791,7 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
char *result;
result = no_resolve (rh->af, &rh[1], rh->data_len);
-#if DEBUG_RESOLVER
- LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result);
-#endif
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s'.\n", result);
if (result != NULL)
{
rh->name_callback (rh->cls, result);
@@ -897,9 +883,7 @@ GNUNET_RESOLVER_local_fqdn_get ()
"gethostname");
return NULL;
}
-#if DEBUG_RESOLVER
- LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"), hostname);
-#endif
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving our FQDN `%s'\n", hostname);
host = gethostbyname (hostname);
if (NULL == host)
{
@@ -934,9 +918,7 @@ GNUNET_RESOLVER_hostname_resolve (int af,
"gethostname");
return NULL;
}
-#if DEBUG_RESOLVER
- LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname);
-#endif
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving our hostname `%s'\n", hostname);
return GNUNET_RESOLVER_ip_get (hostname, af, timeout, callback, cls);
}
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index c54672f..45cc020 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -115,11 +115,6 @@ struct Task
GNUNET_SCHEDULER_TaskIdentifier id;
/**
- * Identifier of a prerequisite task.
- */
- GNUNET_SCHEDULER_TaskIdentifier prereq_id;
-
- /**
* Absolute timeout value for the task, or
* GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout".
*/
@@ -216,13 +211,6 @@ static struct Task *ready[GNUNET_SCHEDULER_PRIORITY_COUNT];
static GNUNET_SCHEDULER_TaskIdentifier last_id;
/**
- * Highest number so that all tasks with smaller identifiers
- * have already completed. Also the lowest number of a task
- * still waiting to be executed.
- */
-static GNUNET_SCHEDULER_TaskIdentifier lowest_pending_id;
-
-/**
* Number of tasks on the ready list.
*/
static unsigned int ready_count;
@@ -293,60 +281,6 @@ check_priority (enum GNUNET_SCHEDULER_Priority p)
/**
- * Is a task with this identifier still pending? Also updates
- * "lowest_pending_id" as a side-effect (for faster checks in the
- * future), but only if the return value is "GNUNET_NO" (and
- * the "lowest_pending_id" check failed).
- *
- * @param id which task are we checking for
- * @return GNUNET_YES if so, GNUNET_NO if not
- */
-static int
-is_pending (GNUNET_SCHEDULER_TaskIdentifier id)
-{
- struct Task *pos;
- enum GNUNET_SCHEDULER_Priority p;
- GNUNET_SCHEDULER_TaskIdentifier min;
-
- if (id < lowest_pending_id)
- return GNUNET_NO;
- min = -1; /* maximum value */
- pos = pending;
- while (pos != NULL)
- {
- if (pos->id == id)
- return GNUNET_YES;
- if (pos->id < min)
- min = pos->id;
- pos = pos->next;
- }
- pos = pending_timeout;
- while (pos != NULL)
- {
- if (pos->id == id)
- return GNUNET_YES;
- if (pos->id < min)
- min = pos->id;
- pos = pos->next;
- }
- for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++)
- {
- pos = ready[p];
- while (pos != NULL)
- {
- if (pos->id == id)
- return GNUNET_YES;
- if (pos->id < min)
- min = pos->id;
- pos = pos->next;
- }
- }
- lowest_pending_id = min;
- return GNUNET_NO;
-}
-
-
-/**
* Update all sets and timeout for select.
*
* @param rs read-set, set to all FDs we would like to read (updated)
@@ -374,12 +308,6 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws,
pos = pending;
while (pos != NULL)
{
- if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
- (GNUNET_YES == is_pending (pos->prereq_id)))
- {
- pos = pos->next;
- continue;
- }
if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
{
to = GNUNET_TIME_absolute_get_difference (now, pos->timeout);
@@ -459,15 +387,7 @@ is_ready (struct Task *task, struct GNUNET_TIME_Absolute now,
reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
if (reason == 0)
return GNUNET_NO; /* not ready */
- if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK)
- {
- if (GNUNET_YES == is_pending (task->prereq_id))
- {
- task->reason = reason;
- return GNUNET_NO; /* prereq waiting */
- }
- reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
- }
+ reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
task->reason = reason;
return GNUNET_YES;
}
@@ -1107,31 +1027,6 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls,
/**
- * Schedule a new task to be run after the specified prerequisite task
- * has completed. It will be run with the DEFAULT priority.
- *
- * @param prerequisite_task run this task after the task with the given
- * task identifier completes (and any of our other
- * conditions, such as delay, read or write-readiness
- * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency
- * on completion of other tasks (this will cause the task to run as
- * soon as possible).
- * @param task main function of the task
- * @param task_cls closure of task
- * @return unique task identifier for the job
- * only valid until "task" is started!
- */
-GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
- GNUNET_SCHEDULER_Task task, void *task_cls)
-{
- return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- prerequisite_task, GNUNET_TIME_UNIT_ZERO,
- NULL, NULL, task, task_cls);
-}
-
-
-/**
* Schedule a new task to be run with a specified priority.
*
* @param prio how important is the new task?
@@ -1144,7 +1039,7 @@ GNUNET_SCHEDULER_TaskIdentifier
GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
GNUNET_SCHEDULER_Task task, void *task_cls)
{
- return GNUNET_SCHEDULER_add_select (prio, GNUNET_SCHEDULER_NO_TASK,
+ return GNUNET_SCHEDULER_add_select (prio,
GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
task_cls);
}
@@ -1299,7 +1194,6 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK,
GNUNET_TIME_UNIT_ZERO, NULL, NULL, task,
task_cls);
GNUNET_assert (pending->id == ret);
@@ -1399,7 +1293,6 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
#if PROFILE_DELAYS
t->start_time = GNUNET_TIME_absolute_get ();
#endif
- t->prereq_id = GNUNET_SCHEDULER_NO_TASK;
t->timeout = GNUNET_TIME_relative_to_absolute (delay);
t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority);
t->lifeness = current_lifeness;
@@ -1441,6 +1334,35 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
struct GNUNET_NETWORK_Handle *rfd,
GNUNET_SCHEDULER_Task task, void *task_cls)
{
+ return GNUNET_SCHEDULER_add_read_net_with_priority (delay,
+ GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+ rfd, task, task_cls);
+}
+
+
+/**
+ * Schedule a new task to be run with a specified priority and to be
+ * run after the specified delay or when the specified file descriptor
+ * is ready for reading. The delay can be used as a timeout on the
+ * socket being ready. The task will be scheduled for execution once
+ * either the delay has expired or the socket operation is ready. It
+ * will be run with the DEFAULT priority.
+ *
+ * @param delay when should this operation time out? Use
+ * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param priority priority to use for the task
+ * @param rfd read file-descriptor
+ * @param task main function of the task
+ * @param task_cls closure of task
+ * @return unique task identifier for the job
+ * only valid until "task" is started!
+ */
+GNUNET_SCHEDULER_TaskIdentifier
+GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
+ enum GNUNET_SCHEDULER_Priority priority,
+ struct GNUNET_NETWORK_Handle *rfd,
+ GNUNET_SCHEDULER_Task task, void *task_cls)
+{
#if MINGW
struct GNUNET_NETWORK_FDSet *rs;
GNUNET_SCHEDULER_TaskIdentifier ret;
@@ -1449,20 +1371,21 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
rs = GNUNET_NETWORK_fdset_create ();
GNUNET_NETWORK_fdset_set (rs, rfd);
ret =
- GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL,
+ GNUNET_SCHEDULER_add_select (priority,
+ delay, rs, NULL,
task, task_cls);
GNUNET_NETWORK_fdset_destroy (rs);
return ret;
#else
return add_without_sets (delay,
- GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+ priority,
GNUNET_NETWORK_get_fd (rfd), -1, task,
task_cls);
#endif
}
+
/**
* Schedule a new task to be run with a specified delay or when the
* specified file descriptor is ready for writing. The delay can be
@@ -1493,7 +1416,7 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
GNUNET_NETWORK_fdset_set (ws, wfd);
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws,
+ delay, NULL, ws,
task, task_cls);
GNUNET_NETWORK_fdset_destroy (ws);
return ret;
@@ -1536,7 +1459,7 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
GNUNET_NETWORK_fdset_handle_set (rs, rfd);
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL,
+ delay, rs, NULL,
task, task_cls);
GNUNET_NETWORK_fdset_destroy (rs);
return ret;
@@ -1581,7 +1504,7 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
GNUNET_NETWORK_fdset_handle_set (ws, wfd);
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws,
+ delay, NULL, ws,
task, task_cls);
GNUNET_NETWORK_fdset_destroy (ws);
return ret;
@@ -1617,11 +1540,6 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
* </code>
*
* @param prio how important is this task?
- * @param prerequisite_task run this task after the task with the given
- * task identifier completes (and any of our other
- * conditions, such as delay, read or write-readiness
- * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency
- * on completion of other tasks.
* @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever",
* which means that the task will only be run after we receive SIGTERM
* @param rs set of file descriptors we want to read (can be NULL)
@@ -1633,7 +1551,6 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
*/
GNUNET_SCHEDULER_TaskIdentifier
GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
- GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
struct GNUNET_TIME_Relative delay,
const struct GNUNET_NETWORK_FDSet *rs,
const struct GNUNET_NETWORK_FDSet *ws,
@@ -1671,7 +1588,6 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
#if PROFILE_DELAYS
t->start_time = GNUNET_TIME_absolute_get ();
#endif
- t->prereq_id = prerequisite_task;
t->timeout = GNUNET_TIME_relative_to_absolute (delay);
t->priority =
check_priority ((prio ==
diff --git a/src/util/server.c b/src/util/server.c
index 24804d2..409e89f 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -26,11 +26,7 @@
#include "platform.h"
#include "gnunet_common.h"
-#include "gnunet_connection_lib.h"
-#include "gnunet_scheduler_lib.h"
-#include "gnunet_server_lib.h"
-#include "gnunet_time_lib.h"
-#include "gnunet_disk_lib.h"
+#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -39,7 +35,6 @@
#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
-#define DEBUG_SERVER GNUNET_EXTRA_LOGGING
/**
* List of arrays of message handlers.
@@ -64,11 +59,16 @@ struct HandlerList
struct NotifyList
{
/**
- * This is a linked list.
+ * This is a doubly linked list.
*/
struct NotifyList *next;
/**
+ * This is a doubly linked list.
+ */
+ struct NotifyList *prev;
+
+ /**
* Function to call.
*/
GNUNET_SERVER_DisconnectCallback callback;
@@ -91,14 +91,24 @@ struct GNUNET_SERVER_Handle
struct HandlerList *handlers;
/**
- * List of our current clients.
+ * Head of list of our current clients.
*/
- struct GNUNET_SERVER_Client *clients;
+ struct GNUNET_SERVER_Client *clients_head;
/**
- * Linked list of functions to call on disconnects by clients.
+ * Head of list of our current clients.
*/
- struct NotifyList *disconnect_notify_list;
+ struct GNUNET_SERVER_Client *clients_tail;
+
+ /**
+ * Head of linked list of functions to call on disconnects by clients.
+ */
+ struct NotifyList *disconnect_notify_list_head;
+
+ /**
+ * Tail of linked list of functions to call on disconnects by clients.
+ */
+ struct NotifyList *disconnect_notify_list_tail;
/**
* Function to call for access control.
@@ -128,22 +138,62 @@ struct GNUNET_SERVER_Handle
GNUNET_SCHEDULER_TaskIdentifier listen_task;
/**
+ * Alternative function to create a MST instance.
+ */
+ GNUNET_SERVER_MstCreateCallback mst_create;
+
+ /**
+ * Alternative function to destroy a MST instance.
+ */
+ GNUNET_SERVER_MstDestroyCallback mst_destroy;
+
+ /**
+ * Alternative function to give data to a MST instance.
+ */
+ GNUNET_SERVER_MstReceiveCallback mst_receive;
+
+ /**
+ * Closure for 'mst_'-callbacks.
+ */
+ void *mst_cls;
+
+ /**
* Do we ignore messages of types that we do not understand or do we
* require that a handler is found (and if not kill the connection)?
*/
int require_found;
/**
- * Should all of the clients of this server continue to process
- * connections as usual even if we get a shutdown request? (the
- * listen socket always ignores shutdown).
+ * Set to GNUNET_YES once we are in 'soft' shutdown where we wait for
+ * all non-monitor clients to disconnect before we call
+ * GNUNET_SERVER_destroy. See 'test_monitor_clients'. Set to
+ * GNUNET_SYSERR once the final destroy task has been scheduled
+ * (we cannot run it in the same task).
*/
- int clients_ignore_shutdown;
+ int in_soft_shutdown;
+};
+
+
+/**
+ * Handle server returns for aborting transmission to a client.
+ */
+struct GNUNET_SERVER_TransmitHandle
+{
+ /**
+ * Function to call to get the message.
+ */
+ GNUNET_CONNECTION_TransmitReadyNotify callback;
+
+ /**
+ * Closure for 'callback'
+ */
+ void *callback_cls;
+
+ /**
+ * Active connection transmission handle.
+ */
+ struct GNUNET_CONNECTION_TransmitHandle *cth;
- GNUNET_SERVER_MstCreateCallback mst_create;
- GNUNET_SERVER_MstDestroyCallback mst_destroy;
- GNUNET_SERVER_MstReceiveCallback mst_receive;
- void *mst_cls;
};
@@ -154,11 +204,16 @@ struct GNUNET_SERVER_Client
{
/**
- * This is a linked list.
+ * This is a doubly linked list.
*/
struct GNUNET_SERVER_Client *next;
/**
+ * This is a doubly linked list.
+ */
+ struct GNUNET_SERVER_Client *prev;
+
+ /**
* Processing of incoming data.
*/
void *mst;
@@ -195,14 +250,10 @@ struct GNUNET_SERVER_Client
struct GNUNET_TIME_Absolute last_activity;
/**
- *
+ * Transmission handle we return for this client from
+ * GNUNET_SERVER_notify_transmit_ready.
*/
- GNUNET_CONNECTION_TransmitReadyNotify callback;
-
- /**
- * callback
- */
- void *callback_cls;
+ struct GNUNET_SERVER_TransmitHandle th;
/**
* After how long should an idle connection time
@@ -235,8 +286,7 @@ struct GNUNET_SERVER_Client
int in_process_client_buffer;
/**
- * We're about to close down this client due to some serious
- * error.
+ * We're about to close down this client.
*/
int shutdown_now;
@@ -259,6 +309,13 @@ struct GNUNET_SERVER_Client
int persist;
/**
+ * Is this client a 'monitor' client that should not be counted
+ * when deciding on destroying the server during soft shutdown?
+ * (see also GNUNET_SERVICE_start)
+ */
+ int is_monitor;
+
+ /**
* Type of last message processed (for warn_no_receive_done).
*/
uint16_t warn_type;
@@ -273,28 +330,66 @@ struct GNUNET_SERVER_Client
* @param tc reason why we are running right now
*/
static void
-process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ * Add a listen task with the scheduler for this server.
+ *
+ * @param server handle to our server for which we are adding the listen
+ * socket
+ */
+static void
+schedule_listen_task (struct GNUNET_SERVER_Handle *server)
{
- struct GNUNET_SERVER_Handle *server = cls;
- struct GNUNET_CONNECTION_Handle *sock;
- struct GNUNET_SERVER_Client *client;
struct GNUNET_NETWORK_FDSet *r;
unsigned int i;
- server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+ if (NULL == server->listen_sockets[0])
+ return; /* nothing to do, no listen sockets! */
+ if (NULL == server->listen_sockets[1])
+ {
+ /* simplified method: no fd set needed; this is then much simpler and
+ much more efficient */
+ server->listen_task =
+ GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_SCHEDULER_PRIORITY_HIGH,
+ server->listen_sockets[0],
+ &process_listen_socket, server);
+ return;
+ }
r = GNUNET_NETWORK_fdset_create ();
i = 0;
while (NULL != server->listen_sockets[i])
GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
+ server->listen_task =
+ GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+ GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+ &process_listen_socket, server);
+ GNUNET_NETWORK_fdset_destroy (r);
+}
+
+
+/**
+ * Scheduler says our listen socket is ready. Process it!
+ *
+ * @param cls handle to our server for which we are processing the listen
+ * socket
+ * @param tc reason why we are running right now
+ */
+static void
+process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_SERVER_Handle *server = cls;
+ struct GNUNET_CONNECTION_Handle *sock;
+ struct GNUNET_SERVER_Client *client;
+ unsigned int i;
+
+ server->listen_task = GNUNET_SCHEDULER_NO_TASK;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
/* ignore shutdown, someone else will take care of it! */
- server->listen_task =
- GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
- &process_listen_socket, server);
- GNUNET_NETWORK_fdset_destroy (r);
+ schedule_listen_task (server);
return;
}
i = 0;
@@ -306,14 +401,10 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CONNECTION_create_from_accept (server->access,
server->access_cls,
server->listen_sockets[i]);
- if (sock != NULL)
+ if (NULL != sock)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Server accepted incoming connection.\n");
-#endif
client = GNUNET_SERVER_connect_socket (server, sock);
- GNUNET_CONNECTION_ignore_shutdown (sock,
- server->clients_ignore_shutdown);
/* decrement reference count, we don't keep "client" alive */
GNUNET_SERVER_client_drop (client);
}
@@ -321,12 +412,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
i++;
}
/* listen for more! */
- server->listen_task =
- GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
- &process_listen_socket, server);
- GNUNET_NETWORK_fdset_destroy (r);
+ schedule_listen_task (server);
}
@@ -340,7 +426,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static struct GNUNET_NETWORK_Handle *
open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
{
- const static int on = 1;
+ static int on = 1;
struct GNUNET_NETWORK_Handle *sock;
uint16_t port;
int eno;
@@ -368,14 +454,14 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
errno = 0;
return NULL;
}
- if (port != 0)
+ if (0 != port)
{
if (GNUNET_NETWORK_socket_setsockopt
(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"setsockopt");
#ifdef IPV6_V6ONLY
- if ((serverAddr->sa_family == AF_INET6) &&
+ if ((AF_INET6 == serverAddr->sa_family) &&
(GNUNET_NETWORK_socket_setsockopt
(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -383,30 +469,30 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
#endif
}
/* bind the socket */
- if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK)
+ if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen))
{
eno = errno;
- if (errno != EADDRINUSE)
+ if (EADDRINUSE != errno)
{
/* we don't log 'EADDRINUSE' here since an IPv4 bind may
* fail if we already took the port on IPv6; if both IPv4 and
* IPv6 binds fail, then our caller will log using the
* errno preserved in 'eno' */
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
- if (port != 0)
+ if (0 != port)
LOG (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed for port %d (%s).\n"),
"bind", port,
- (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
+ (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6");
eno = 0;
}
else
{
- if (port != 0)
+ if (0 != port)
LOG (GNUNET_ERROR_TYPE_WARNING,
_("`%s' failed for port %d (%s): address already in use\n"),
"bind", port,
- (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
- else if (serverAddr->sa_family == AF_UNIX)
+ (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6");
+ else if (AF_UNIX == serverAddr->sa_family)
LOG (GNUNET_ERROR_TYPE_WARNING,
_("`%s' failed for `%s': address already in use\n"), "bind",
((const struct sockaddr_un *) serverAddr)->sun_path);
@@ -423,11 +509,9 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
errno = 0;
return NULL;
}
-#if DEBUG_SERVER
- if (port != 0)
+ if (0 != port)
LOG (GNUNET_ERROR_TYPE_DEBUG, "Server starts to listen on port %u.\n",
port);
-#endif
return sock;
}
@@ -451,30 +535,17 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
struct GNUNET_TIME_Relative idle_timeout,
int require_found)
{
- struct GNUNET_SERVER_Handle *ret;
- struct GNUNET_NETWORK_FDSet *r;
- int i;
-
- ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
- ret->idle_timeout = idle_timeout;
- ret->listen_sockets = lsocks;
- ret->access = access;
- ret->access_cls = access_cls;
- ret->require_found = require_found;
- if (lsocks != NULL)
- {
- r = GNUNET_NETWORK_fdset_create ();
- i = 0;
- while (NULL != ret->listen_sockets[i])
- GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
- ret->listen_task =
- GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
- &process_listen_socket, ret);
- GNUNET_NETWORK_fdset_destroy (r);
- }
- return ret;
+ struct GNUNET_SERVER_Handle *server;
+
+ server = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
+ server->idle_timeout = idle_timeout;
+ server->listen_sockets = lsocks;
+ server->access = access;
+ server->access_cls = access_cls;
+ server->require_found = require_found;
+ if (NULL != lsocks)
+ schedule_listen_task (server);
+ return server;
}
@@ -501,25 +572,41 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
struct GNUNET_NETWORK_Handle **lsocks;
unsigned int i;
unsigned int j;
+ unsigned int k;
+ int seen;
i = 0;
- while (serverAddr[i] != NULL)
+ while (NULL != serverAddr[i])
i++;
if (i > 0)
{
lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
i = 0;
j = 0;
- while (serverAddr[i] != NULL)
+ while (NULL != serverAddr[i])
{
+ seen = 0;
+ for (k=0;k<i;k++)
+ if ( (socklen[k] == socklen[i]) &&
+ (0 == memcmp (serverAddr[k], serverAddr[i], socklen[i])) )
+ {
+ seen = 1;
+ break;
+ }
+ if (0 != seen)
+ {
+ /* duplicate address, skip */
+ i++;
+ continue;
+ }
lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
- if (lsocks[j] != NULL)
+ if (NULL != lsocks[j])
j++;
i++;
}
- if (j == 0)
+ if (0 == j)
{
- if (errno != 0)
+ if (0 != errno)
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
GNUNET_free (lsocks);
lsocks = NULL;
@@ -535,48 +622,137 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
/**
+ * Set the 'monitor' flag on this client. Clients which have been
+ * marked as 'monitors' won't prevent the server from shutting down
+ * once 'GNUNET_SERVER_stop_listening' has been invoked. The idea is
+ * that for "normal" clients we likely want to allow them to process
+ * their requests; however, monitor-clients are likely to 'never'
+ * disconnect during shutdown and thus will not be considered when
+ * determining if the server should continue to exist after
+ * 'GNUNET_SERVER_destroy' has been called.
+ *
+ * @param client the client to set the 'monitor' flag on
+ */
+void
+GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
+{
+ client->is_monitor = GNUNET_YES;
+}
+
+
+/**
+ * Helper function for 'test_monitor_clients' to trigger
+ * 'GNUNET_SERVER_destroy' after the stack has unwound.
+ *
+ * @param cls the 'struct GNUNET_SERVER_Handle' to destroy
+ * @param tc unused
+ */
+static void
+do_destroy (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_SERVER_Handle *server = cls;
+ GNUNET_SERVER_destroy (server);
+}
+
+
+/**
+ * Check if only 'monitor' clients are left. If so, destroy the
+ * server completely.
+ *
+ * @param server server to test for full shutdown
+ */
+static void
+test_monitor_clients (struct GNUNET_SERVER_Handle *server)
+{
+ struct GNUNET_SERVER_Client *client;
+
+ if (GNUNET_YES != server->in_soft_shutdown)
+ return;
+ for (client = server->clients_head; NULL != client; client = client->next)
+ if (GNUNET_NO == client->is_monitor)
+ return; /* not done yet */
+ server->in_soft_shutdown = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_add_continuation (&do_destroy, server,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+/**
+ * Stop the listen socket and get ready to shutdown the server
+ * once only 'monitor' clients are left.
+ *
+ * @param server server to stop listening on
+ */
+void
+GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server)
+{
+ unsigned int i;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Server in soft shutdown\n");
+ if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
+ {
+ GNUNET_SCHEDULER_cancel (server->listen_task);
+ server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != server->listen_sockets)
+ {
+ i = 0;
+ while (NULL != server->listen_sockets[i])
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
+ GNUNET_free (server->listen_sockets);
+ server->listen_sockets = NULL;
+ }
+ if (GNUNET_NO == server->in_soft_shutdown)
+ server->in_soft_shutdown = GNUNET_YES;
+ test_monitor_clients (server);
+}
+
+
+/**
* Free resources held by this server.
*
- * @param s server to destroy
+ * @param server server to destroy
*/
void
-GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
+GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
{
struct HandlerList *hpos;
struct NotifyList *npos;
unsigned int i;
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
-#endif
- if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
+ if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
{
- GNUNET_SCHEDULER_cancel (s->listen_task);
- s->listen_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_SCHEDULER_cancel (server->listen_task);
+ server->listen_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (s->listen_sockets != NULL)
+ if (NULL != server->listen_sockets)
{
i = 0;
- while (s->listen_sockets[i] != NULL)
+ while (NULL != server->listen_sockets[i])
GNUNET_break (GNUNET_OK ==
- GNUNET_NETWORK_socket_close (s->listen_sockets[i++]));
- GNUNET_free (s->listen_sockets);
- s->listen_sockets = NULL;
+ GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
+ GNUNET_free (server->listen_sockets);
+ server->listen_sockets = NULL;
}
- while (s->clients != NULL)
- GNUNET_SERVER_client_disconnect (s->clients);
- while (NULL != (hpos = s->handlers))
+ while (NULL != server->clients_head)
+ GNUNET_SERVER_client_disconnect (server->clients_head);
+ while (NULL != (hpos = server->handlers))
{
- s->handlers = hpos->next;
+ server->handlers = hpos->next;
GNUNET_free (hpos);
}
- while (NULL != (npos = s->disconnect_notify_list))
+ while (NULL != (npos = server->disconnect_notify_list_head))
{
npos->callback (npos->callback_cls, NULL);
- s->disconnect_notify_list = npos->next;
+ GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
+ server->disconnect_notify_list_tail,
+ npos);
GNUNET_free (npos);
}
- GNUNET_free (s);
+ GNUNET_free (server);
}
@@ -606,6 +782,16 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
}
+/**
+ * Change functions used by the server to tokenize the message stream.
+ * (very rarely used).
+ *
+ * @param server server to modify
+ * @param create new tokenizer initialization function
+ * @param destroy new tokenizer destruction function
+ * @param receive new tokenizer receive function
+ * @param cls closure for 'create', 'receive', 'destroy'
+ */
void
GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
GNUNET_SERVER_MstCreateCallback create,
@@ -631,6 +817,7 @@ warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_SERVER_Client *client = cls;
+ GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
client->warn_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
&warn_no_receive_done, client);
@@ -691,15 +878,11 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
type = ntohs (message->type);
size = ntohs (message->size);
-#if DEBUG_SERVER
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server schedules transmission of %u-byte message of type %u to client.\n",
size, type);
-#endif
- pos = server->handlers;
found = GNUNET_NO;
- while (pos != NULL)
+ for (pos = server->handlers; NULL != pos; pos = pos->next)
{
i = 0;
while (pos->handlers[i].callback != NULL)
@@ -707,7 +890,7 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
mh = &pos->handlers[i];
if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
{
- if ((mh->expected_size != 0) && (mh->expected_size != size))
+ if ((0 != mh->expected_size) && (mh->expected_size != size))
{
#if GNUNET8_NETWORK_IS_DEAD
LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -717,11 +900,13 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
#endif
return GNUNET_SYSERR;
}
- if (sender != NULL)
+ if (NULL != sender)
{
- if (0 == sender->suspended)
+ if ( (0 == sender->suspended) &&
+ (GNUNET_SCHEDULER_NO_TASK == sender->warn_task) )
{
- sender->warn_start = GNUNET_TIME_absolute_get ();
+ GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
+ sender->warn_start = GNUNET_TIME_absolute_get ();
sender->warn_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
&warn_no_receive_done, sender);
@@ -734,13 +919,12 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
}
i++;
}
- pos = pos->next;
}
- if (found == GNUNET_NO)
+ if (GNUNET_NO == found)
{
LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
"Received message of unknown type %d\n", type);
- if (server->require_found == GNUNET_YES)
+ if (GNUNET_YES == server->require_found)
return GNUNET_SYSERR;
}
return GNUNET_OK;
@@ -778,28 +962,24 @@ process_incoming (void *cls, const void *buf, size_t available,
static void
process_mst (struct GNUNET_SERVER_Client *client, int ret)
{
- while ((ret != GNUNET_SYSERR) && (client->server != NULL) &&
+ while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
(GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
{
- if (ret == GNUNET_OK)
+ if (GNUNET_OK == ret)
{
- client->receive_pending = GNUNET_YES;
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server re-enters receive loop, timeout: %llu.\n",
client->idle_timeout.rel_value);
-#endif
+ client->receive_pending = GNUNET_YES;
GNUNET_CONNECTION_receive (client->connection,
GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
client->idle_timeout, &process_incoming,
client);
break;
}
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server processes additional messages instantly.\n");
-#endif
- if (client->server->mst_receive != NULL)
+ if (NULL != client->server->mst_receive)
ret =
client->server->mst_receive (client->server->mst_cls, client->mst,
client, NULL, 0, GNUNET_NO, GNUNET_YES);
@@ -808,23 +988,17 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
GNUNET_YES);
}
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
ret, client->server, client->shutdown_now, client->suspended);
-#endif
-
- if (ret == GNUNET_NO)
+ if (GNUNET_NO == ret)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server has more data pending but is suspended.\n");
-#endif
client->receive_pending = GNUNET_SYSERR; /* data pending */
}
- if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now))
+ if ((GNUNET_SYSERR == ret) || (GNUNET_YES == client->shutdown_now))
GNUNET_SERVER_client_disconnect (client);
- GNUNET_SERVER_client_drop (client);
}
@@ -848,22 +1022,20 @@ process_incoming (void *cls, const void *buf, size_t available,
struct GNUNET_TIME_Absolute now;
int ret;
- GNUNET_assert (client->receive_pending == GNUNET_YES);
+ GNUNET_assert (GNUNET_YES == client->receive_pending);
client->receive_pending = GNUNET_NO;
now = GNUNET_TIME_absolute_get ();
end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout);
- if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) &&
- (client->shutdown_now != GNUNET_YES) && (server != NULL) &&
+ if ((NULL == buf) && (0 == available) && (NULL == addr) && (0 == errCode) &&
+ (GNUNET_YES != client->shutdown_now) && (NULL != server) &&
(GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
(end.abs_value > now.abs_value))
{
/* wait longer, timeout changed (i.e. due to us sending) */
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Receive time out, but no disconnect due to sending (%p)\n",
GNUNET_a2s (addr, addrlen));
-#endif
client->receive_pending = GNUNET_YES;
GNUNET_CONNECTION_receive (client->connection,
GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
@@ -871,31 +1043,37 @@ process_incoming (void *cls, const void *buf, size_t available,
&process_incoming, client);
return;
}
- if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) ||
- (client->shutdown_now == GNUNET_YES) ||
+ if ((NULL == buf) || (0 == available) || (0 != errCode) || (NULL == server) ||
+ (GNUNET_YES == client->shutdown_now) ||
(GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
{
/* other side closed connection, error connecting, etc. */
GNUNET_SERVER_client_disconnect (client);
return;
}
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n",
(unsigned int) available, GNUNET_a2s (addr, addrlen));
-#endif
GNUNET_SERVER_client_keep (client);
client->last_activity = now;
- if (server->mst_receive != NULL)
+ if (NULL != server->mst_receive)
ret =
client->server->mst_receive (client->server->mst_cls, client->mst,
client, buf, available, GNUNET_NO, GNUNET_YES);
- else
+ else if (NULL != client->mst)
+ {
ret =
GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO,
GNUNET_YES);
+ }
+ else
+ {
+ GNUNET_break (0);
+ return;
+ }
process_mst (client, ret);
+ GNUNET_SERVER_client_drop (client);
}
@@ -910,33 +1088,24 @@ static void
restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_SERVER_Client *client = cls;
- struct GNUNET_SERVER_Handle *server = client->server;
+ GNUNET_assert (GNUNET_YES != client->shutdown_now);
client->restart_task = GNUNET_SCHEDULER_NO_TASK;
- if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
- (GNUNET_NO == server->clients_ignore_shutdown))
- {
- GNUNET_SERVER_client_disconnect (client);
- return;
- }
- if (client->receive_pending == GNUNET_NO)
+ if (GNUNET_NO == client->receive_pending)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
-#endif
client->receive_pending = GNUNET_YES;
GNUNET_CONNECTION_receive (client->connection,
GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
client->idle_timeout, &process_incoming, client);
return;
}
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server continues processing messages still in the buffer.\n");
-#endif
GNUNET_SERVER_client_keep (client);
client->receive_pending = GNUNET_NO;
process_mst (client, GNUNET_NO);
+ GNUNET_SERVER_client_drop (client);
}
@@ -947,8 +1116,10 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
* @param cls closure (struct GNUNET_SERVER_Handle)
* @param client identification of the client (struct GNUNET_SERVER_Client*)
* @param message the actual message
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
*/
-static void
+static int
client_message_tokenizer_callback (void *cls, void *client,
const struct GNUNET_MessageHeader *message)
{
@@ -956,17 +1127,18 @@ client_message_tokenizer_callback (void *cls, void *client,
struct GNUNET_SERVER_Client *sender = client;
int ret;
-#if DEBUG_SERVER
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Tokenizer gives server message of type %u from client\n",
ntohs (message->type));
-#endif
sender->in_process_client_buffer = GNUNET_YES;
ret = GNUNET_SERVER_inject (server, sender, message);
sender->in_process_client_buffer = GNUNET_NO;
- if (GNUNET_OK != ret)
+ if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
+ {
GNUNET_SERVER_client_disconnect (sender);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
}
@@ -990,25 +1162,21 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
client->connection = connection;
- client->mst =
- GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server);
client->reference_count = 1;
client->server = server;
client->last_activity = GNUNET_TIME_absolute_get ();
- client->next = server->clients;
client->idle_timeout = server->idle_timeout;
- server->clients = client;
- client->receive_pending = GNUNET_YES;
- client->callback = NULL;
- client->callback_cls = NULL;
-
- if (server->mst_create != NULL)
+ GNUNET_CONTAINER_DLL_insert (server->clients_head,
+ server->clients_tail,
+ client);
+ if (NULL != server->mst_create)
client->mst =
server->mst_create (server->mst_cls, client);
else
client->mst =
GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server);
-
+ GNUNET_assert (NULL != client->mst);
+ client->receive_pending = GNUNET_YES;
GNUNET_CONNECTION_receive (client->connection,
GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
client->idle_timeout, &process_incoming, client);
@@ -1032,14 +1200,6 @@ GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
}
-void
-GNUNET_SERVER_client_set_finish_pending_write (struct GNUNET_SERVER_Client *client,
- int finish)
-{
- client->finish_pending_write = finish;
-}
-
-
/**
* Notify the server that the given client handle should
* be kept (keeps the connection up if possible, increments
@@ -1067,7 +1227,7 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
{
GNUNET_assert (client->reference_count > 0);
client->reference_count--;
- if ((client->shutdown_now == GNUNET_YES) && (client->reference_count == 0))
+ if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
GNUNET_SERVER_client_disconnect (client);
}
@@ -1108,8 +1268,9 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
n = GNUNET_malloc (sizeof (struct NotifyList));
n->callback = callback;
n->callback_cls = callback_cls;
- n->next = server->disconnect_notify_list;
- server->disconnect_notify_list = n;
+ GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
+ server->disconnect_notify_list_tail,
+ n);
}
@@ -1126,31 +1287,42 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
callback, void *callback_cls)
{
struct NotifyList *pos;
- struct NotifyList *prev;
- prev = NULL;
- pos = server->disconnect_notify_list;
- while (pos != NULL)
- {
+ for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
break;
- prev = pos;
- pos = pos->next;
- }
- if (pos == NULL)
+ if (NULL == pos)
{
GNUNET_break (0);
return;
}
- if (prev == NULL)
- server->disconnect_notify_list = pos->next;
- else
- prev->next = pos->next;
+ GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
+ server->disconnect_notify_list_tail,
+ pos);
GNUNET_free (pos);
}
/**
+ * Destroy the connection that is passed in via 'cls'. Used
+ * as calling 'GNUNET_CONNECTION_destroy' from within a function
+ * that was itself called from within 'process_notify' of
+ * 'connection.c' is not allowed (see #2329).
+ *
+ * @param cls connection to destroy
+ * @param tc scheduler context (unused)
+ */
+static void
+destroy_connection (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_CONNECTION_Handle *connection = cls;
+
+ GNUNET_CONNECTION_destroy (connection);
+}
+
+
+/**
* Ask the server to disconnect from the given client.
* This is the same as returning GNUNET_SYSERR from a message
* handler, except that it allows dropping of a client even
@@ -1161,22 +1333,17 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
void
GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
{
- struct GNUNET_SERVER_Client *prev;
- struct GNUNET_SERVER_Client *pos;
- struct GNUNET_SERVER_Handle *server;
+ struct GNUNET_SERVER_Handle *server = client->server;
struct NotifyList *n;
- unsigned int rc;
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Client is being disconnected from the server.\n");
-#endif
- if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != client->restart_task)
{
GNUNET_SCHEDULER_cancel (client->restart_task);
client->restart_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
{
GNUNET_SCHEDULER_cancel (client->warn_task);
client->warn_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1186,68 +1353,58 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
GNUNET_CONNECTION_receive_cancel (client->connection);
client->receive_pending = GNUNET_NO;
}
-
- rc = client->reference_count;
- if (client->shutdown_now != GNUNET_YES)
+ client->shutdown_now = GNUNET_YES;
+ client->reference_count++; /* make sure nobody else clean up client... */
+ if ( (NULL != client->mst) &&
+ (NULL != server) )
{
- server = client->server;
- client->shutdown_now = GNUNET_YES;
- prev = NULL;
- pos = server->clients;
- while ((pos != NULL) && (pos != client))
- {
- prev = pos;
- pos = pos->next;
- }
- GNUNET_assert (pos != NULL);
- if (prev == NULL)
- server->clients = pos->next;
+ GNUNET_CONTAINER_DLL_remove (server->clients_head,
+ server->clients_tail,
+ client);
+ if (NULL != server->mst_destroy)
+ server->mst_destroy (server->mst_cls, client->mst);
else
- prev->next = pos->next;
- if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (client->restart_task);
- client->restart_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (client->warn_task);
- client->warn_task = GNUNET_SCHEDULER_NO_TASK;
- }
- n = server->disconnect_notify_list;
- while (n != NULL)
- {
+ GNUNET_SERVER_mst_destroy (client->mst);
+ client->mst = NULL;
+ for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
n->callback (n->callback_cls, client);
- n = n->next;
- }
}
- if (rc > 0)
+ client->reference_count--;
+ if (client->reference_count > 0)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"RC still positive, not destroying everything.\n");
-#endif
+ client->server = NULL;
return;
}
- if (client->in_process_client_buffer == GNUNET_YES)
+ if (GNUNET_YES == client->in_process_client_buffer)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Still processing inputs, not destroying everything.\n");
-#endif
return;
}
-
- if (client->persist == GNUNET_YES)
+ if (GNUNET_YES == client->persist)
GNUNET_CONNECTION_persist_ (client->connection);
- GNUNET_CONNECTION_destroy (client->connection, client->finish_pending_write);
-
- if (client->server->mst_destroy != NULL)
- client->server->mst_destroy (client->server->mst_cls, client->mst);
- else
- GNUNET_SERVER_mst_destroy (client->mst);
-
+ if (NULL != client->th.cth)
+ GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
+ (void) GNUNET_SCHEDULER_add_now (&destroy_connection,
+ client->connection);
+ /* need to cancel again, as it might have been re-added
+ in the meantime (i.e. during callbacks) */
+ if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
+ {
+ GNUNET_SCHEDULER_cancel (client->warn_task);
+ client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (GNUNET_YES == client->receive_pending)
+ {
+ GNUNET_CONNECTION_receive_cancel (client->connection);
+ client->receive_pending = GNUNET_NO;
+ }
GNUNET_free (client);
+ /* we might be in soft-shutdown, test if we're done */
+ if (NULL != server)
+ test_monitor_clients (server);
}
@@ -1279,12 +1436,13 @@ static size_t
transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
{
struct GNUNET_SERVER_Client *client = cls;
- size_t ret;
+ GNUNET_CONNECTION_TransmitReadyNotify callback;
- ret = client->callback (client->callback_cls, size, buf);
- if (ret > 0)
- client->last_activity = GNUNET_TIME_absolute_get ();
- return ret;
+ client->th.cth = NULL;
+ callback = client->th.callback;
+ client->th.callback = NULL;
+ client->last_activity = GNUNET_TIME_absolute_get ();
+ return callback (client->th.callback_cls, size, buf);
}
@@ -1300,22 +1458,39 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
* @param callback_cls closure for callback
* @return non-NULL if the notify callback was queued; can be used
* to cancel the request using
- * GNUNET_CONNECTION_notify_transmit_ready_cancel.
+ * GNUNET_SERVER_notify_transmit_ready_cancel.
* NULL if we are already going to notify someone else (busy)
*/
-struct GNUNET_CONNECTION_TransmitHandle *
+struct GNUNET_SERVER_TransmitHandle *
GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
size_t size,
struct GNUNET_TIME_Relative timeout,
GNUNET_CONNECTION_TransmitReadyNotify
callback, void *callback_cls)
{
- client->callback_cls = callback_cls;
- client->callback = callback;
- return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
- timeout,
- &transmit_ready_callback_wrapper,
- client);
+ if (NULL != client->th.callback)
+ return NULL;
+ client->th.callback_cls = callback_cls;
+ client->th.callback = callback;
+ client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
+ timeout,
+ &transmit_ready_callback_wrapper,
+ client);
+ return &client->th;
+}
+
+
+/**
+ * Abort transmission request.
+ *
+ * @param th request to abort
+ */
+void
+GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
+{
+ GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth);
+ th->cth = NULL;
+ th->callback = NULL;
}
@@ -1347,25 +1522,24 @@ GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
void
GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
{
- if (client == NULL)
+ if (NULL == client)
return;
GNUNET_assert (client->suspended > 0);
client->suspended--;
- if (success != GNUNET_OK)
+ if (GNUNET_OK != success)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"GNUNET_SERVER_receive_done called with failure indication\n");
-#endif
- GNUNET_SERVER_client_disconnect (client);
+ if ( (client->reference_count > 0) || (client->suspended > 0) )
+ client->shutdown_now = GNUNET_YES;
+ else
+ GNUNET_SERVER_client_disconnect (client);
return;
}
if (client->suspended > 0)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"GNUNET_SERVER_receive_done called, but more clients pending\n");
-#endif
return;
}
if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
@@ -1373,43 +1547,22 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
GNUNET_SCHEDULER_cancel (client->warn_task);
client->warn_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (client->in_process_client_buffer == GNUNET_YES)
+ if (GNUNET_YES == client->in_process_client_buffer)
{
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"GNUNET_SERVER_receive_done called while still in processing loop\n");
-#endif
return;
}
- if ((client->server == NULL) || (GNUNET_YES == client->shutdown_now))
+ if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
{
GNUNET_SERVER_client_disconnect (client);
return;
}
-#if DEBUG_SERVER
LOG (GNUNET_ERROR_TYPE_DEBUG,
"GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
-#endif
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client);
}
-/**
- * Configure this server's connections to continue handling client
- * requests as usual even after we get a shutdown signal. The change
- * only applies to clients that connect to the server from the outside
- * using TCP after this call. Clients managed previously or those
- * added using GNUNET_SERVER_connect_socket and
- * GNUNET_SERVER_connect_callback are not affected by this option.
- *
- * @param h server handle
- * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default
- */
-void
-GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore)
-{
- h->clients_ignore_shutdown = do_ignore;
-}
-
/* end of server.c */
diff --git a/src/util/server_mst.c b/src/util/server_mst.c
index 6161770..9dd04f0 100644
--- a/src/util/server_mst.c
+++ b/src/util/server_mst.c
@@ -31,7 +31,6 @@
#include "gnunet_server_lib.h"
#include "gnunet_time_lib.h"
-#define DEBUG_SERVER_MST GNUNET_EXTRA_LOGGING
#if HAVE_UNALIGNED_64_ACCESS
#define ALIGN_FACTOR 4
@@ -134,11 +133,9 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
GNUNET_assert (mst->off <= mst->pos);
GNUNET_assert (mst->pos <= mst->curr_buf);
-#if DEBUG_SERVER_MST
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server-mst receives %u bytes with %u bytes already in private buffer\n",
(unsigned int) size, (unsigned int) (mst->pos - mst->off));
-#endif
ret = GNUNET_OK;
ibuf = (char *) mst->hdr;
while (mst->pos > 0)
@@ -224,7 +221,8 @@ do_align:
if (one_shot == GNUNET_YES)
one_shot = GNUNET_SYSERR;
mst->off += want;
- mst->cb (mst->cb_cls, client_identity, hdr);
+ if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
+ return GNUNET_SYSERR;
if (mst->off == mst->pos)
{
/* reset to beginning of buffer, it's free right now! */
@@ -235,11 +233,9 @@ do_align:
GNUNET_assert (0 == mst->pos);
while (size > 0)
{
-#if DEBUG_SERVER_MST
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server-mst has %u bytes left in inbound buffer\n",
(unsigned int) size);
-#endif
if (size < sizeof (struct GNUNET_MessageHeader))
break;
offset = (unsigned long) buf;
@@ -266,7 +262,8 @@ do_align:
}
if (one_shot == GNUNET_YES)
one_shot = GNUNET_SYSERR;
- mst->cb (mst->cb_cls, client_identity, hdr);
+ if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
+ return GNUNET_SYSERR;
buf += want;
size -= want;
}
@@ -295,11 +292,9 @@ copy:
mst->off = 0;
mst->pos = 0;
}
-#if DEBUG_SERVER_MST
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Server-mst leaves %u bytes in private buffer\n",
(unsigned int) (mst->pos - mst->off));
-#endif
return ret;
}
diff --git a/src/util/server_nc.c b/src/util/server_nc.c
index 08ffd4b..6e0181e 100644
--- a/src/util/server_nc.c
+++ b/src/util/server_nc.c
@@ -36,8 +36,6 @@
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
-#define DEBUG_SERVER_NC GNUNET_EXTRA_LOGGING
-
/**
* Entry in list of messages pending to be transmitted.
*/
@@ -75,11 +73,16 @@ struct ClientList
{
/**
- * This is a linked list.
+ * This is a doubly linked list.
*/
struct ClientList *next;
/**
+ * This is a doubly linked list.
+ */
+ struct ClientList *prev;
+
+ /**
* Overall context this client belongs to.
*/
struct GNUNET_SERVER_NotificationContext *nc;
@@ -92,7 +95,7 @@ struct ClientList
/**
* Handle for pending transmission request to the client (or NULL).
*/
- struct GNUNET_CONNECTION_TransmitHandle *th;
+ struct GNUNET_SERVER_TransmitHandle *th;
/**
* Head of linked list of requests queued for transmission.
@@ -129,9 +132,14 @@ struct GNUNET_SERVER_NotificationContext
struct GNUNET_SERVER_Handle *server;
/**
- * List of clients receiving notifications.
+ * Head of list of clients receiving notifications.
*/
- struct ClientList *clients;
+ struct ClientList *clients_head;
+
+ /**
+ * Tail of list of clients receiving notifications.
+ */
+ struct ClientList *clients_tail;
/**
* Maximum number of optional messages to queue per client.
@@ -152,45 +160,37 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
{
struct GNUNET_SERVER_NotificationContext *nc = cls;
struct ClientList *pos;
- struct ClientList *prev;
struct PendingMessageList *pml;
- if (client == NULL)
+ if (NULL == client)
{
nc->server = NULL;
return;
}
- prev = NULL;
- pos = nc->clients;
- while (NULL != pos)
- {
+ for (pos = nc->clients_head; NULL != pos; pos = pos->next)
if (pos->client == client)
break;
- prev = pos;
- pos = pos->next;
- }
- if (pos == NULL)
+ if (NULL == pos)
return;
-#if DEBUG_SERVER_NC
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Client disconnected, cleaning up %u messages in NC queue\n",
pos->num_pending);
-#endif
- if (prev == NULL)
- nc->clients = pos->next;
- else
- prev->next = pos->next;
+ GNUNET_CONTAINER_DLL_remove (nc->clients_head,
+ nc->clients_tail,
+ pos);
while (NULL != (pml = pos->pending_head))
{
GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, pml);
GNUNET_free (pml);
+ pos->num_pending--;
}
- if (pos->th != NULL)
+ if (NULL != pos->th)
{
- GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th);
+ GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
pos->th = NULL;
}
GNUNET_SERVER_client_drop (client);
+ GNUNET_assert (0 == pos->num_pending);
GNUNET_free (pos);
}
@@ -231,18 +231,27 @@ GNUNET_SERVER_notification_context_destroy (struct
struct ClientList *pos;
struct PendingMessageList *pml;
- while (NULL != (pos = nc->clients))
+ while (NULL != (pos = nc->clients_head))
{
- nc->clients = pos->next;
+ GNUNET_CONTAINER_DLL_remove (nc->clients_head,
+ nc->clients_tail,
+ pos);
+ if (NULL != pos->th)
+ {
+ GNUNET_SERVER_notify_transmit_ready_cancel(pos->th);
+ pos->th = NULL;
+ }
GNUNET_SERVER_client_drop (pos->client);
while (NULL != (pml = pos->pending_head))
{
GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, pml);
GNUNET_free (pml);
+ pos->num_pending--;
}
+ GNUNET_assert (0 == pos->num_pending);
GNUNET_free (pos);
}
- if (nc->server != NULL)
+ if (NULL != nc->server)
GNUNET_SERVER_disconnect_notify_cancel (nc->server,
&handle_client_disconnect, nc);
GNUNET_free (nc);
@@ -262,15 +271,16 @@ GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext
{
struct ClientList *cl;
- for (cl = nc->clients; NULL != cl; cl = cl->next)
+ for (cl = nc->clients_head; NULL != cl; cl = cl->next)
if (cl->client == client)
return; /* already present */
cl = GNUNET_malloc (sizeof (struct ClientList));
- cl->next = nc->clients;
+ GNUNET_CONTAINER_DLL_insert (nc->clients_head,
+ nc->clients_tail,
+ cl);
cl->nc = nc;
cl->client = client;
GNUNET_SERVER_client_keep (client);
- nc->clients = cl;
}
@@ -294,13 +304,11 @@ transmit_message (void *cls, size_t size, void *buf)
size_t ret;
cl->th = NULL;
- if (buf == NULL)
+ if (NULL == buf)
{
/* 'cl' should be freed via disconnect notification shortly */
-#if DEBUG_SERVER_NC
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Failed to transmit message from NC queue to client\n");
-#endif
return 0;
}
ret = 0;
@@ -310,31 +318,29 @@ transmit_message (void *cls, size_t size, void *buf)
if (size < msize)
break;
GNUNET_CONTAINER_DLL_remove (cl->pending_head, cl->pending_tail, pml);
-#if DEBUG_SERVER_NC
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Copying message of type %u and size %u from pending queue to transmission buffer\n",
ntohs (pml->msg->type), msize);
-#endif
memcpy (&cbuf[ret], pml->msg, msize);
ret += msize;
size -= msize;
GNUNET_free (pml);
cl->num_pending--;
}
- if (pml != NULL)
+ if (NULL != pml)
{
-#if DEBUG_SERVER_NC
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Have %u messages left in NC queue, will try transmission again\n",
cl->num_pending);
-#endif
cl->th =
GNUNET_SERVER_notify_transmit_ready (cl->client, ntohs (pml->msg->size),
GNUNET_TIME_UNIT_FOREVER_REL,
&transmit_message, cl);
}
else
- GNUNET_assert (cl->num_pending == 0);
+ {
+ GNUNET_assert (0 == cl->num_pending);
+ }
return ret;
}
@@ -372,11 +378,9 @@ do_unicast (struct GNUNET_SERVER_NotificationContext *nc,
pml = GNUNET_malloc (sizeof (struct PendingMessageList) + size);
pml->msg = (const struct GNUNET_MessageHeader *) &pml[1];
pml->can_drop = can_drop;
-#if DEBUG_SERVER_NC
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Adding message of type %u and size %u to pending queue (which has %u entries)\n",
ntohs (msg->type), ntohs (msg->size), (unsigned int) nc->queue_length);
-#endif
memcpy (&pml[1], msg, size);
/* append */
GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail,
@@ -410,14 +414,10 @@ GNUNET_SERVER_notification_context_unicast (struct
{
struct ClientList *pos;
- pos = nc->clients;
- while (NULL != pos)
- {
+ for (pos = nc->clients_head; NULL != pos; pos = pos->next)
if (pos->client == client)
break;
- pos = pos->next;
- }
- GNUNET_assert (pos != NULL);
+ GNUNET_assert (NULL != pos);
do_unicast (nc, pos, msg, can_drop);
}
@@ -438,12 +438,8 @@ GNUNET_SERVER_notification_context_broadcast (struct
{
struct ClientList *pos;
- pos = nc->clients;
- while (NULL != pos)
- {
+ for (pos = nc->clients_head; NULL != pos; pos = pos->next)
do_unicast (nc, pos, msg, can_drop);
- pos = pos->next;
- }
}
diff --git a/src/util/server_tc.c b/src/util/server_tc.c
index ce40db1..f803af4 100644
--- a/src/util/server_tc.c
+++ b/src/util/server_tc.c
@@ -82,7 +82,7 @@ transmit_response (void *cls, size_t size, void *buf)
struct GNUNET_SERVER_TransmitContext *tc = cls;
size_t msize;
- if (buf == NULL)
+ if (NULL == buf)
{
GNUNET_SERVER_transmit_context_destroy (tc, GNUNET_SYSERR);
return 0;
@@ -95,7 +95,6 @@ transmit_response (void *cls, size_t size, void *buf)
tc->off += msize;
if (tc->total == tc->off)
{
-
GNUNET_SERVER_receive_done (tc->client, GNUNET_OK);
GNUNET_SERVER_client_drop (tc->client);
GNUNET_free_non_null (tc->buf);
@@ -131,7 +130,7 @@ GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client)
{
struct GNUNET_SERVER_TransmitContext *tc;
- GNUNET_assert (client != NULL);
+ GNUNET_assert (NULL != client);
tc = GNUNET_malloc (sizeof (struct GNUNET_SERVER_TransmitContext));
GNUNET_SERVER_client_keep (client);
tc->client = client;
diff --git a/src/util/service.c b/src/util/service.c
index 243e7da..6a6fb6c 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -42,7 +42,6 @@
#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
-#define DEBUG_SERVICE GNUNET_EXTRA_LOGGING
/* ******************* access control ******************** */
@@ -51,7 +50,14 @@
*/
struct IPv4NetworkSet
{
+ /**
+ * IPv4 address.
+ */
struct in_addr network;
+
+ /**
+ * IPv4 netmask.
+ */
struct in_addr netmask;
};
@@ -60,11 +66,25 @@ struct IPv4NetworkSet
*/
struct IPv6NetworkSet
{
+ /**
+ * IPv6 address.
+ */
struct in6_addr network;
+
+ /**
+ * IPv6 netmask.
+ */
struct in6_addr netmask;
};
+int
+GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+int
+GNUNET_SPEEDUP_stop_ (void);
+
+
/**
* Parse a network specification. The argument specifies
* a list of networks. The format is
@@ -72,7 +92,7 @@ struct IPv6NetworkSet
* with a semicolon). The network must be given in dotted-decimal
* notation. The netmask can be given in CIDR notation (/16) or
* in dotted-decimal (/255.255.0.0).
- * <p>
+ *
* @param routeList a string specifying the forbidden networks
* @return the converted list, NULL if the synatx is flawed
*/
@@ -89,27 +109,25 @@ parse_ipv4_specification (const char *routeList)
int slash;
struct IPv4NetworkSet *result;
- if (routeList == NULL)
+ if (NULL == routeList)
return NULL;
len = strlen (routeList);
- if (len == 0)
+ if (0 == len)
return NULL;
count = 0;
for (i = 0; i < len; i++)
if (routeList[i] == ';')
count++;
result = GNUNET_malloc (sizeof (struct IPv4NetworkSet) * (count + 1));
- /* add termination */
- memset (result, 0, sizeof (struct IPv4NetworkSet) * (count + 1));
i = 0;
pos = 0;
while (i < count)
{
cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0],
+ SSCANF (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0],
&temps[1], &temps[2], &temps[3], &temps[4], &temps[5],
&temps[6], &temps[7]);
- if (cnt == 8)
+ if (8 == cnt)
{
for (j = 0; j < 8; j++)
if (temps[j] > 0xFF)
@@ -133,9 +151,9 @@ parse_ipv4_specification (const char *routeList)
}
/* try second notation */
cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1],
+ SSCANF (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1],
&temps[2], &temps[3], &slash);
- if (cnt == 5)
+ if (5 == cnt)
{
for (j = 0; j < 4; j++)
if (temps[j] > 0xFF)
@@ -158,7 +176,7 @@ parse_ipv4_specification (const char *routeList)
slash--;
}
result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
- while (routeList[pos] != ';')
+ while (';' != routeList[pos])
pos++;
pos++;
i++;
@@ -176,9 +194,9 @@ parse_ipv4_specification (const char *routeList)
/* try third notation */
slash = 32;
cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1],
+ SSCANF (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1],
&temps[2], &temps[3]);
- if (cnt == 4)
+ if (4 == cnt)
{
for (j = 0; j < 4; j++)
if (temps[j] > 0xFF)
@@ -227,7 +245,7 @@ parse_ipv4_specification (const char *routeList)
* with a semicolon). The network must be given in colon-hex
* notation. The netmask must be given in CIDR notation (/16) or
* can be omitted to specify a single host.
- * <p>
+ *
* @param routeListX a string specifying the forbidden networks
* @return the converted list, NULL if the synatx is flawed
*/
@@ -247,17 +265,17 @@ parse_ipv6_specification (const char *routeListX)
unsigned int off;
int save;
- if (routeListX == NULL)
+ if (NULL == routeListX)
return NULL;
len = strlen (routeListX);
- if (len == 0)
+ if (0 == len)
return NULL;
routeList = GNUNET_strdup (routeListX);
count = 0;
for (i = 0; i < len; i++)
- if (routeList[i] == ';')
+ if (';' == routeList[i])
count++;
- if (routeList[len - 1] != ';')
+ if (';' != routeList[len - 1])
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Invalid network notation (does not end with ';': `%s')\n"),
@@ -267,13 +285,12 @@ parse_ipv6_specification (const char *routeListX)
}
result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1));
- memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1));
i = 0;
pos = 0;
while (i < count)
{
start = pos;
- while (routeList[pos] != ';')
+ while (';' != routeList[pos])
pos++;
slash = pos;
while ((slash >= start) && (routeList[slash] != '/'))
@@ -292,7 +309,7 @@ parse_ipv6_specification (const char *routeListX)
save = errno;
if ((1 != SSCANF (&routeList[slash + 1], "%u", &bits)) || (bits >= 128))
{
- if (ret == 0)
+ if (0 == ret)
LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong format `%s' for netmask\n"),
&routeList[slash + 1]);
else
@@ -322,7 +339,7 @@ parse_ipv6_specification (const char *routeListX)
ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
if (ret <= 0)
{
- if (ret == 0)
+ if (0 == ret)
LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong format `%s' for network\n"),
&routeList[slash + 1]);
else
@@ -349,12 +366,11 @@ parse_ipv6_specification (const char *routeListX)
static int
check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add)
{
- int i;
+ unsigned int i;
- i = 0;
- if (list == NULL)
+ if (NULL == list)
return GNUNET_NO;
-
+ i = 0;
while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
{
if ((add->s_addr & list[i].netmask.s_addr) ==
@@ -365,6 +381,7 @@ check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add)
return GNUNET_NO;
}
+
/**
* Check if the given IP address is in the list of IP addresses.
*
@@ -379,13 +396,12 @@ check_ipv6_listed (const struct IPv6NetworkSet *list, const struct in6_addr *ip)
unsigned int j;
struct in6_addr zero;
- if (list == NULL)
+ if (NULL == list)
return GNUNET_NO;
-
memset (&zero, 0, sizeof (struct in6_addr));
i = 0;
NEXT:
- while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0)
+ while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
{
for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
@@ -427,7 +443,7 @@ struct GNUNET_SERVICE_Context
/**
* Name of our service.
*/
- const char *serviceName;
+ const char *service_name;
/**
* Main service-specific task to run.
@@ -478,6 +494,11 @@ struct GNUNET_SERVICE_Context
struct GNUNET_NETWORK_Handle **lsocks;
/**
+ * Task ID of the shutdown task.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
+
+ /**
* Idle timeout for server.
*/
struct GNUNET_TIME_Relative timeout;
@@ -526,6 +547,14 @@ struct GNUNET_SERVICE_Context
/* ****************** message handlers ****************** */
+/**
+ * Send a 'TEST' message back to the client.
+ *
+ * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
+ * @param size number of bytes available in 'buf'
+ * @param buf where to copy the message
+ * @return number of bytes written to 'buf'
+ */
static size_t
write_test (void *cls, size_t size, void *buf)
{
@@ -544,6 +573,7 @@ write_test (void *cls, size_t size, void *buf)
return sizeof (struct GNUNET_MessageHeader);
}
+
/**
* Handler for TEST message.
*
@@ -577,7 +607,6 @@ static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
};
-
/* ****************** service core routines ************** */
@@ -605,31 +634,32 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
case AF_INET:
GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
i4 = (const struct sockaddr_in *) addr;
- ret = ((sctx->v4_allowed == NULL) ||
+ ret = ((NULL == sctx->v4_allowed) ||
(check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
- ((sctx->v4_denied == NULL) ||
+ ((NULL == sctx->v4_denied) ||
(!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
break;
case AF_INET6:
GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
i6 = (const struct sockaddr_in6 *) addr;
- ret = ((sctx->v6_allowed == NULL) ||
+ ret = ((NULL == sctx->v6_allowed) ||
(check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
- ((sctx->v6_denied == NULL) ||
+ ((NULL == sctx->v6_denied) ||
(!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
break;
#ifndef WINDOWS
case AF_UNIX:
ret = GNUNET_OK; /* always OK for now */
- if (sctx->match_uid == GNUNET_YES)
+ if (GNUNET_YES == sctx->match_uid)
{
/* UID match required */
- ret = (uc != NULL) && (uc->uid == geteuid ());
+ ret = (NULL != uc) && (uc->uid == geteuid ());
}
- else if (sctx->match_gid == GNUNET_YES)
+ else if ( (GNUNET_YES == sctx->match_gid) &&
+ ( (NULL == uc) || (uc->uid != geteuid ()) ) )
{
- /* group match required */
- if (uc == NULL)
+ /* group match required and UID does not match */
+ if (NULL == uc)
{
/* no credentials, group match not possible */
ret = GNUNET_NO;
@@ -666,7 +696,7 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
}
if (GNUNET_NO == ret)
LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"),
- (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid);
+ (NULL == uc) ? -1 : uc->uid, (NULL == uc) ? -1 : uc->gid);
break;
#endif
default:
@@ -674,12 +704,12 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
addr->sa_family);
return GNUNET_SYSERR;
}
- if (ret != GNUNET_OK)
+ if (GNUNET_OK != ret)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
- _("Access from `%s' denied to service `%s'\n"), GNUNET_a2s (addr,
- addrlen),
- sctx->serviceName);
+ _("Access from `%s' denied to service `%s'\n"),
+ GNUNET_a2s (addr, addrlen),
+ sctx->service_name);
}
return ret;
}
@@ -688,15 +718,17 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
/**
* Get the name of the file where we will
* write the PID of the service.
+ *
+ * @param sctx service context
+ * @return name of the file for the process ID
*/
static char *
get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
{
-
char *pif;
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
"PIDFILE", &pif))
return NULL;
return pif;
@@ -705,6 +737,12 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
/**
* Parse an IPv4 access control list.
+ *
+ * @param ret location where to write the ACL (set)
+ * @param sctx service context to use to get the configuration
+ * @param option name of the ACL option to parse
+ * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including
+ * no ACL configured)
*/
static int
process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
@@ -712,17 +750,20 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
{
char *opt;
- if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
+ if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
+ {
+ *ret = NULL;
return GNUNET_OK;
+ }
GNUNET_break (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
- sctx->serviceName,
+ sctx->service_name,
option, &opt));
if (NULL == (*ret = parse_ipv4_specification (opt)))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
_("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
- opt, sctx->serviceName, option);
+ opt, sctx->service_name, option);
GNUNET_free (opt);
return GNUNET_SYSERR;
}
@@ -732,7 +773,13 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
/**
- * Parse an IPv4 access control list.
+ * Parse an IPv6 access control list.
+ *
+ * @param ret location where to write the ACL (set)
+ * @param sctx service context to use to get the configuration
+ * @param option name of the ACL option to parse
+ * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including
+ * no ACL configured)
*/
static int
process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
@@ -740,17 +787,20 @@ process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
{
char *opt;
- if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
+ if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
+ {
+ *ret = NULL;
return GNUNET_OK;
+ }
GNUNET_break (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
- sctx->serviceName,
+ sctx->service_name,
option, &opt));
if (NULL == (*ret = parse_ipv6_specification (opt)))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
_("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
- opt, sctx->serviceName, option);
+ opt, sctx->service_name, option);
GNUNET_free (opt);
return GNUNET_SYSERR;
}
@@ -758,6 +808,7 @@ process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
return GNUNET_OK;
}
+
/**
* Add the given UNIX domain path as an address to the
* list (as the first entry).
@@ -802,7 +853,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
* Get the list of addresses that a server for the given service
* should bind to.
*
- * @param serviceName name of the service
+ * @param service_name name of the service
* @param cfg configuration (which specifies the addresses)
* @param addrs set (call by reference) to an array of pointers to the
* addresses the server should bind to and listen on; the
@@ -819,7 +870,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
* set to NULL).
*/
int
-GNUNET_SERVICE_get_server_addresses (const char *serviceName,
+GNUNET_SERVICE_get_server_addresses (const char *service_name,
const struct GNUNET_CONFIGURATION_Handle
*cfg, struct sockaddr ***addrs,
socklen_t ** addr_lens)
@@ -842,11 +893,11 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
*addrs = NULL;
*addr_lens = NULL;
desc = NULL;
- if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "DISABLEV6"))
+ if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
{
if (GNUNET_SYSERR ==
(disablev6 =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, serviceName, "DISABLEV6")))
+ GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
return GNUNET_SYSERR;
}
else
@@ -858,8 +909,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
if (NULL == desc)
{
- if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
- (errno == EACCES))
+ if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
+ (EACCES == errno))
{
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
return GNUNET_SYSERR;
@@ -867,7 +918,7 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
LOG (GNUNET_ERROR_TYPE_INFO,
_
("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
- serviceName, STRERROR (errno));
+ service_name, STRERROR (errno));
disablev6 = GNUNET_YES;
}
else
@@ -878,24 +929,24 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
}
port = 0;
- if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT"))
+ if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
{
GNUNET_break (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_number (cfg, serviceName,
+ GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
"PORT", &port));
if (port > 65535)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Require valid port number for service `%s' in configuration!\n"),
- serviceName);
+ service_name);
return GNUNET_SYSERR;
}
}
- if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO"))
+ if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
{
GNUNET_break (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cfg, serviceName,
+ GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
"BINDTO", &hostname));
}
else
@@ -904,9 +955,9 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
unixpath = NULL;
#ifdef AF_UNIX
if ((GNUNET_YES ==
- GNUNET_CONFIGURATION_have_value (cfg, serviceName, "UNIXPATH")) &&
+ GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
(GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, "UNIXPATH",
+ GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH",
&unixpath)) &&
(0 < strlen (unixpath)))
{
@@ -926,8 +977,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
if (NULL == desc)
{
- if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
- (errno == EACCES))
+ if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
+ (EACCES == errno))
{
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
GNUNET_free_non_null (hostname);
@@ -937,7 +988,7 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
LOG (GNUNET_ERROR_TYPE_INFO,
_
("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
- serviceName, STRERROR (errno));
+ service_name, STRERROR (errno));
GNUNET_free (unixpath);
unixpath = NULL;
}
@@ -949,16 +1000,16 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
}
#endif
- if ((port == 0) && (unixpath == NULL))
+ if ((0 == port) && (NULL == unixpath))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_
("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
- serviceName);
+ service_name);
GNUNET_free_non_null (hostname);
return GNUNET_SYSERR;
}
- if (port == 0)
+ if (0 == port)
{
saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
@@ -970,16 +1021,15 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
return 1;
}
- if (hostname != NULL)
+ if (NULL != hostname)
{
-#if DEBUG_SERVICE
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Resolving `%s' since that is where `%s' will bind to.\n", hostname,
- serviceName);
-#endif
+ service_name);
memset (&hints, 0, sizeof (struct addrinfo));
if (disablev6)
hints.ai_family = AF_INET;
+ hints.ai_protocol = IPPROTO_TCP;
if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
(res == NULL))
{
@@ -1022,19 +1072,17 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
while (NULL != (pos = next))
{
next = pos->ai_next;
- if ((disablev6) && (pos->ai_family == AF_INET6))
+ if ((disablev6) && (AF_INET6 == pos->ai_family))
continue;
- if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
+ if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
continue; /* not TCP */
- if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
+ if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
continue; /* huh? */
-#if DEBUG_SERVICE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
- serviceName, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
-#endif
- if (pos->ai_family == AF_INET)
+ service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
+ if (AF_INET == pos->ai_family)
{
- GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
+ GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
saddrlens[i] = pos->ai_addrlen;
saddrs[i] = GNUNET_malloc (saddrlens[i]);
memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
@@ -1042,8 +1090,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
}
else
{
- GNUNET_assert (pos->ai_family == AF_INET6);
- GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
+ GNUNET_assert (AF_INET6 == pos->ai_family);
+ GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
saddrlens[i] = pos->ai_addrlen;
saddrs[i] = GNUNET_malloc (saddrlens[i]);
memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
@@ -1120,6 +1168,9 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
#ifdef MINGW
/**
+ * Read listen sockets from the parent process (ARM).
+ *
+ * @param sctx service context to initialize
* @return GNUNET_YES if ok, GNUNET_NO if not ok (must bind yourself),
* and GNUNET_SYSERR on error.
*/
@@ -1128,22 +1179,20 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
{
const char *env_buf;
int fail;
- uint64_t count, i;
+ uint64_t count;
+ uint64_t i;
HANDLE lsocks_pipe;
env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
- if ((env_buf == NULL) || (strlen (env_buf) <= 0))
- {
+ if ((NULL == env_buf) || (strlen (env_buf) <= 0))
return GNUNET_NO;
- }
/* Using W32 API directly here, because this pipe will
* never be used outside of this function, and it's just too much of a bother
* to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
*/
lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10);
- if (lsocks_pipe == 0 || lsocks_pipe == INVALID_HANDLE_VALUE)
+ if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
return GNUNET_NO;
-
fail = 1;
do
{
@@ -1152,7 +1201,7 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
DWORD rd;
ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL);
- if (ret == 0 || rd != sizeof (count) || count == 0)
+ if ((0 == ret) || (sizeof (count) != rd) || (0 == count))
break;
sctx->lsocks =
GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1));
@@ -1163,15 +1212,16 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
WSAPROTOCOL_INFOA pi;
uint64_t size;
SOCKET s;
+
ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL);
- if (ret == 0 || rd != sizeof (size) || size != sizeof (pi))
+ if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) )
break;
ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL);
- if (ret == 0 || rd != sizeof (pi))
+ if ( (0 == ret) || (sizeof (pi) != rd))
break;
s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED);
sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
- if (sctx->lsocks[i] == NULL)
+ if (NULL == sctx->lsocks[i])
break;
else if (i == count - 1)
fail2 = 0;
@@ -1189,13 +1239,12 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Could not access a pre-bound socket, will try to bind myself\n"));
- for (i = 0; i < count && sctx->lsocks[i] != NULL; i++)
+ for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++)
GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i]));
GNUNET_free_non_null (sctx->lsocks);
sctx->lsocks = NULL;
return GNUNET_NO;
}
-
return GNUNET_YES;
}
#endif
@@ -1216,6 +1265,7 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
* - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
* - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
*
+ * @param sctx service context to initialize
* @return GNUNET_OK if configuration succeeded
*/
static int
@@ -1232,15 +1282,15 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
int flags;
#endif
- if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, "TIMEOUT"))
+ if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
{
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
"TIMEOUT", &idleout))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Specified value for `%s' of service `%s' is invalid\n"),
- "TIMEOUT", sctx->serviceName);
+ "TIMEOUT", sctx->service_name);
return GNUNET_SYSERR;
}
sctx->timeout = idleout;
@@ -1249,16 +1299,16 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
if (GNUNET_CONFIGURATION_have_value
- (sctx->cfg, sctx->serviceName, "TOLERANT"))
+ (sctx->cfg, sctx->service_name, "TOLERANT"))
{
if (GNUNET_SYSERR ==
(tolerant =
- GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
"TOLERANT")))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Specified value for `%s' of service `%s' is invalid\n"),
- "TOLERANT", sctx->serviceName);
+ "TOLERANT", sctx->service_name);
return GNUNET_SYSERR;
}
}
@@ -1268,9 +1318,9 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
#ifndef MINGW
errno = 0;
if ((NULL != (lpid = getenv ("LISTEN_PID"))) &&
- (1 == sscanf (lpid, "%u", &pid)) && (getpid () == (pid_t) pid) &&
+ (1 == SSCANF (lpid, "%u", &pid)) && (getpid () == (pid_t) pid) &&
(NULL != (nfds = getenv ("LISTEN_FDS"))) &&
- (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
+ (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
(cnt + 4 < FD_SETSIZE))
{
sctx->lsocks =
@@ -1305,17 +1355,17 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
}
#endif
- if ((sctx->lsocks == NULL) &&
+ if ((NULL == sctx->lsocks) &&
(GNUNET_SYSERR ==
- GNUNET_SERVICE_get_server_addresses (sctx->serviceName, sctx->cfg,
+ GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg,
&sctx->addrs, &sctx->addrlens)))
return GNUNET_SYSERR;
sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
sctx->match_uid =
- GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
"UNIX_MATCH_UID");
sctx->match_gid =
- GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
"UNIX_MATCH_GID");
process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
@@ -1329,15 +1379,17 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
/**
* Get the name of the user that'll be used
* to provide the service.
+ *
+ * @param sctx service context
+ * @return value of the 'USERNAME' option
*/
static char *
get_user_name (struct GNUNET_SERVICE_Context *sctx)
{
-
char *un;
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName,
+ GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
"USERNAME", &un))
return NULL;
return un;
@@ -1345,6 +1397,10 @@ get_user_name (struct GNUNET_SERVICE_Context *sctx)
/**
* Write PID file.
+ *
+ * @param sctx service context
+ * @param pid PID to write (should be equal to 'getpid()'
+ * @return GNUNET_OK on success (including no work to be done)
*/
static int
write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
@@ -1368,7 +1424,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
/* we get to create a directory -- and claim it
* as ours! */
GNUNET_DISK_directory_create (rdir);
- if ((user != NULL) && (0 < strlen (user)))
+ if ((NULL != user) && (0 < strlen (user)))
GNUNET_DISK_file_change_owner (rdir, user);
}
if (0 != ACCESS (rdir, W_OK | X_OK))
@@ -1381,7 +1437,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
}
GNUNET_free (rdir);
pidfd = FOPEN (pif, "w");
- if (pidfd == NULL)
+ if (NULL == pidfd)
{
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
GNUNET_free (pif);
@@ -1391,7 +1447,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
if (0 > FPRINTF (pidfd, "%u", pid))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
GNUNET_break (0 == FCLOSE (pidfd));
- if ((user != NULL) && (0 < strlen (user)))
+ if ((NULL != user) && (0 < strlen (user)))
GNUNET_DISK_file_change_owner (pif, user);
GNUNET_free_non_null (user);
GNUNET_free (pif);
@@ -1400,22 +1456,30 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
/**
- * Task run during shutdown.
+ * Task run during shutdown. Stops the server/service.
*
- * @param cls unused
+ * @param cls the 'struct GNUNET_SERVICE_Context'
* @param tc unused
*/
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_SERVER_Handle *server = cls;
+ struct GNUNET_SERVICE_Context *service = cls;
+ struct GNUNET_SERVER_Handle *server = service->server;
- GNUNET_SERVER_destroy (server);
+ service->shutdown_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN))
+ GNUNET_SERVER_stop_listening (server);
+ else
+ GNUNET_SERVER_destroy (server);
}
/**
* Initial task for the service.
+ *
+ * @param cls service context
+ * @param tc unused
*/
static void
service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -1424,7 +1488,7 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
unsigned int i;
GNUNET_RESOLVER_connect (sctx->cfg);
- if (sctx->lsocks != NULL)
+ if (NULL != sctx->lsocks)
sctx->server =
GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
sctx->timeout, sctx->require_found);
@@ -1432,15 +1496,15 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
sctx->server =
GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
sctx->timeout, sctx->require_found);
- if (sctx->server == NULL)
+ if (NULL == sctx->server)
{
- if (sctx->addrs != NULL)
+ if (NULL != sctx->addrs)
{
i = 0;
- while (sctx->addrs[i] != NULL)
+ while (NULL != sctx->addrs[i])
{
LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to start `%s' at `%s'\n"),
- sctx->serviceName, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+ sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
i++;
}
}
@@ -1451,29 +1515,29 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
/* install a task that will kill the server
* process if the scheduler ever gets a shutdown signal */
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
- sctx->server);
+ sctx->shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
+ sctx);
}
sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
i = 0;
- while ((sctx->my_handlers[i].callback != NULL))
+ while (NULL != sctx->my_handlers[i].callback)
sctx->my_handlers[i++].callback_cls = sctx;
GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
- if (sctx->ready_confirm_fd != -1)
+ if (-1 != sctx->ready_confirm_fd)
{
GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
sctx->ready_confirm_fd = -1;
write_pid_file (sctx, getpid ());
}
- if (sctx->addrs != NULL)
+ if (NULL != sctx->addrs)
{
i = 0;
- while (sctx->addrs[i] != NULL)
+ while (NULL != sctx->addrs[i])
{
LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
- sctx->serviceName, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+ sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
i++;
}
}
@@ -1483,6 +1547,9 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
* Detach from terminal.
+ *
+ * @param sctx service context
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
static int
detach_terminal (struct GNUNET_SERVICE_Context *sctx)
@@ -1503,7 +1570,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
return GNUNET_SYSERR;
}
- if (pid != 0)
+ if (0 != pid)
{
/* Parent */
char c;
@@ -1547,7 +1614,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
(void) CLOSE (nullfd);
/* Detach from controlling terminal */
pid = setsid ();
- if (pid == -1)
+ if (-1 == pid)
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
sctx->ready_confirm_fd = filedes[1];
#else
@@ -1561,6 +1628,9 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
/**
* Set user ID.
+ *
+ * @param sctx service context
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
static int
set_user_id (struct GNUNET_SERVICE_Context *sctx)
@@ -1574,7 +1644,7 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx)
errno = 0;
pws = getpwnam (user);
- if (pws == NULL)
+ if (NULL == pws)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Cannot obtain information about user `%s': %s\n"), user,
@@ -1605,13 +1675,15 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx)
/**
* Delete the PID file that was created by our parent.
+ *
+ * @param sctx service context
*/
static void
pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
{
char *pif = get_pid_file_name (sctx);
- if (pif == NULL)
+ if (NULL == pif)
return; /* no PID file */
if (0 != UNLINK (pif))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
@@ -1625,16 +1697,16 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
*
* @param argc number of command line arguments
* @param argv command line arguments
- * @param serviceName our service name
- * @param opt service options
+ * @param service_name our service name
+ * @param options service options
* @param task main task of the service
* @param task_cls closure for task
* @return GNUNET_SYSERR on error, GNUNET_OK
* if we shutdown nicely
*/
int
-GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
- enum GNUNET_SERVICE_Options opt, GNUNET_SERVICE_Main task,
+GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name,
+ enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_Main task,
void *task_cls)
{
#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
@@ -1656,7 +1728,7 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
{'d', "daemonize", NULL,
gettext_noop ("do daemonize (detach from terminal)"), 0,
GNUNET_GETOPT_set_one, &do_daemonize},
- GNUNET_GETOPT_OPTION_HELP (serviceName),
+ GNUNET_GETOPT_OPTION_HELP (NULL),
GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION),
@@ -1668,32 +1740,30 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
loglev = NULL;
cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE);
memset (&sctx, 0, sizeof (sctx));
- sctx.options = opt;
+ sctx.options = options;
sctx.ready_confirm_fd = -1;
sctx.ret = GNUNET_OK;
sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
sctx.task = task;
sctx.task_cls = task_cls;
- sctx.serviceName = serviceName;
+ sctx.service_name = service_name;
sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
/* setup subsystems */
if (GNUNET_SYSERR ==
- GNUNET_GETOPT_run (serviceName, service_options, argc, argv))
+ GNUNET_GETOPT_run (service_name, service_options, argc, argv))
goto shutdown;
- if (GNUNET_OK != GNUNET_log_setup (serviceName, loglev, logfile))
+ if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
HANDLE_ERROR;
if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfg_fn))
goto shutdown;
if (GNUNET_OK != setup_service (&sctx))
goto shutdown;
- if ((do_daemonize == 1) && (GNUNET_OK != detach_terminal (&sctx)))
+ if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
HANDLE_ERROR;
if (GNUNET_OK != set_user_id (&sctx))
goto shutdown;
-#if DEBUG_SERVICE
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Service `%s' runs with configuration from `%s'\n", serviceName, cfg_fn);
-#endif
+ "Service `%s' runs with configuration from `%s'\n", service_name, cfg_fn);
if ((GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
"SKEW_OFFSET", &skew_offset)) &&
@@ -1703,31 +1773,30 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
{
clock_offset = skew_offset - skew_variance;
GNUNET_TIME_set_offset (clock_offset);
-#if DEBUG_SERVICE
LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
-#endif
}
/* actually run service */
err = 0;
GNUNET_SCHEDULER_run (&service_task, &sctx);
-
+ GNUNET_SPEEDUP_start_ (cfg);
/* shutdown */
- if ((do_daemonize == 1) && (sctx.server != NULL))
+ if ((1 == do_daemonize) && (NULL != sctx.server))
pid_file_delete (&sctx);
GNUNET_free_non_null (sctx.my_handlers);
shutdown:
- if (sctx.ready_confirm_fd != -1)
+ if (-1 != sctx.ready_confirm_fd)
{
if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
}
+ GNUNET_SPEEDUP_stop_ ();
GNUNET_CONFIGURATION_destroy (cfg);
i = 0;
- if (sctx.addrs != NULL)
- while (sctx.addrs[i] != NULL)
+ if (NULL != sctx.addrs)
+ while (NULL != sctx.addrs[i])
GNUNET_free (sctx.addrs[i++]);
GNUNET_free_non_null (sctx.addrs);
GNUNET_free_non_null (sctx.addrlens);
@@ -1747,13 +1816,15 @@ shutdown:
* Run a service startup sequence within an existing
* initialized system.
*
- * @param serviceName our service name
+ * @param service_name our service name
* @param cfg configuration to use
+ * @param options service options
* @return NULL on error, service handle
*/
struct GNUNET_SERVICE_Context *
-GNUNET_SERVICE_start (const char *serviceName,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+GNUNET_SERVICE_start (const char *service_name,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ enum GNUNET_SERVICE_Options options)
{
int i;
struct GNUNET_SERVICE_Context *sctx;
@@ -1762,8 +1833,9 @@ GNUNET_SERVICE_start (const char *serviceName,
sctx->ready_confirm_fd = -1; /* no daemonizing */
sctx->ret = GNUNET_OK;
sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
- sctx->serviceName = serviceName;
+ sctx->service_name = service_name;
sctx->cfg = cfg;
+ sctx->options = options;
/* setup subsystems */
if (GNUNET_OK != setup_service (sctx))
@@ -1771,7 +1843,7 @@ GNUNET_SERVICE_start (const char *serviceName,
GNUNET_SERVICE_stop (sctx);
return NULL;
}
- if (sctx->lsocks != NULL)
+ if (NULL != sctx->lsocks)
sctx->server =
GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
sctx->timeout, sctx->require_found);
@@ -1794,6 +1866,7 @@ GNUNET_SERVICE_start (const char *serviceName,
return sctx;
}
+
/**
* Obtain the server used by a service. Note that the server must NOT
* be destroyed by the caller.
@@ -1818,13 +1891,18 @@ GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
{
unsigned int i;
+ if (GNUNET_SCHEDULER_NO_TASK != sctx->shutdown_task)
+ {
+ GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
+ sctx->shutdown_task = GNUNET_SCHEDULER_NO_TASK;
+ }
if (NULL != sctx->server)
GNUNET_SERVER_destroy (sctx->server);
GNUNET_free_non_null (sctx->my_handlers);
- if (sctx->addrs != NULL)
+ if (NULL != sctx->addrs)
{
i = 0;
- while (sctx->addrs[i] != NULL)
+ while (NULL != sctx->addrs[i])
GNUNET_free (sctx->addrs[i++]);
GNUNET_free (sctx->addrs);
}
diff --git a/src/util/speedup.c b/src/util/speedup.c
new file mode 100644
index 0000000..0a005c0
--- /dev/null
+++ b/src/util/speedup.c
@@ -0,0 +1,92 @@
+/*
+ This file is part of GNUnet.
+ (C) 2001, 2002, 2006, 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/speedup.c
+ * @author Matthias Wachs
+ * @brief functions to speedup peer execution by manipulation system time
+ */
+#include "platform.h"
+#include "gnunet_time_lib.h"
+#include "gnunet_scheduler_lib.h"
+
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+
+
+static struct GNUNET_TIME_Relative interval;
+
+static struct GNUNET_TIME_Relative delta;
+
+static GNUNET_SCHEDULER_TaskIdentifier speedup_task;
+
+
+static void
+do_speedup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ static long long current_offset;
+
+ speedup_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ return;
+ current_offset += delta.rel_value;
+ GNUNET_TIME_set_offset (current_offset);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Speeding up execution time by %llu ms\n", delta.rel_value);
+ speedup_task = GNUNET_SCHEDULER_add_delayed (interval, &do_speedup, NULL);
+}
+
+
+int
+GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "SPEEDUP_INTERVAL", &interval))
+ return GNUNET_SYSERR;
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "SPEEDUP_DELTA", &delta))
+ return GNUNET_SYSERR;
+
+ if ((0 == interval.rel_value) || (0 == delta.rel_value))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Speed up disabled\n");
+ return GNUNET_OK;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Speed up execution time %llu ms every %llu ms\n",
+ delta.rel_value, interval.rel_value);
+ speedup_task = GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO, &do_speedup, NULL);
+ return GNUNET_OK;
+}
+
+
+void
+GNUNET_SPEEDUP_stop_ ( )
+{
+ if (GNUNET_SCHEDULER_NO_TASK != speedup_task)
+ {
+ GNUNET_SCHEDULER_cancel (speedup_task);
+ speedup_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Stopped execution speed up\n");
+}
+
+
+
+/* end of speedup.c */
diff --git a/src/util/strings.c b/src/util/strings.c
index 8000a93..11134f1 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -31,6 +31,7 @@
#endif
#include "gnunet_common.h"
#include "gnunet_strings_lib.h"
+#include <unicase.h>
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -170,51 +171,38 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
/**
- * Convert a given fancy human-readable size to bytes.
+ * Unit conversion table entry for 'convert_with_table'.
+ */
+struct ConversionTable
+{
+ /**
+ * Name of the unit (or NULL for end of table).
+ */
+ const char *name;
+
+ /**
+ * Factor to apply for this unit.
+ */
+ unsigned long long value;
+};
+
+
+/**
+ * Convert a string of the form "4 X 5 Y" into a numeric value
+ * by interpreting "X" and "Y" as units and then multiplying
+ * the numbers with the values associated with the respective
+ * unit from the conversion table.
*
- * @param fancy_size human readable string (i.e. 1 MB)
- * @param size set to the size in bytes
+ * @param input input string to parse
+ * @param table table with the conversion of unit names to numbers
+ * @param output where to store the result
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
-int
-GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
- unsigned long long *size)
+static int
+convert_with_table (const char *input,
+ const struct ConversionTable *table,
+ unsigned long long *output)
{
- struct
- {
- const char *name;
- unsigned long long value;
- } table[] =
- {
- {
- "B", 1},
- {
- "KiB", 1024},
- {
- "kB", 1000},
- {
- "MiB", 1024 * 1024},
- {
- "MB", 1000 * 1000},
- {
- "GiB", 1024 * 1024 * 1024},
- {
- "GB", 1000 * 1000 * 1000},
- {
- "TiB", 1024LL * 1024LL * 1024LL * 1024LL},
- {
- "TB", 1000LL * 1000LL * 1000LL * 1024LL},
- {
- "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
- {
- "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL},
- {
- "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
- {
- "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL},
- {
- NULL, 0}
- };
unsigned long long ret;
char *in;
const char *tok;
@@ -223,7 +211,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
ret = 0;
last = 0;
- in = GNUNET_strdup (fancy_size);
+ in = GNUNET_strdup (input);
for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
{
i = 0;
@@ -235,7 +223,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
{
ret += last;
last = 0;
- if (1 != sscanf (tok, "%llu", &last))
+ if (1 != SSCANF (tok, "%llu", &last))
{
GNUNET_free (in);
return GNUNET_SYSERR; /* expected number */
@@ -243,88 +231,80 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
}
}
ret += last;
- *size = ret;
+ *output = ret;
GNUNET_free (in);
return GNUNET_OK;
}
/**
+ * Convert a given fancy human-readable size to bytes.
+ *
+ * @param fancy_size human readable string (i.e. 1 MB)
+ * @param size set to the size in bytes
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
+ unsigned long long *size)
+{
+ static const struct ConversionTable table[] =
+ {
+ { "B", 1},
+ { "KiB", 1024},
+ { "kB", 1000},
+ { "MiB", 1024 * 1024},
+ { "MB", 1000 * 1000},
+ { "GiB", 1024 * 1024 * 1024},
+ { "GB", 1000 * 1000 * 1000},
+ { "TiB", 1024LL * 1024LL * 1024LL * 1024LL},
+ { "TB", 1000LL * 1000LL * 1000LL * 1024LL},
+ { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
+ { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL},
+ { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
+ { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL},
+ { NULL, 0}
+ };
+
+ return convert_with_table (fancy_size,
+ table,
+ size);
+}
+
+
+/**
* Convert a given fancy human-readable time to our internal
* representation.
*
- * @param fancy_size human readable string (i.e. 1 minute)
+ * @param fancy_time human readable string (i.e. 1 minute)
* @param rtime set to the relative time
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
int
-GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size,
+GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
struct GNUNET_TIME_Relative *rtime)
{
- struct
- {
- const char *name;
- unsigned long long value;
- } table[] =
+ static const struct ConversionTable table[] =
{
- {
- "ms", 1},
- {
- "s", 1000},
- {
- "\"", 1000},
- {
- "min", 60 * 1000},
- {
- "minutes", 60 * 1000},
- {
- "'", 60 * 1000},
- {
- "h", 60 * 60 * 1000},
- {
- "d", 24 * 60 * 60 * 1000},
- {
- "a", 31557600 /* year */ },
- {
- NULL, 0}
+ { "ms", 1},
+ { "s", 1000},
+ { "\"", 1000},
+ { "min", 60 * 1000},
+ { "minutes", 60 * 1000},
+ { "'", 60 * 1000},
+ { "h", 60 * 60 * 1000},
+ { "d", 24 * 60 * 60 * 1000},
+ { "a", 31536000000LL /* year */ },
+ { NULL, 0}
};
- unsigned long long ret;
- char *in;
- const char *tok;
- unsigned long long last;
- unsigned int i;
+ int ret;
+ unsigned long long val;
- if ((0 == strcasecmp (fancy_size, "infinity")) ||
- (0 == strcasecmp (fancy_size, "forever")))
- {
- *rtime = GNUNET_TIME_UNIT_FOREVER_REL;
- return GNUNET_OK;
- }
- ret = 0;
- last = 0;
- in = GNUNET_strdup (fancy_size);
- for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
- {
- i = 0;
- while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
- i++;
- if (table[i].name != NULL)
- last *= table[i].value;
- else
- {
- ret += last;
- last = 0;
- if (1 != sscanf (tok, "%llu", &last))
- {
- GNUNET_free (in);
- return GNUNET_SYSERR; /* expected number */
- }
- }
- }
- ret += last;
- rtime->rel_value = (uint64_t) ret;
- GNUNET_free (in);
- return GNUNET_OK;
+ ret = convert_with_table (fancy_time,
+ table,
+ &val);
+ rtime->rel_value = (uint64_t) val;
+ return ret;
}
/**
@@ -422,6 +402,45 @@ GNUNET_STRINGS_from_utf8 (const char *input, size_t len, const char *charset)
return GNUNET_STRINGS_conv (input, len, "UTF-8", charset);
}
+/**
+ * Convert the utf-8 input string to lowercase
+ * Output needs to be allocated appropriately
+ *
+ * @param input input string
+ * @param output output buffer
+ */
+void
+GNUNET_STRINGS_utf8_tolower(const char* input, char** output)
+{
+ uint8_t *tmp_in;
+ size_t len;
+
+ tmp_in = u8_tolower ((uint8_t*)input, strlen ((char *) input),
+ NULL, UNINORM_NFD, NULL, &len);
+ memcpy(*output, tmp_in, len);
+ (*output)[len] = '\0';
+ free(tmp_in);
+}
+
+/**
+ * Convert the utf-8 input string to uppercase
+ * Output needs to be allocated appropriately
+ *
+ * @param input input string
+ * @param output output buffer
+ */
+void
+GNUNET_STRINGS_utf8_toupper(const char* input, char** output)
+{
+ uint8_t *tmp_in;
+ size_t len;
+
+ tmp_in = u8_toupper ((uint8_t*)input, strlen ((char *) input),
+ NULL, UNINORM_NFD, NULL, &len);
+ memcpy(*output, tmp_in, len);
+ (*output)[len] = '\0';
+ free(tmp_in);
+}
/**
@@ -630,4 +649,468 @@ GNUNET_STRINGS_get_short_name (const char *filename)
return short_fn;
}
+
+/**
+ * Get the numeric value corresponding to a character.
+ *
+ * @param a a character
+ * @return corresponding numeric value
+ */
+static unsigned int
+getValue__ (unsigned char a)
+{
+ if ((a >= '0') && (a <= '9'))
+ return a - '0';
+ if ((a >= 'A') && (a <= 'V'))
+ return (a - 'A' + 10);
+ return -1;
+}
+
+
+/**
+ * Convert binary data to ASCII encoding. The ASCII encoding is rather
+ * GNUnet specific. It was chosen such that it only uses characters
+ * in [0-9A-V], can be produced without complex arithmetics and uses a
+ * small number of characters.
+ * Does not append 0-terminator, but returns a pointer to the place where
+ * it should be placed, if needed.
+ *
+ * @param data data to encode
+ * @param size size of data (in bytes)
+ * @param out buffer to fill
+ * @param out_size size of the buffer. Must be large enough to hold
+ * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes
+ * @return pointer to the next byte in 'out' or NULL on error.
+ */
+char *
+GNUNET_STRINGS_data_to_string (const unsigned char *data, size_t size, char *out, size_t out_size)
+{
+ /**
+ * 32 characters for encoding
+ */
+ static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+ unsigned int wpos;
+ unsigned int rpos;
+ unsigned int bits;
+ unsigned int vbit;
+
+ GNUNET_assert (data != NULL);
+ GNUNET_assert (out != NULL);
+ if (out_size < (((size*8) + ((size*8) % 5)) % 5))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ vbit = 0;
+ wpos = 0;
+ rpos = 0;
+ bits = 0;
+ while ((rpos < size) || (vbit > 0))
+ {
+ if ((rpos < size) && (vbit < 5))
+ {
+ bits = (bits << 8) | data[rpos++]; /* eat 8 more bits */
+ vbit += 8;
+ }
+ if (vbit < 5)
+ {
+ bits <<= (5 - vbit); /* zero-padding */
+ GNUNET_assert (vbit == ((size * 8) % 5));
+ vbit = 5;
+ }
+ if (wpos >= out_size)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
+ vbit -= 5;
+ }
+ if (wpos != out_size)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ GNUNET_assert (vbit == 0);
+ return &out[wpos];
+}
+
+
+/**
+ * Convert ASCII encoding back to data
+ * out_size must match exactly the size of the data before it was encoded.
+ *
+ * @param enc the encoding
+ * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing)
+ * @param out location where to store the decoded data
+ * @param out_size sizeof the output buffer
+ * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
+ */
+int
+GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen,
+ unsigned char *out, size_t out_size)
+{
+ unsigned int rpos;
+ unsigned int wpos;
+ unsigned int bits;
+ unsigned int vbit;
+ int ret;
+ int shift;
+ int encoded_len = out_size * 8;
+ if (encoded_len % 5 > 0)
+ {
+ vbit = encoded_len % 5; /* padding! */
+ shift = 5 - vbit;
+ }
+ else
+ {
+ vbit = 0;
+ shift = 0;
+ }
+ if ((encoded_len + shift) / 5 != enclen)
+ return GNUNET_SYSERR;
+
+ wpos = out_size;
+ rpos = enclen;
+ bits = (ret = getValue__ (enc[--rpos])) >> (5 - encoded_len % 5);
+ if (-1 == ret)
+ return GNUNET_SYSERR;
+ while (wpos > 0)
+ {
+ GNUNET_assert (rpos > 0);
+ bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
+ if (-1 == ret)
+ return GNUNET_SYSERR;
+ vbit += 5;
+ if (vbit >= 8)
+ {
+ out[--wpos] = (unsigned char) bits;
+ bits >>= 8;
+ vbit -= 8;
+ }
+ }
+ GNUNET_assert (rpos == 0);
+ GNUNET_assert (vbit == 0);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Parse a path that might be an URI.
+ *
+ * @param path path to parse. Must be NULL-terminated.
+ * @param scheme_part a pointer to 'char *' where a pointer to a string that
+ * represents the URI scheme will be stored. Can be NULL. The string is
+ * allocated by the function, and should be freed by GNUNET_free() when
+ * it is no longer needed.
+ * @param path_part a pointer to 'const char *' where a pointer to the path
+ * part of the URI will be stored. Can be NULL. Points to the same block
+ * of memory as 'path', and thus must not be freed. Might point to '\0',
+ * if path part is zero-length.
+ * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not
+ * an URI, '* scheme_part' and '*path_part' will remain unchanged
+ * (if they weren't NULL).
+ */
+int
+GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part,
+ const char **path_part)
+{
+ size_t len;
+ int i, end;
+ int pp_state = 0;
+ const char *post_scheme_part = NULL;
+ len = strlen (path);
+ for (end = 0, i = 0; !end && i < len; i++)
+ {
+ switch (pp_state)
+ {
+ case 0:
+ if (path[i] == ':' && i > 0)
+ {
+ pp_state += 1;
+ continue;
+ }
+ if (!((path[i] >= 'A' && path[i] <= 'Z') || (path[i] >= 'a' && path[i] <= 'z')
+ || (path[i] >= '0' && path[i] <= '9') || path[i] == '+' || path[i] == '-'
+ || (path[i] == '.')))
+ end = 1;
+ break;
+ case 1:
+ case 2:
+ if (path[i] == '/')
+ {
+ pp_state += 1;
+ continue;
+ }
+ end = 1;
+ break;
+ case 3:
+ post_scheme_part = &path[i];
+ end = 1;
+ break;
+ default:
+ end = 1;
+ }
+ }
+ if (post_scheme_part == NULL)
+ return GNUNET_NO;
+ if (scheme_part)
+ {
+ *scheme_part = GNUNET_malloc (post_scheme_part - path + 1);
+ memcpy (*scheme_part, path, post_scheme_part - path);
+ (*scheme_part)[post_scheme_part - path] = '\0';
+ }
+ if (path_part)
+ *path_part = post_scheme_part;
+ return GNUNET_YES;
+}
+
+
+/**
+ * Check whether 'filename' is absolute or not, and if it's an URI
+ *
+ * @param filename filename to check
+ * @param can_be_uri GNUNET_YES to check for being URI, GNUNET_NO - to
+ * assume it's not URI
+ * @param r_is_uri a pointer to an int that is set to GNUNET_YES if 'filename'
+ * is URI and to GNUNET_NO otherwise. Can be NULL. If 'can_be_uri' is
+ * not GNUNET_YES, *r_is_uri is set to GNUNET_NO.
+ * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI scheme.
+ * The string is allocated by the function, and should be freed with
+ * GNUNET_free (). Can be NULL.
+ * @return GNUNET_YES if 'filename' is absolute, GNUNET_NO otherwise.
+ */
+int
+GNUNET_STRINGS_path_is_absolute (const char *filename, int can_be_uri,
+ int *r_is_uri, char **r_uri_scheme)
+{
+#if WINDOWS
+ size_t len;
+#endif
+ const char *post_scheme_path;
+ int is_uri;
+ char * uri;
+ /* consider POSIX paths to be absolute too, even on W32,
+ * as plibc expansion will fix them for us.
+ */
+ if (filename[0] == '/')
+ return GNUNET_YES;
+ if (can_be_uri)
+ {
+ is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path);
+ if (r_is_uri)
+ *r_is_uri = is_uri;
+ if (is_uri)
+ {
+ if (r_uri_scheme)
+ *r_uri_scheme = uri;
+ else
+ GNUNET_free_non_null (uri);
+#if WINDOWS
+ len = strlen(post_scheme_path);
+ /* Special check for file:///c:/blah
+ * We want to parse 'c:/', not '/c:/'
+ */
+ if (post_scheme_path[0] == '/' && len >= 3 && post_scheme_path[2] == ':')
+ post_scheme_path = &post_scheme_path[1];
+#endif
+ return GNUNET_STRINGS_path_is_absolute (post_scheme_path, GNUNET_NO, NULL, NULL);
+ }
+ }
+ else
+ {
+ is_uri = GNUNET_NO;
+ if (r_is_uri)
+ *r_is_uri = GNUNET_NO;
+ }
+#if WINDOWS
+ len = strlen (filename);
+ if (len >= 3 &&
+ ((filename[0] >= 'A' && filename[0] <= 'Z')
+ || (filename[0] >= 'a' && filename[0] <= 'z'))
+ && filename[1] == ':' && (filename[2] == '/' || filename[2] == '\\'))
+ return GNUNET_YES;
+#endif
+ return GNUNET_NO;
+}
+
+#if MINGW
+#define _IFMT 0170000 /* type of file */
+#define _IFLNK 0120000 /* symbolic link */
+#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
+#endif
+
+
+/**
+ * Perform 'checks' on 'filename'
+ *
+ * @param filename file to check
+ * @param checks checks to perform
+ * @return GNUNET_YES if all checks pass, GNUNET_NO if at least one of them
+ * fails, GNUNET_SYSERR when a check can't be performed
+ */
+int
+GNUNET_STRINGS_check_filename (const char *filename,
+ enum GNUNET_STRINGS_FilenameCheck checks)
+{
+ struct stat st;
+ if ( (NULL == filename) || (filename[0] == '\0') )
+ return GNUNET_SYSERR;
+ if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
+ if (!GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL))
+ return GNUNET_NO;
+ if (0 != (checks & (GNUNET_STRINGS_CHECK_EXISTS
+ | GNUNET_STRINGS_CHECK_IS_DIRECTORY
+ | GNUNET_STRINGS_CHECK_IS_LINK)))
+ {
+ if (0 != STAT (filename, &st))
+ {
+ if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
+ return GNUNET_NO;
+ else
+ return GNUNET_SYSERR;
+ }
+ }
+ if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
+ if (!S_ISDIR (st.st_mode))
+ return GNUNET_NO;
+ if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
+ if (!S_ISLNK (st.st_mode))
+ return GNUNET_NO;
+ return GNUNET_YES;
+}
+
+
+
+/**
+ * Tries to convert 'zt_addr' string to an IPv6 address.
+ * The string is expected to have the format "[ABCD::01]:80".
+ *
+ * @param zt_addr 0-terminated string. May be mangled by the function.
+ * @param addrlen length of zt_addr (not counting 0-terminator).
+ * @param r_buf a buffer to fill. Initially gets filled with zeroes,
+ * then its sin6_port, sin6_family and sin6_addr are set appropriately.
+ * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which
+ * case the contents of r_buf are undefined.
+ */
+int
+GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
+ uint16_t addrlen,
+ struct sockaddr_in6 *r_buf)
+{
+ char zbuf[addrlen + 1];
+ int ret;
+ char *port_colon;
+ unsigned int port;
+
+ if (addrlen < 6)
+ return GNUNET_SYSERR;
+ memcpy (zbuf, zt_addr, addrlen);
+ if ('[' != zbuf[0])
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("IPv6 address did not start with `['\n"));
+ return GNUNET_SYSERR;
+ }
+ zbuf[addrlen] = '\0';
+ port_colon = strrchr (zbuf, ':');
+ if (NULL == port_colon)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("IPv6 address did contain ':' to separate port number\n"));
+ return GNUNET_SYSERR;
+ }
+ if (']' != *(port_colon - 1))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("IPv6 address did contain ']' before ':' to separate port number\n"));
+ return GNUNET_SYSERR;
+ }
+ ret = SSCANF (port_colon, ":%u", &port);
+ if ( (1 != ret) || (port > 65535) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("IPv6 address did contain a valid port number after the last ':'\n"));
+ return GNUNET_SYSERR;
+ }
+ *(port_colon-1) = '\0';
+ memset (r_buf, 0, sizeof (struct sockaddr_in6));
+ ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
+ if (ret <= 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Invalid IPv6 address `%s': %s\n"),
+ &zbuf[1],
+ STRERROR (errno));
+ return GNUNET_SYSERR;
+ }
+ r_buf->sin6_port = htons (port);
+ r_buf->sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ r_buf->sin6_len = (u_char) sizeof (struct sockaddr_in6);
+#endif
+ return GNUNET_OK;
+}
+
+
+/**
+ * Tries to convert 'zt_addr' string to an IPv4 address.
+ * The string is expected to have the format "1.2.3.4:80".
+ *
+ * @param zt_addr 0-terminated string. May be mangled by the function.
+ * @param addrlen length of zt_addr (not counting 0-terminator).
+ * @param r_buf a buffer to fill.
+ * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which case
+ * the contents of r_buf are undefined.
+ */
+int
+GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen,
+ struct sockaddr_in *r_buf)
+{
+ unsigned int temps[4];
+ unsigned int port;
+ unsigned int cnt;
+
+ if (addrlen < 9)
+ return GNUNET_SYSERR;
+ cnt = SSCANF (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2], &temps[3], &port);
+ if (5 != cnt)
+ return GNUNET_SYSERR;
+ for (cnt = 0; cnt < 4; cnt++)
+ if (temps[cnt] > 0xFF)
+ return GNUNET_SYSERR;
+ if (port > 65535)
+ return GNUNET_SYSERR;
+ r_buf->sin_family = AF_INET;
+ r_buf->sin_port = htons (port);
+ r_buf->sin_addr.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16) +
+ (temps[2] << 8) + temps[3]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ r_buf->sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+ return GNUNET_OK;
+}
+
+
+/**
+ * Tries to convert 'addr' string to an IP (v4 or v6) address.
+ * Will automatically decide whether to treat 'addr' as v4 or v6 address.
+ *
+ * @param addr a string, may not be 0-terminated.
+ * @param addrlen number of bytes in addr (if addr is 0-terminated,
+ * 0-terminator should not be counted towards addrlen).
+ * @param r_buf a buffer to fill.
+ * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which
+ * case the contents of r_buf are undefined.
+ */
+int
+GNUNET_STRINGS_to_address_ip (const char *addr,
+ uint16_t addrlen,
+ struct sockaddr_storage *r_buf)
+{
+ if (addr[0] == '[')
+ return GNUNET_STRINGS_to_address_ipv6 (addr, addrlen, (struct sockaddr_in6 *) r_buf);
+ return GNUNET_STRINGS_to_address_ipv4 (addr, addrlen, (struct sockaddr_in *) r_buf);
+}
+
/* end of strings.c */
diff --git a/src/util/test_client.c b/src/util/test_client.c
index f9d961a..54881b2 100644
--- a/src/util/test_client.c
+++ b/src/util/test_client.c
@@ -109,7 +109,7 @@ recv_bounce (void *cls, const struct GNUNET_MessageHeader *got)
msg.type = htons (MY_TYPE);
msg.size = htons (sizeof (struct GNUNET_MessageHeader));
GNUNET_assert (0 == memcmp (got, &msg, sizeof (struct GNUNET_MessageHeader)));
- GNUNET_CLIENT_disconnect (client, GNUNET_YES);
+ GNUNET_CLIENT_disconnect (client);
client = NULL;
GNUNET_SERVER_destroy (server);
server = NULL;
@@ -137,6 +137,10 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
struct sockaddr *sap[2];
socklen_t slens[2];
+ /* test that ill-configured client fails instantly */
+ GNUNET_assert (NULL == GNUNET_CLIENT_connect ("invalid-service", cfg));
+
+ /* test IPC between client and server */
sap[0] = (struct sockaddr *) &sa;
slens[0] = sizeof (sa);
sap[1] = NULL;
diff --git a/src/util/test_common_logging_runtime_loglevels.c b/src/util/test_common_logging_runtime_loglevels.c
index cdf1f66..b914ae1 100644
--- a/src/util/test_common_logging_runtime_loglevels.c
+++ b/src/util/test_common_logging_runtime_loglevels.c
@@ -55,7 +55,7 @@ end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
}
GNUNET_OS_process_wait (proc);
- GNUNET_OS_process_close (proc);
+ GNUNET_OS_process_destroy (proc);
proc = NULL;
GNUNET_DISK_pipe_close (pipe_stdout);
if (ok == 1)
diff --git a/src/util/test_configuration.c b/src/util/test_configuration.c
index b1a446f..1242a5c 100644
--- a/src/util/test_configuration.c
+++ b/src/util/test_configuration.c
@@ -28,7 +28,6 @@
#include "gnunet_configuration_lib.h"
#include "gnunet_disk_lib.h"
-#define DEBUG GNUNET_EXTRA_LOGGING
/* Test Configuration Diffs Options */
enum
@@ -40,10 +39,8 @@ enum
ADD_NEW_ENTRY,
REMOVE_SECTION,
REMOVE_ENTRY,
- COMPARE
-#if DEBUG
- , PRINT
-#endif
+ COMPARE,
+ PRINT
};
static struct GNUNET_CONFIGURATION_Handle *cfg;
diff --git a/src/util/test_connection.c b/src/util/test_connection.c
index cb69f40..4568f8e 100644
--- a/src/util/test_connection.c
+++ b/src/util/test_connection.c
@@ -102,7 +102,8 @@ receive_check (void *cls, const void *buf, size_t available,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive closes accepted socket\n");
#endif
*ok = 0;
- GNUNET_CONNECTION_destroy (asock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (asock);
+ GNUNET_CONNECTION_destroy (csock);
}
}
@@ -119,7 +120,7 @@ run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
#endif
- GNUNET_CONNECTION_destroy (lsock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (lsock);
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Test asks to receive on accepted socket\n");
@@ -142,7 +143,6 @@ make_hello (void *cls, size_t size, void *buf)
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
#endif
- GNUNET_CONNECTION_destroy (csock, GNUNET_YES);
return 12;
}
diff --git a/src/util/test_connection_addressing.c b/src/util/test_connection_addressing.c
index 2d08acc..ba7acae 100644
--- a/src/util/test_connection_addressing.c
+++ b/src/util/test_connection_addressing.c
@@ -99,7 +99,8 @@ receive_check (void *cls, const void *buf, size_t available,
else
{
*ok = 0;
- GNUNET_CONNECTION_destroy (asock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (csock);
+ GNUNET_CONNECTION_destroy (asock);
}
}
@@ -128,7 +129,7 @@ run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
GNUNET_assert (0 == memcmp (&expect, v4, alen));
GNUNET_free (addr);
- GNUNET_CONNECTION_destroy (lsock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (lsock);
GNUNET_CONNECTION_receive (asock, 1024,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
@@ -143,6 +144,7 @@ make_hello (void *cls, size_t size, void *buf)
return 12;
}
+
static void
task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
@@ -167,7 +169,6 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
GNUNET_TIME_UNIT_SECONDS,
&make_hello, NULL));
- GNUNET_CONNECTION_destroy (csock, GNUNET_YES);
GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
cls);
}
diff --git a/src/util/test_connection_receive_cancel.c b/src/util/test_connection_receive_cancel.c
index aa16724..93fcd5f 100644
--- a/src/util/test_connection_receive_cancel.c
+++ b/src/util/test_connection_receive_cancel.c
@@ -86,11 +86,10 @@ dead_receive (void *cls, const void *buf, size_t available,
static void
run_accept_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
-
asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
GNUNET_assert (asock != NULL);
GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
- GNUNET_CONNECTION_destroy (lsock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (lsock);
GNUNET_CONNECTION_receive (asock, 1024,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 5), &dead_receive, cls);
@@ -103,8 +102,8 @@ receive_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
int *ok = cls;
GNUNET_CONNECTION_receive_cancel (asock);
- GNUNET_CONNECTION_destroy (csock, GNUNET_YES);
- GNUNET_CONNECTION_destroy (asock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (csock);
+ GNUNET_CONNECTION_destroy (asock);
*ok = 0;
}
diff --git a/src/util/test_connection_timeout.c b/src/util/test_connection_timeout.c
index 2338665..c0597b2 100644
--- a/src/util/test_connection_timeout.c
+++ b/src/util/test_connection_timeout.c
@@ -83,8 +83,8 @@ send_kilo (void *cls, size_t size, void *buf)
#endif
GNUNET_assert (buf == NULL);
*ok = 0;
- GNUNET_CONNECTION_destroy (lsock, GNUNET_YES);
- GNUNET_CONNECTION_destroy (csock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (lsock);
+ GNUNET_CONNECTION_destroy (csock);
return 0;
}
#if VERBOSE
diff --git a/src/util/test_connection_transmit_cancel.c b/src/util/test_connection_transmit_cancel.c
index d81c32a..fec72d2 100644
--- a/src/util/test_connection_transmit_cancel.c
+++ b/src/util/test_connection_transmit_cancel.c
@@ -56,7 +56,7 @@ task_transmit_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
&not_run, cls);
GNUNET_assert (NULL != th);
GNUNET_CONNECTION_notify_transmit_ready_cancel (th);
- GNUNET_CONNECTION_destroy (csock, GNUNET_YES);
+ GNUNET_CONNECTION_destroy (csock);
*ok = 0;
}
diff --git a/src/util/test_disk.c b/src/util/test_disk.c
index 5462772..149cec0 100644
--- a/src/util/test_disk.c
+++ b/src/util/test_disk.c
@@ -97,7 +97,7 @@ testOpenClose ()
GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5));
GNUNET_DISK_file_close (fh);
GNUNET_break (GNUNET_OK ==
- GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO));
+ GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES));
if (size != 5)
return 1;
GNUNET_break (0 == UNLINK (".testfile"));
diff --git a/src/util/test_os_start_process.c b/src/util/test_os_start_process.c
index 54638c1..0d14818 100644
--- a/src/util/test_os_start_process.c
+++ b/src/util/test_os_start_process.c
@@ -51,13 +51,12 @@ static GNUNET_SCHEDULER_TaskIdentifier die_task;
static void
end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
-
if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
}
- GNUNET_OS_process_wait (proc);
- GNUNET_OS_process_close (proc);
+ GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc));
+ GNUNET_OS_process_destroy (proc);
proc = NULL;
GNUNET_DISK_pipe_close (hello_pipe_stdout);
GNUNET_DISK_pipe_close (hello_pipe_stdin);
@@ -106,7 +105,7 @@ read_call (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static void
-task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
char *fn;
const struct GNUNET_DISK_FileHandle *stdout_read_handle;
@@ -160,22 +159,79 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
stdout_read_handle, &read_call,
(void *) stdout_read_handle);
-
}
+
/**
* Main method, starts scheduler with task1,
* checks that "ok" is correct at the end.
*/
static int
-check ()
+check_run ()
{
ok = 1;
- GNUNET_SCHEDULER_run (&task, &ok);
+ GNUNET_SCHEDULER_run (&run_task, &ok);
return ok;
}
+/**
+ * Test killing via pipe.
+ */
+static int
+check_kill ()
+{
+ hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
+ hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
+ if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL))
+ {
+ return 1;
+ }
+ proc =
+ GNUNET_OS_start_process (GNUNET_YES, hello_pipe_stdin, hello_pipe_stdout, "cat",
+ "gnunet-service-resolver", "-", NULL);
+ sleep (1); /* give process time to start and open pipe */
+ if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ }
+ GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc));
+ GNUNET_OS_process_destroy (proc);
+ proc = NULL;
+ GNUNET_DISK_pipe_close (hello_pipe_stdout);
+ GNUNET_DISK_pipe_close (hello_pipe_stdin);
+ return 0;
+}
+
+
+/**
+ * Test killing via pipe.
+ */
+static int
+check_instant_kill ()
+{
+ hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
+ hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
+ if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL))
+ {
+ return 1;
+ }
+ proc =
+ GNUNET_OS_start_process (GNUNET_YES, hello_pipe_stdin, hello_pipe_stdout, "cat",
+ "gnunet-service-resolver", "-", NULL);
+ if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ }
+ GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc));
+ GNUNET_OS_process_destroy (proc);
+ proc = NULL;
+ GNUNET_DISK_pipe_close (hello_pipe_stdout);
+ GNUNET_DISK_pipe_close (hello_pipe_stdin);
+ return 0;
+}
+
+
int
main (int argc, char *argv[])
{
@@ -188,7 +244,10 @@ main (int argc, char *argv[])
"WARNING",
#endif
NULL);
- ret = check ();
+ ret = 0;
+ ret |= check_run ();
+ ret |= check_kill ();
+ ret |= check_instant_kill ();
return ret;
}
diff --git a/src/util/test_pseudonym.c b/src/util/test_pseudonym.c
index 20a3d3d..4ce8b38 100644
--- a/src/util/test_pseudonym.c
+++ b/src/util/test_pseudonym.c
@@ -39,6 +39,7 @@ static GNUNET_HashCode id1;
static int
iter (void *cls, const GNUNET_HashCode * pseudonym,
+ const char *name, const char *unique_name,
const struct GNUNET_CONTAINER_MetaData *md, int rating)
{
int *ok = cls;
@@ -54,6 +55,7 @@ iter (void *cls, const GNUNET_HashCode * pseudonym,
static int
noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
+ const char *name, const char *unique_name,
const struct GNUNET_CONTAINER_MetaData *md, int rating)
{
int *ret = cls;
@@ -64,6 +66,7 @@ noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
static int
fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
+ const char *name, const char *unique_name,
const struct GNUNET_CONTAINER_MetaData *md, int rating)
{
int *ret = cls;
@@ -74,6 +77,7 @@ fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
static int
false_callback (void *cls, const GNUNET_HashCode * pseudonym,
+ const char *name, const char *unique_name,
const struct GNUNET_CONTAINER_MetaData *md, int rating)
{
return GNUNET_OK;
@@ -95,7 +99,10 @@ main (int argc, char *argv[])
char *name1;
char *name2;
char *name3;
+ char *name1_unique;
+ char *name2_unique;
char *noname;
+ int noname_is_a_dup;
int notiCount, fakenotiCount;
int count;
static char m[1024 * 1024 * 10];
@@ -152,15 +159,21 @@ main (int argc, char *argv[])
strlen (m) + 1));
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3);
GNUNET_PSEUDONYM_add (cfg, &id3, meta);
- name3 = GNUNET_PSEUDONYM_id_to_name (cfg, &id3);
- name2 = GNUNET_PSEUDONYM_id_to_name (cfg, &id2);
+ GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL);
+ CHECK (name3 != NULL);
+ GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL);
CHECK (name2 != NULL);
- name1 = GNUNET_PSEUDONYM_id_to_name (cfg, &id1);
+ GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL);
CHECK (name1 != NULL);
- CHECK (0 != strcmp (name1, name2));
+ CHECK (0 == strcmp (name1, name2));
+ name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL);
+ name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL);
+ CHECK (0 != strcmp (name1_unique, name2_unique));
CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2));
- CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
- CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
+ CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
+ CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2));
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1));
CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode)));
CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode)));
@@ -168,14 +181,17 @@ main (int argc, char *argv[])
GNUNET_log_skip (1, GNUNET_NO);
CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0));
GNUNET_log_skip (0, GNUNET_YES);
- noname = GNUNET_PSEUDONYM_id_to_name (cfg, &fid);
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL, &noname, &noname_is_a_dup));
CHECK (noname != NULL);
+ CHECK (noname_is_a_dup == GNUNET_YES);
CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0));
CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10));
CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
GNUNET_free (name1);
GNUNET_free (name2);
+ GNUNET_free (name1_unique);
+ GNUNET_free (name2_unique);
GNUNET_free (name3);
GNUNET_free (noname);
/* END OF TEST CODE */
diff --git a/src/util/test_resolver_api.c b/src/util/test_resolver_api.c
index 67d5f46..4a3a203 100644
--- a/src/util/test_resolver_api.c
+++ b/src/util/test_resolver_api.c
@@ -64,10 +64,8 @@ check_localhost_num (void *cls, const char *hostname)
return;
if (0 == strcmp (hostname, "127.0.0.1"))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct hostname `%s'.\n",
hostname);
-#endif
(*ok) &= ~4;
}
else
@@ -88,10 +86,8 @@ check_localhost (void *cls, const char *hostname)
return;
if (0 == strcmp (hostname, "localhost"))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct hostname `%s'.\n",
hostname);
-#endif
(*ok) &= ~2;
}
else
@@ -113,9 +109,7 @@ check_127 (void *cls, const struct sockaddr *sa, socklen_t salen)
GNUNET_assert (sizeof (struct sockaddr_in) == salen);
if (sai->sin_addr.s_addr == htonl (INADDR_LOOPBACK))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct address.\n");
-#endif
(*ok) &= ~1;
}
else
@@ -142,10 +136,8 @@ check_local_fqdn (void *cls, const char *gnunet_fqdn)
"gethostname");
return;
}
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"),
hostname);
-#endif
host = gethostbyname (hostname);
if (NULL == host)
{
@@ -180,18 +172,14 @@ check_rootserver_ip (void *cls, const struct sockaddr *sa, socklen_t salen)
if (0 == strcmp (inet_ntoa (sai->sin_addr), ROOTSERVER_IP))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received correct rootserver ip address.\n");
-#endif
(*ok) &= ~1;
}
else
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received incorrect rootserver ip address.\n");
-#endif
GNUNET_break (0);
}
}
@@ -206,10 +194,8 @@ check_rootserver_name (void *cls, const char *hostname)
if (0 == strcmp (hostname, ROOTSERVER_NAME))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received correct rootserver hostname `%s'.\n", hostname);
-#endif
(*ok) &= ~2;
}
else
@@ -270,10 +256,8 @@ run (void *cls, char *const *args, const char *cfgfile,
count_ips++;
if (count_ips > 1)
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"IP received range for root name server, but a root name server has only 1 IP\n");
-#endif
GNUNET_break (0);
}
@@ -286,11 +270,8 @@ run (void *cls, char *const *args, const char *cfgfile,
"IP received and IP for root name server differ\n");
GNUNET_break (0);
}
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"System's own forward name resolution is working\n");
-#endif
-
/* Resolve the same using GNUNET */
GNUNET_RESOLVER_ip_get (ROOTSERVER_NAME, AF_INET, timeout,
&check_rootserver_ip, cls);
@@ -305,10 +286,8 @@ run (void *cls, char *const *args, const char *cfgfile,
rootserver->h_name = "";
if (1 != inet_pton (AF_INET, ROOTSERVER_IP, &rootserver_addr))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Could not transform root name server IP address\n");
-#endif
GNUNET_break (0);
}
@@ -326,19 +305,14 @@ run (void *cls, char *const *args, const char *cfgfile,
{
if (0 != strcmp (rootserver->h_name, ROOTSERVER_NAME))
{
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received hostname and hostname for root name server differ\n");
-#endif
GNUNET_break (0);
}
}
-#if DEBUG_RESOLVER
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"System's own reverse name resolution is working\n");
-#endif
-
/* Resolve the same using GNUNET */
memset (&sa, 0, sizeof (sa));
sa.sin_family = AF_INET;
@@ -410,7 +384,7 @@ check ()
ok = 1;
}
GNUNET_OS_process_wait (proc);
- GNUNET_OS_process_close (proc);
+ GNUNET_OS_process_destroy (proc);
proc = NULL;
if (ok != 0)
FPRINTF (stderr, "Missed some resolutions: %u\n", ok);
diff --git a/src/util/test_scheduler.c b/src/util/test_scheduler.c
index 01982ee..9832ade 100644
--- a/src/util/test_scheduler.c
+++ b/src/util/test_scheduler.c
@@ -30,37 +30,25 @@
#define VERBOSE GNUNET_NO
static void
-task3 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+task2 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
int *ok = cls;
- /* t4 should be ready (albeit with lower priority) */
+ /* t3 should be ready (albeit with lower priority) */
GNUNET_assert (1 ==
GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_COUNT));
- GNUNET_assert (3 == *ok);
- (*ok) = 4;
-}
-
-
-static void
-task2 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- int *ok = cls;
-
GNUNET_assert (2 == *ok);
(*ok) = 3;
- /* t3 will go before t4: higher priority */
- GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, &task3,
- cls);
}
+
static void
-task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+task3 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
int *ok = cls;
- GNUNET_assert (4 == *ok);
- (*ok) = 5;
+ GNUNET_assert (3 == *ok);
+ (*ok) = 4;
}
struct GNUNET_DISK_PipeHandle *p;
@@ -113,11 +101,11 @@ taskRd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static void
-task5 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
int *ok = cls;
- GNUNET_assert (5 == *ok);
+ GNUNET_assert (4 == *ok);
(*ok) = 6;
p = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
GNUNET_assert (NULL != p);
@@ -134,17 +122,13 @@ static void
task1 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
int *ok = cls;
- GNUNET_SCHEDULER_TaskIdentifier t2;
- GNUNET_SCHEDULER_TaskIdentifier t4;
GNUNET_assert (1 == *ok);
(*ok) = 2;
- /* t2 will go first -- prereq for all */
- t2 = GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_NO_TASK, &task2, cls);
- /* t4 will go after t2 ('add after') and after t3 (priority) */
- t4 = GNUNET_SCHEDULER_add_after (t2, &task4, cls);
- /* t5 will go last (after p4) */
- GNUNET_SCHEDULER_add_after (t4, &task5, cls);
+ GNUNET_SCHEDULER_add_now (&task3, cls);
+ GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, &task2,
+ cls);
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &task4, cls);
}
@@ -225,8 +209,8 @@ taskCancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_assert (1 == *ok);
*ok = 0;
- GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_add_after
- (GNUNET_SCHEDULER_NO_TASK, &taskNeverRun, NULL));
+ GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_add_now
+ (&taskNeverRun, NULL));
}
diff --git a/src/util/test_server.c b/src/util/test_server.c
index 6718c65..0faf61b 100644
--- a/src/util/test_server.c
+++ b/src/util/test_server.c
@@ -54,7 +54,7 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_assert (ok == 6);
ok = 0;
GNUNET_SERVER_destroy (server);
- GNUNET_CLIENT_disconnect (cc, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (cc);
GNUNET_CONFIGURATION_destroy (cfg);
}
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c
index 8010695..c54f9cb 100644
--- a/src/util/test_server_disconnect.c
+++ b/src/util/test_server_disconnect.c
@@ -51,7 +51,7 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_assert (ok == 5);
ok = 0;
GNUNET_SERVER_destroy (server);
- GNUNET_CLIENT_disconnect (cc, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (cc);
GNUNET_CONFIGURATION_destroy (cfg);
}
diff --git a/src/util/test_server_mst_interrupt.c b/src/util/test_server_mst_interrupt.c
new file mode 100644
index 0000000..fd34bd0
--- /dev/null
+++ b/src/util/test_server_mst_interrupt.c
@@ -0,0 +1,81 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file util/test_server_mst_interrupt.c
+ * @brief test for interrupt message processing in server_mst.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_protocols.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_scheduler_lib.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_time_lib.h"
+
+static struct GNUNET_SERVER_MessageStreamTokenizer * mst;
+static int ret;
+
+/* Callback destroying mst with data in buffer */
+static int
+mst_cb (void *cls, void *client,
+ const struct GNUNET_MessageHeader * message)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MST gave me message, destroying\n");
+ GNUNET_SERVER_mst_destroy (mst);
+ return GNUNET_SYSERR;
+}
+
+/**
+ * Main method
+ */
+static int
+check ()
+{
+
+ struct GNUNET_PeerIdentity id;
+ struct GNUNET_MessageHeader msg[2];
+
+ /* Prepare */
+ memset (&id, sizeof (id), '\0');
+ msg[0].size = htons (sizeof (msg));
+ msg[0].type = htons (sizeof (GNUNET_MESSAGE_TYPE_DUMMY));
+
+ mst = GNUNET_SERVER_mst_create(mst_cb, NULL);
+
+ GNUNET_SERVER_mst_receive(mst, &id, (const char *) &msg, 2 * sizeof (msg), GNUNET_NO, GNUNET_NO);
+
+ /* If we reach this line, it did not crash */
+ ret = 0;
+
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ret = 1;
+
+ GNUNET_log_setup ("test_server", "WARNING", NULL);
+ check ();
+
+ return ret;
+}
+
+/* end of test_server_mst_interrupt.c */
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c
index 06a4b71..ad56071 100644
--- a/src/util/test_server_with_client.c
+++ b/src/util/test_server_with_client.c
@@ -89,7 +89,7 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient,
break;
case 4:
ok++;
- GNUNET_CLIENT_disconnect (client, GNUNET_YES);
+ GNUNET_CLIENT_disconnect (client);
GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
break;
default:
diff --git a/src/util/test_server_with_client_unix.c b/src/util/test_server_with_client_unix.c
index 99af4e8..eae80e4 100644
--- a/src/util/test_server_with_client_unix.c
+++ b/src/util/test_server_with_client_unix.c
@@ -68,7 +68,7 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient,
break;
case 4:
ok++;
- GNUNET_CLIENT_disconnect (client, GNUNET_YES);
+ GNUNET_CLIENT_disconnect (client);
GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
break;
default:
diff --git a/src/util/test_service.c b/src/util/test_service.c
index 049282d..5547249 100644
--- a/src/util/test_service.c
+++ b/src/util/test_service.c
@@ -41,18 +41,49 @@ static struct GNUNET_SERVICE_Context *sctx;
static int ok = 1;
+static struct GNUNET_CLIENT_Connection *client;
+
+
+
+
+static void
+do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (NULL != client)
+ {
+ GNUNET_CLIENT_disconnect (client);
+ client = NULL;
+ }
+ if (NULL != sctx)
+ {
+ GNUNET_SERVICE_stop (sctx);
+ sctx = NULL;
+ }
+ else
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ }
+}
+
static size_t
build_msg (void *cls, size_t size, void *buf)
{
- struct GNUNET_CLIENT_Connection *client = cls;
struct GNUNET_MessageHeader *msg = buf;
+ if (size < sizeof (struct GNUNET_MessageHeader))
+ {
+ /* timeout */
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&do_stop, NULL);
+ ok = 1;
+ return 0;
+ }
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected, transmitting\n");
GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
msg->type = htons (MY_TYPE);
msg->size = htons (sizeof (struct GNUNET_MessageHeader));
- GNUNET_CLIENT_disconnect (client, GNUNET_NO);
return sizeof (struct GNUNET_MessageHeader);
}
@@ -61,7 +92,6 @@ static void
ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
- struct GNUNET_CLIENT_Connection *client;
GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service confirmed running\n");
@@ -72,27 +102,19 @@ ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CLIENT_notify_transmit_ready (client,
sizeof (struct GNUNET_MessageHeader),
GNUNET_TIME_UNIT_SECONDS, GNUNET_NO,
- &build_msg, client);
-}
-
-
-static void
-do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_SERVICE_stop (sctx);
+ &build_msg, NULL);
}
static void
-recv_cb (void *cls, struct GNUNET_SERVER_Client *client,
+recv_cb (void *cls, struct GNUNET_SERVER_Client *sc,
const struct GNUNET_MessageHeader *message)
{
+ if (NULL == message)
+ return;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- if (sctx != NULL)
- GNUNET_SCHEDULER_add_now (&do_stop, NULL);
- else
- GNUNET_SCHEDULER_shutdown ();
+ GNUNET_SERVER_receive_done (sc, GNUNET_OK);
+ GNUNET_SCHEDULER_add_now (&do_stop, NULL);
ok = 0;
}
@@ -146,7 +168,6 @@ static void
ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
- struct GNUNET_CLIENT_Connection *client;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n");
GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
@@ -156,7 +177,7 @@ ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CLIENT_notify_transmit_ready (client,
sizeof (struct GNUNET_MessageHeader),
GNUNET_TIME_UNIT_SECONDS, GNUNET_NO,
- &build_msg, client);
+ &build_msg, NULL);
}
static void
@@ -206,7 +227,7 @@ start_stop_main (void *cls, char *const *args, const char *cfgfile,
int *ret = cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting service using start method\n");
- sctx = GNUNET_SERVICE_start ("test_service", cfg);
+ sctx = GNUNET_SERVICE_start ("test_service", cfg, GNUNET_SERVICE_OPTION_NONE);
GNUNET_assert (NULL != sctx);
runner (cls, GNUNET_SERVICE_get_server (sctx), cfg);
*ret = 0;
@@ -257,7 +278,6 @@ main (int argc, char *argv[])
NULL);
ret += check ();
ret += check ();
-
// FIXME
#ifndef MINGW
s = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
@@ -280,7 +300,6 @@ main (int argc, char *argv[])
ret += check6 ();
}
ret += check_start_stop ();
-
return ret;
}
diff --git a/src/util/test_speedup.c b/src/util/test_speedup.c
new file mode 100644
index 0000000..03cffbd
--- /dev/null
+++ b/src/util/test_speedup.c
@@ -0,0 +1,120 @@
+/*
+ This file is part of GNUnet.
+ (C) 2001, 2002, 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file util/test_speedup.c
+ * @brief testcase for speedup.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_program_lib.h"
+#include "gnunet_time_lib.h"
+#include "gnunet_strings_lib.h"
+
+/**
+ * Start time of the testcase
+ */
+static struct GNUNET_TIME_Absolute start;
+
+/**
+ * End-time of the testcase (affected by speed-up)
+ */
+static struct GNUNET_TIME_Absolute end;
+
+/**
+ * Number of cycles we have spent in 'run'.
+ */
+static unsigned int cycles;
+
+
+/**
+ * Main task that is scheduled with the speed-up.
+ *
+ * @param cls NULL
+ * @param tc scheduler context, unused
+ */
+static void
+run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ cycles++;
+ fprintf (stderr, "..%u", cycles);
+ if (cycles <= 5)
+ {
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &run, NULL);
+ return;
+ }
+ end = GNUNET_TIME_absolute_get();
+ fprintf (stderr, "\n");
+ fflush(stdout);
+}
+
+
+/**
+ *
+ */
+static void
+check (void *cls, char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *
+ cfg)
+{
+ fprintf (stderr, "0");
+ fflush(stdout);
+ GNUNET_SCHEDULER_add_now(&run, NULL);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ static char *const argvn[] = { "test-speedup",
+ "-c", "test_speedup_data.conf",
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ time_t start_real;
+ time_t end_real;
+ struct GNUNET_TIME_Relative delta;
+
+ start_real = time (NULL);
+ start = GNUNET_TIME_absolute_get();
+ GNUNET_PROGRAM_run ((sizeof (argvn) / sizeof (char *)) - 1, argvn, "test-speedup",
+ "nohelp", options, &check, NULL);
+
+ end_real = time (NULL);
+ delta = GNUNET_TIME_absolute_get_difference(start, end);
+
+ if (delta.rel_value > ((end_real - start_real) * 1500LL))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Execution time in GNUnet time: %llu ms\n",
+ (unsigned long long) delta.rel_value);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Execution time in system time: %llu ms\n",
+ (unsigned long long) ((end_real - start_real) * 1000LL));
+ return 0;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Execution time in GNUnet time: %llu ms\n",
+ (unsigned long long) delta.rel_value);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Execution time in system time: %llu ms\n",
+ (unsigned long long) ((end_real - start_real) * 1000LL));
+ return 1;
+}
+
+/* end of test_speedup.c */
diff --git a/src/util/test_speedup_data.conf b/src/util/test_speedup_data.conf
new file mode 100644
index 0000000..699cdc9
--- /dev/null
+++ b/src/util/test_speedup_data.conf
@@ -0,0 +1,3 @@
+[testing]
+SPEEDUP_INTERVAL = 100 ms
+SPEEDUP_DELTA = 100 ms
diff --git a/src/util/test_strings.c b/src/util/test_strings.c
index 570776a..b662623 100644
--- a/src/util/test_strings.c
+++ b/src/util/test_strings.c
@@ -97,10 +97,12 @@ check ()
GNUNET_free (r);
b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII");
WANT ("TEST", b);
+#if ENABLE_NLS && HAVE_ICONV
GNUNET_log_skip (2, GNUNET_NO);
b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown");
GNUNET_log_skip (0, GNUNET_YES);
WANT ("TEST", b);
+#endif
return 0;
}
diff --git a/src/util/test_time.c b/src/util/test_time.c
index 788884f..b4c7233 100644
--- a/src/util/test_time.c
+++ b/src/util/test_time.c
@@ -43,9 +43,9 @@ check ()
struct GNUNET_TIME_RelativeNBO reln;
unsigned int i;
- forever = GNUNET_TIME_absolute_get_forever ();
- relForever = GNUNET_TIME_relative_get_forever ();
- relUnit = GNUNET_TIME_relative_get_unit ();
+ forever = GNUNET_TIME_UNIT_FOREVER_ABS;
+ relForever = GNUNET_TIME_UNIT_FOREVER_REL;
+ relUnit = GNUNET_TIME_UNIT_MILLISECONDS;
zero.abs_value = 0;
last = now = GNUNET_TIME_absolute_get ();
@@ -62,7 +62,7 @@ check ()
GNUNET_assert (rel.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value);
/*check zero */
rel.rel_value = (UINT64_MAX) - 1024;
- GNUNET_assert (GNUNET_TIME_relative_get_zero ().rel_value ==
+ GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value ==
GNUNET_TIME_relative_multiply (rel, 0).rel_value);
/* test infinity-check for relative to absolute */
@@ -77,7 +77,7 @@ check ()
GNUNET_TIME_relative_to_absolute (rel).abs_value);
/*check forever */
rel.rel_value = UINT64_MAX;
- GNUNET_assert (GNUNET_TIME_absolute_get_forever ().abs_value ==
+ GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value ==
GNUNET_TIME_relative_to_absolute (rel).abs_value);
/* check overflow for r2a */
rel.rel_value = (UINT64_MAX) - 1024;
@@ -125,8 +125,8 @@ check ()
rel = GNUNET_TIME_absolute_get_remaining (future);
GNUNET_assert (rel.rel_value > 0);
GNUNET_assert (rel.rel_value <= 1000000);
- forever = GNUNET_TIME_absolute_get_forever ();
- GNUNET_assert (GNUNET_TIME_relative_get_forever ().rel_value ==
+ forever = GNUNET_TIME_UNIT_FOREVER_ABS;
+ GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value ==
GNUNET_TIME_absolute_get_remaining (forever).rel_value);
/* check endianess */
@@ -175,13 +175,13 @@ check ()
/* check Return absolute time of 0ms */
- zero = GNUNET_TIME_absolute_get_zero ();
+ zero = GNUNET_TIME_UNIT_ZERO_ABS;
/* check GNUNET_TIME_calculate_eta */
last.abs_value = GNUNET_TIME_absolute_get ().abs_value - 1024;
- forever = GNUNET_TIME_absolute_get_forever ();
+ forever = GNUNET_TIME_UNIT_FOREVER_ABS;
forever.abs_value = forever.abs_value - 1024;
- GNUNET_assert (GNUNET_TIME_absolute_get_zero ().abs_value ==
+ GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value ==
GNUNET_TIME_calculate_eta (forever, 50000, 100000).rel_value);
/* check zero */
GNUNET_log_skip (1, GNUNET_NO);
@@ -199,11 +199,11 @@ check ()
GNUNET_assert (1024 ==
GNUNET_TIME_relative_subtract (relForever, rel).rel_value);
/*check zero */
- GNUNET_assert (GNUNET_TIME_relative_get_zero ().rel_value ==
+ GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value ==
GNUNET_TIME_relative_subtract (rel, relForever).rel_value);
/*check forever */
rel.rel_value = UINT64_MAX;
- GNUNET_assert (GNUNET_TIME_relative_get_forever ().rel_value ==
+ GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value ==
GNUNET_TIME_relative_subtract (rel, relForever).rel_value);
/*check GNUNET_TIME_relative_min */
diff --git a/src/util/time.c b/src/util/time.c
index c57ccd1..7467b44 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -68,7 +68,7 @@ GNUNET_TIME_absolute_get ()
* Return relative time of 0ms.
*/
struct GNUNET_TIME_Relative
-GNUNET_TIME_relative_get_zero ()
+GNUNET_TIME_relative_get_zero_ ()
{
static struct GNUNET_TIME_Relative zero;
@@ -80,28 +80,63 @@ GNUNET_TIME_relative_get_zero ()
* Return absolute time of 0ms.
*/
struct GNUNET_TIME_Absolute
-GNUNET_TIME_absolute_get_zero ()
+GNUNET_TIME_absolute_get_zero_ ()
{
static struct GNUNET_TIME_Absolute zero;
return zero;
}
+
/**
* Return relative time of 1ms.
*/
struct GNUNET_TIME_Relative
-GNUNET_TIME_relative_get_unit ()
+GNUNET_TIME_relative_get_unit_ ()
{
static struct GNUNET_TIME_Relative one = { 1 };
return one;
}
+
+/**
+ * Return relative time of 1s.
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_get_second_ ()
+{
+ static struct GNUNET_TIME_Relative one = { 1000 };
+ return one;
+}
+
+
+/**
+ * Return relative time of 1 minute.
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_get_minute_ ()
+{
+ static struct GNUNET_TIME_Relative one = { 60 * 1000 };
+ return one;
+}
+
+
+/**
+ * Return relative time of 1 hour.
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_get_hour_ ()
+{
+ static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 };
+ return one;
+}
+
+
/**
* Return "forever".
*/
struct GNUNET_TIME_Relative
-GNUNET_TIME_relative_get_forever ()
+GNUNET_TIME_relative_get_forever_ ()
{
static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
return forever;
@@ -111,7 +146,7 @@ GNUNET_TIME_relative_get_forever ()
* Return "forever".
*/
struct GNUNET_TIME_Absolute
-GNUNET_TIME_absolute_get_forever ()
+GNUNET_TIME_absolute_get_forever_ ()
{
static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
return forever;
@@ -129,13 +164,13 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
struct GNUNET_TIME_Absolute ret;
if (rel.rel_value == UINT64_MAX)
- return GNUNET_TIME_absolute_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_ABS;
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
if (rel.rel_value + now.abs_value < rel.rel_value)
{
GNUNET_break (0); /* overflow... */
- return GNUNET_TIME_absolute_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_ABS;
}
ret.abs_value = rel.rel_value + now.abs_value;
return ret;
@@ -193,7 +228,7 @@ GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
*
* @param t1 first timestamp
* @param t2 other timestamp
- * @return timestamp that is smaller
+ * @return timestamp that is bigger
*/
struct GNUNET_TIME_Absolute
GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
@@ -215,11 +250,11 @@ GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
struct GNUNET_TIME_Relative ret;
if (future.abs_value == UINT64_MAX)
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
if (now.abs_value > future.abs_value)
- return GNUNET_TIME_relative_get_zero ();
+ return GNUNET_TIME_UNIT_ZERO;
ret.rel_value = future.abs_value - now.abs_value;
return ret;
}
@@ -238,9 +273,9 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
struct GNUNET_TIME_Relative ret;
if (end.abs_value == UINT64_MAX)
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
if (end.abs_value < start.abs_value)
- return GNUNET_TIME_relative_get_zero ();
+ return GNUNET_TIME_UNIT_ZERO;
ret.rel_value = end.abs_value - start.abs_value;
return ret;
}
@@ -260,7 +295,7 @@ GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
now = GNUNET_TIME_absolute_get ();
GNUNET_assert (whence.abs_value != UINT64_MAX);
if (whence.abs_value > now.abs_value)
- return GNUNET_TIME_relative_get_zero ();
+ return GNUNET_TIME_UNIT_ZERO;
ret.rel_value = now.abs_value - whence.abs_value;
return ret;
}
@@ -279,11 +314,11 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
struct GNUNET_TIME_Absolute ret;
if ((start.abs_value == UINT64_MAX) || (duration.rel_value == UINT64_MAX))
- return GNUNET_TIME_absolute_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_ABS;
if (start.abs_value + duration.rel_value < start.abs_value)
{
GNUNET_break (0);
- return GNUNET_TIME_absolute_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_ABS;
}
ret.abs_value = start.abs_value + duration.rel_value;
return ret;
@@ -325,12 +360,12 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
struct GNUNET_TIME_Relative ret;
if (factor == 0)
- return GNUNET_TIME_relative_get_zero ();
+ return GNUNET_TIME_UNIT_ZERO;
ret.rel_value = rel.rel_value * (unsigned long long) factor;
if (ret.rel_value / factor != rel.rel_value)
{
GNUNET_break (0);
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
}
return ret;
}
@@ -401,11 +436,11 @@ GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
struct GNUNET_TIME_Relative ret;
if ((a1.rel_value == UINT64_MAX) || (a2.rel_value == UINT64_MAX))
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
if (a1.rel_value + a2.rel_value < a1.rel_value)
{
GNUNET_break (0);
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
}
ret.rel_value = a1.rel_value + a2.rel_value;
return ret;
@@ -426,9 +461,9 @@ GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
struct GNUNET_TIME_Relative ret;
if (a2.rel_value >= a1.rel_value)
- return GNUNET_TIME_relative_get_zero ();
+ return GNUNET_TIME_UNIT_ZERO;
if (a1.rel_value == UINT64_MAX)
- return GNUNET_TIME_relative_get_forever ();
+ return GNUNET_TIME_UNIT_FOREVER_REL;
ret.rel_value = a1.rel_value - a2.rel_value;
return ret;
}
diff --git a/src/util/util.conf b/src/util/util.conf
index ba9dfec..f3d301e 100644
--- a/src/util/util.conf
+++ b/src/util/util.conf
@@ -14,3 +14,5 @@ HOME = $SERVICEHOME
[TESTING]
WEAKRANDOM = NO
+SPEEDUP_INTERVAL = 0 ms
+SPEEDUP_DELTA = 0 ms
diff --git a/src/util/winproc.c b/src/util/winproc.c
index 7cd80a9..b75fc86 100644
--- a/src/util/winproc.c
+++ b/src/util/winproc.c
@@ -27,7 +27,6 @@
#include "platform.h"
#include "gnunet_common.h"
-#define DEBUG_WINPROC 0
#ifdef MINGW
@@ -146,7 +145,7 @@ GNInitWinEnv ()
plibc_initialized ();
plibc_set_panic_proc (plibc_panic);
- ret = plibc_init ("GNU", PACKAGE);
+ ret = plibc_init_utf8 ("GNU", PACKAGE, 1);
/* don't load other DLLs twice */
if (hNTDLL)