aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/Makefile.am142
-rw-r--r--src/namestore/Makefile.in489
-rw-r--r--src/namestore/gnunet-namestore.c507
-rw-r--r--src/namestore/gnunet-service-namestore.c1501
-rw-r--r--src/namestore/namestore.conf.in1
-rw-r--r--src/namestore/namestore.h441
-rw-r--r--src/namestore/namestore_api.c736
-rw-r--r--src/namestore/namestore_common.c582
-rw-r--r--src/namestore/plugin_namestore_sqlite.c352
-rw-r--r--src/namestore/test_hostkeybin0 -> 914 bytes
-rw-r--r--src/namestore/test_namestore_api.c35
-rw-r--r--src/namestore/test_namestore_api.conf7
-rw-r--r--src/namestore/test_namestore_api_create.c478
-rw-r--r--src/namestore/test_namestore_api_create_update.c517
-rw-r--r--src/namestore/test_namestore_api_lookup.c317
-rw-r--r--src/namestore/test_namestore_api_lookup_specific_type.c399
-rw-r--r--src/namestore/test_namestore_api_put.c249
-rw-r--r--src/namestore/test_namestore_api_remove.c366
-rw-r--r--src/namestore/test_namestore_api_remove_not_existing_record.c299
-rw-r--r--src/namestore/test_namestore_api_sign_verify.c150
-rw-r--r--src/namestore/test_namestore_api_zone_iteration.c334
-rw-r--r--src/namestore/test_namestore_api_zone_iteration_specific_zone.c451
-rw-r--r--src/namestore/test_namestore_api_zone_iteration_stop.c501
-rw-r--r--src/namestore/test_namestore_api_zone_to_name.c288
-rw-r--r--src/namestore/test_namestore_record_serialization.c29
-rw-r--r--src/namestore/test_plugin_namestore.c9
-rw-r--r--src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey (renamed from src/namestore/hostkey)bin913 -> 913 bytes
-rw-r--r--src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkeybin0 -> 914 bytes
28 files changed, 8334 insertions, 846 deletions
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 47517b9..7783506 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -2,10 +2,11 @@ INCLUDES = -I$(top_srcdir)/src/include
plugindir = $(libdir)/gnunet
-pkgcfgdir= $(pkgnamedir)/config.d/
+pkgcfgdir= $(pkgdatadir)/config.d/
+
+pkgcfg_DATA = \
+ namestore.conf
-pkgcfg_NAME = \
- namestore.conf
if MINGW
WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
@@ -24,19 +25,30 @@ endif
check_PROGRAMS = \
$(SQLITE_TESTS) \
+ test_namestore_record_serialization \
+ test_namestore_api_sign_verify \
test_namestore_api \
+ test_namestore_api_put \
+ test_namestore_api_lookup \
+ test_namestore_api_lookup_specific_type \
+ test_namestore_api_create \
+ test_namestore_api_create_update \
+ test_namestore_api_remove \
+ test_namestore_api_remove_not_existing_record \
+ test_namestore_api_zone_to_name \
test_namestore_api_zone_iteration \
- test_namestore_record_serialization
+ test_namestore_api_zone_iteration_specific_zone \
+ test_namestore_api_zone_iteration_stop
-if HAVE_EXPERIMENTAL
- check_PROGRAMS
+if ENABLE_TEST_RUN
+TESTS = $(check_PROGRAMS)
endif
lib_LTLIBRARIES = \
libgnunetnamestore.la
-
+
libgnunetnamestore_la_SOURCES = \
- namestore_api.c namestore.h
+ namestore_api.c namestore_common.c namestore.h
libgnunetnamestore_la_LIBADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
@@ -46,15 +58,34 @@ libgnunetnamestore_la_LDFLAGS = \
-version-info 0:0:0
bin_PROGRAMS = \
- gnunet-service-namestore
+ gnunet-service-namestore \
+ gnunet-namestore
+
+
+gnunet_namestore_SOURCES = \
+ gnunet-namestore.c
+gnunet_namestore_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la \
+ $(GN_LIBINTL)
+gnunet_namestore_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
+
+
gnunet_service_namestore_SOURCES = \
- gnunet-service-namestore.c \
- namestore_common.c
+ gnunet-service-namestore.c
+
gnunet_service_namestore_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la \
$(GN_LIBINTL)
+gnunet_service_namestore_DEPENDENCIES = \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
if HAVE_SQLITE
SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la
@@ -64,31 +95,100 @@ plugin_LTLIBRARIES = \
$(SQLITE_PLUGIN)
libgnunet_plugin_namestore_sqlite_la_SOURCES = \
- plugin_namestore_sqlite.c
+ plugin_namestore_sqlite.c namestore_common.c
libgnunet_plugin_namestore_sqlite_la_LIBADD = \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3
libgnunet_plugin_namestore_sqlite_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
+libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
+test_namestore_api_sign_verify_SOURCES = \
+ test_namestore_api_sign_verify.c
+test_namestore_api_sign_verify_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
test_namestore_api_SOURCES = \
- test_namestore_api.c \
- namestore_common.c
+ test_namestore_api.c
test_namestore_api_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
-
+
+test_namestore_api_put_SOURCES = \
+ test_namestore_api_put.c
+test_namestore_api_put_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_lookup_SOURCES = \
+ test_namestore_api_lookup.c
+test_namestore_api_lookup_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_lookup_specific_type_SOURCES = \
+ test_namestore_api_lookup_specific_type.c
+test_namestore_api_lookup_specific_type_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+
+test_namestore_api_create_SOURCES = \
+ test_namestore_api_create.c
+test_namestore_api_create_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_create_update_SOURCES = \
+ test_namestore_api_create_update.c
+test_namestore_api_create_update_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+
+test_namestore_api_remove_SOURCES = \
+ test_namestore_api_remove.c
+test_namestore_api_remove_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_remove_not_existing_record_SOURCES = \
+ test_namestore_api_remove_not_existing_record.c
+test_namestore_api_remove_not_existing_record_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_zone_to_name_SOURCES = \
+ test_namestore_api_zone_to_name.c
+test_namestore_api_zone_to_name_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
test_namestore_api_zone_iteration_SOURCES = \
- test_namestore_api_zone_iteration.c \
- namestore_common.c
+ test_namestore_api_zone_iteration.c
test_namestore_api_zone_iteration_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_zone_iteration_specific_zone_SOURCES = \
+ test_namestore_api_zone_iteration_specific_zone.c
+test_namestore_api_zone_iteration_specific_zone_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_zone_iteration_stop_SOURCES = \
+ test_namestore_api_zone_iteration_stop.c
+test_namestore_api_zone_iteration_stop_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
test_namestore_record_serialization_SOURCES = \
- test_namestore_record_serialization.c \
- namestore_common.c
+ test_namestore_record_serialization.c
test_namestore_record_serialization_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
@@ -96,7 +196,9 @@ test_namestore_record_serialization_LDADD = \
EXTRA_DIST = \
test_namestore_api.conf \
test_plugin_namestore_sqlite.conf\
- hostkey
+ test_hostkey \
+ zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey \
+ zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey
test_plugin_namestore_sqlite_SOURCES = \
diff --git a/src/namestore/Makefile.in b/src/namestore/Makefile.in
index 2ed2a46..180232d 100644
--- a/src/namestore/Makefile.in
+++ b/src/namestore/Makefile.in
@@ -16,6 +16,7 @@
@SET_MAKE@
+
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@@ -36,10 +37,22 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-check_PROGRAMS = $(am__EXEEXT_1) test_namestore_api$(EXEEXT) \
+check_PROGRAMS = $(am__EXEEXT_1) \
+ test_namestore_record_serialization$(EXEEXT) \
+ test_namestore_api_sign_verify$(EXEEXT) \
+ test_namestore_api$(EXEEXT) test_namestore_api_put$(EXEEXT) \
+ test_namestore_api_lookup$(EXEEXT) \
+ test_namestore_api_lookup_specific_type$(EXEEXT) \
+ test_namestore_api_create$(EXEEXT) \
+ test_namestore_api_create_update$(EXEEXT) \
+ test_namestore_api_remove$(EXEEXT) \
+ test_namestore_api_remove_not_existing_record$(EXEEXT) \
+ test_namestore_api_zone_to_name$(EXEEXT) \
test_namestore_api_zone_iteration$(EXEEXT) \
- test_namestore_record_serialization$(EXEEXT)
-bin_PROGRAMS = gnunet-service-namestore$(EXEEXT)
+ test_namestore_api_zone_iteration_specific_zone$(EXEEXT) \
+ test_namestore_api_zone_iteration_stop$(EXEEXT)
+bin_PROGRAMS = gnunet-service-namestore$(EXEEXT) \
+ gnunet-namestore$(EXEEXT)
subdir = src/namestore
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/namestore.conf.in
@@ -84,15 +97,11 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \
- "$(DESTDIR)$(bindir)"
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"
LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
-libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(am__DEPENDENCIES_1)
am_libgnunet_plugin_namestore_sqlite_la_OBJECTS = \
- plugin_namestore_sqlite.lo
+ plugin_namestore_sqlite.lo namestore_common.lo
libgnunet_plugin_namestore_sqlite_la_OBJECTS = \
$(am_libgnunet_plugin_namestore_sqlite_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
@@ -109,7 +118,8 @@ libgnunetnamestore_la_DEPENDENCIES = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(am__DEPENDENCIES_1)
-am_libgnunetnamestore_la_OBJECTS = namestore_api.lo
+am_libgnunetnamestore_la_OBJECTS = namestore_api.lo \
+ namestore_common.lo
libgnunetnamestore_la_OBJECTS = $(am_libgnunetnamestore_la_OBJECTS)
libgnunetnamestore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
@@ -118,31 +128,101 @@ libgnunetnamestore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@HAVE_SQLITE_TRUE@am__EXEEXT_1 = \
@HAVE_SQLITE_TRUE@ test_plugin_namestore_sqlite$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
+am_gnunet_namestore_OBJECTS = gnunet-namestore.$(OBJEXT)
+gnunet_namestore_OBJECTS = $(am_gnunet_namestore_OBJECTS)
am_gnunet_service_namestore_OBJECTS = \
- gnunet-service-namestore.$(OBJEXT) namestore_common.$(OBJEXT)
+ gnunet-service-namestore.$(OBJEXT)
gnunet_service_namestore_OBJECTS = \
$(am_gnunet_service_namestore_OBJECTS)
-gnunet_service_namestore_DEPENDENCIES = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(am__DEPENDENCIES_1)
-am_test_namestore_api_OBJECTS = test_namestore_api.$(OBJEXT) \
- namestore_common.$(OBJEXT)
+am_test_namestore_api_OBJECTS = test_namestore_api.$(OBJEXT)
test_namestore_api_OBJECTS = $(am_test_namestore_api_OBJECTS)
test_namestore_api_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_create_OBJECTS = \
+ test_namestore_api_create.$(OBJEXT)
+test_namestore_api_create_OBJECTS = \
+ $(am_test_namestore_api_create_OBJECTS)
+test_namestore_api_create_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_create_update_OBJECTS = \
+ test_namestore_api_create_update.$(OBJEXT)
+test_namestore_api_create_update_OBJECTS = \
+ $(am_test_namestore_api_create_update_OBJECTS)
+test_namestore_api_create_update_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_lookup_OBJECTS = \
+ test_namestore_api_lookup.$(OBJEXT)
+test_namestore_api_lookup_OBJECTS = \
+ $(am_test_namestore_api_lookup_OBJECTS)
+test_namestore_api_lookup_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_lookup_specific_type_OBJECTS = \
+ test_namestore_api_lookup_specific_type.$(OBJEXT)
+test_namestore_api_lookup_specific_type_OBJECTS = \
+ $(am_test_namestore_api_lookup_specific_type_OBJECTS)
+test_namestore_api_lookup_specific_type_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_put_OBJECTS = test_namestore_api_put.$(OBJEXT)
+test_namestore_api_put_OBJECTS = $(am_test_namestore_api_put_OBJECTS)
+test_namestore_api_put_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_remove_OBJECTS = \
+ test_namestore_api_remove.$(OBJEXT)
+test_namestore_api_remove_OBJECTS = \
+ $(am_test_namestore_api_remove_OBJECTS)
+test_namestore_api_remove_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_remove_not_existing_record_OBJECTS = \
+ test_namestore_api_remove_not_existing_record.$(OBJEXT)
+test_namestore_api_remove_not_existing_record_OBJECTS = \
+ $(am_test_namestore_api_remove_not_existing_record_OBJECTS)
+test_namestore_api_remove_not_existing_record_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_sign_verify_OBJECTS = \
+ test_namestore_api_sign_verify.$(OBJEXT)
+test_namestore_api_sign_verify_OBJECTS = \
+ $(am_test_namestore_api_sign_verify_OBJECTS)
+test_namestore_api_sign_verify_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
am_test_namestore_api_zone_iteration_OBJECTS = \
- test_namestore_api_zone_iteration.$(OBJEXT) \
- namestore_common.$(OBJEXT)
+ test_namestore_api_zone_iteration.$(OBJEXT)
test_namestore_api_zone_iteration_OBJECTS = \
$(am_test_namestore_api_zone_iteration_OBJECTS)
test_namestore_api_zone_iteration_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_zone_iteration_specific_zone_OBJECTS = \
+ test_namestore_api_zone_iteration_specific_zone.$(OBJEXT)
+test_namestore_api_zone_iteration_specific_zone_OBJECTS = \
+ $(am_test_namestore_api_zone_iteration_specific_zone_OBJECTS)
+test_namestore_api_zone_iteration_specific_zone_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_zone_iteration_stop_OBJECTS = \
+ test_namestore_api_zone_iteration_stop.$(OBJEXT)
+test_namestore_api_zone_iteration_stop_OBJECTS = \
+ $(am_test_namestore_api_zone_iteration_stop_OBJECTS)
+test_namestore_api_zone_iteration_stop_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+am_test_namestore_api_zone_to_name_OBJECTS = \
+ test_namestore_api_zone_to_name.$(OBJEXT)
+test_namestore_api_zone_to_name_OBJECTS = \
+ $(am_test_namestore_api_zone_to_name_OBJECTS)
+test_namestore_api_zone_to_name_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
am_test_namestore_record_serialization_OBJECTS = \
- test_namestore_record_serialization.$(OBJEXT) \
- namestore_common.$(OBJEXT)
+ test_namestore_record_serialization.$(OBJEXT)
test_namestore_record_serialization_OBJECTS = \
$(am_test_namestore_record_serialization_OBJECTS)
test_namestore_record_serialization_DEPENDENCIES = \
@@ -181,21 +261,46 @@ AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libgnunet_plugin_namestore_sqlite_la_SOURCES) \
- $(libgnunetnamestore_la_SOURCES) \
+ $(libgnunetnamestore_la_SOURCES) $(gnunet_namestore_SOURCES) \
$(gnunet_service_namestore_SOURCES) \
$(test_namestore_api_SOURCES) \
+ $(test_namestore_api_create_SOURCES) \
+ $(test_namestore_api_create_update_SOURCES) \
+ $(test_namestore_api_lookup_SOURCES) \
+ $(test_namestore_api_lookup_specific_type_SOURCES) \
+ $(test_namestore_api_put_SOURCES) \
+ $(test_namestore_api_remove_SOURCES) \
+ $(test_namestore_api_remove_not_existing_record_SOURCES) \
+ $(test_namestore_api_sign_verify_SOURCES) \
$(test_namestore_api_zone_iteration_SOURCES) \
+ $(test_namestore_api_zone_iteration_specific_zone_SOURCES) \
+ $(test_namestore_api_zone_iteration_stop_SOURCES) \
+ $(test_namestore_api_zone_to_name_SOURCES) \
$(test_namestore_record_serialization_SOURCES) \
$(test_plugin_namestore_sqlite_SOURCES)
DIST_SOURCES = $(libgnunet_plugin_namestore_sqlite_la_SOURCES) \
- $(libgnunetnamestore_la_SOURCES) \
+ $(libgnunetnamestore_la_SOURCES) $(gnunet_namestore_SOURCES) \
$(gnunet_service_namestore_SOURCES) \
$(test_namestore_api_SOURCES) \
+ $(test_namestore_api_create_SOURCES) \
+ $(test_namestore_api_create_update_SOURCES) \
+ $(test_namestore_api_lookup_SOURCES) \
+ $(test_namestore_api_lookup_specific_type_SOURCES) \
+ $(test_namestore_api_put_SOURCES) \
+ $(test_namestore_api_remove_SOURCES) \
+ $(test_namestore_api_remove_not_existing_record_SOURCES) \
+ $(test_namestore_api_sign_verify_SOURCES) \
$(test_namestore_api_zone_iteration_SOURCES) \
+ $(test_namestore_api_zone_iteration_specific_zone_SOURCES) \
+ $(test_namestore_api_zone_iteration_stop_SOURCES) \
+ $(test_namestore_api_zone_to_name_SOURCES) \
$(test_namestore_record_serialization_SOURCES) \
$(test_plugin_namestore_sqlite_SOURCES)
+DATA = $(pkgcfg_DATA)
ETAGS = etags
CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -252,6 +357,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+JAVAPORT = @JAVAPORT@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBADD_DL = @LIBADD_DL@
@@ -285,6 +391,7 @@ LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+MONKEYPREFIX = @MONKEYPREFIX@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
@@ -403,9 +510,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
INCLUDES = -I$(top_srcdir)/src/include
plugindir = $(libdir)/gnunet
-pkgcfgdir = $(pkgnamedir)/config.d/
-pkgcfg_NAME = \
- namestore.conf
+pkgcfgdir = $(pkgdatadir)/config.d/
+pkgcfg_DATA = \
+ namestore.conf
@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0
@@ -413,11 +520,12 @@ pkgcfg_NAME = \
@HAVE_SQLITE_TRUE@SQLITE_TESTS = \
@HAVE_SQLITE_TRUE@ test_plugin_namestore_sqlite
+@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS)
lib_LTLIBRARIES = \
libgnunetnamestore.la
libgnunetnamestore_la_SOURCES = \
- namestore_api.c namestore.h
+ namestore_api.c namestore_common.c namestore.h
libgnunetnamestore_la_LIBADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
@@ -428,48 +536,145 @@ libgnunetnamestore_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
-version-info 0:0:0
+gnunet_namestore_SOURCES = \
+ gnunet-namestore.c
+
+gnunet_namestore_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la \
+ $(GN_LIBINTL)
+
+gnunet_namestore_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
+
gnunet_service_namestore_SOURCES = \
- gnunet-service-namestore.c \
- namestore_common.c
+ gnunet-service-namestore.c
gnunet_service_namestore_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la \
$(GN_LIBINTL)
+gnunet_service_namestore_DEPENDENCIES = \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
+
@HAVE_SQLITE_TRUE@SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la
plugin_LTLIBRARIES = \
$(SQLITE_PLUGIN)
libgnunet_plugin_namestore_sqlite_la_SOURCES = \
- plugin_namestore_sqlite.c
+ plugin_namestore_sqlite.c namestore_common.c
libgnunet_plugin_namestore_sqlite_la_LIBADD = \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3
libgnunet_plugin_namestore_sqlite_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
+libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetnamestore.la
+
+test_namestore_api_sign_verify_SOURCES = \
+ test_namestore_api_sign_verify.c
+
+test_namestore_api_sign_verify_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
test_namestore_api_SOURCES = \
- test_namestore_api.c \
- namestore_common.c
+ test_namestore_api.c
test_namestore_api_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
+test_namestore_api_put_SOURCES = \
+ test_namestore_api_put.c
+
+test_namestore_api_put_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_lookup_SOURCES = \
+ test_namestore_api_lookup.c
+
+test_namestore_api_lookup_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_lookup_specific_type_SOURCES = \
+ test_namestore_api_lookup_specific_type.c
+
+test_namestore_api_lookup_specific_type_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_create_SOURCES = \
+ test_namestore_api_create.c
+
+test_namestore_api_create_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_create_update_SOURCES = \
+ test_namestore_api_create_update.c
+
+test_namestore_api_create_update_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_remove_SOURCES = \
+ test_namestore_api_remove.c
+
+test_namestore_api_remove_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_remove_not_existing_record_SOURCES = \
+ test_namestore_api_remove_not_existing_record.c
+
+test_namestore_api_remove_not_existing_record_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_zone_to_name_SOURCES = \
+ test_namestore_api_zone_to_name.c
+
+test_namestore_api_zone_to_name_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
test_namestore_api_zone_iteration_SOURCES = \
- test_namestore_api_zone_iteration.c \
- namestore_common.c
+ test_namestore_api_zone_iteration.c
test_namestore_api_zone_iteration_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/namestore/libgnunetnamestore.la
+test_namestore_api_zone_iteration_specific_zone_SOURCES = \
+ test_namestore_api_zone_iteration_specific_zone.c
+
+test_namestore_api_zone_iteration_specific_zone_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
+test_namestore_api_zone_iteration_stop_SOURCES = \
+ test_namestore_api_zone_iteration_stop.c
+
+test_namestore_api_zone_iteration_stop_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la
+
test_namestore_record_serialization_SOURCES = \
- test_namestore_record_serialization.c \
- namestore_common.c
+ test_namestore_record_serialization.c
test_namestore_record_serialization_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
@@ -478,7 +683,9 @@ test_namestore_record_serialization_LDADD = \
EXTRA_DIST = \
test_namestore_api.conf \
test_plugin_namestore_sqlite.conf\
- hostkey
+ test_hostkey \
+ zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey \
+ zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey
test_plugin_namestore_sqlite_SOURCES = \
test_plugin_namestore.c
@@ -640,15 +847,51 @@ clean-checkPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+gnunet-namestore$(EXEEXT): $(gnunet_namestore_OBJECTS) $(gnunet_namestore_DEPENDENCIES)
+ @rm -f gnunet-namestore$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gnunet_namestore_OBJECTS) $(gnunet_namestore_LDADD) $(LIBS)
gnunet-service-namestore$(EXEEXT): $(gnunet_service_namestore_OBJECTS) $(gnunet_service_namestore_DEPENDENCIES)
@rm -f gnunet-service-namestore$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gnunet_service_namestore_OBJECTS) $(gnunet_service_namestore_LDADD) $(LIBS)
test_namestore_api$(EXEEXT): $(test_namestore_api_OBJECTS) $(test_namestore_api_DEPENDENCIES)
@rm -f test_namestore_api$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_namestore_api_OBJECTS) $(test_namestore_api_LDADD) $(LIBS)
+test_namestore_api_create$(EXEEXT): $(test_namestore_api_create_OBJECTS) $(test_namestore_api_create_DEPENDENCIES)
+ @rm -f test_namestore_api_create$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_create_OBJECTS) $(test_namestore_api_create_LDADD) $(LIBS)
+test_namestore_api_create_update$(EXEEXT): $(test_namestore_api_create_update_OBJECTS) $(test_namestore_api_create_update_DEPENDENCIES)
+ @rm -f test_namestore_api_create_update$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_create_update_OBJECTS) $(test_namestore_api_create_update_LDADD) $(LIBS)
+test_namestore_api_lookup$(EXEEXT): $(test_namestore_api_lookup_OBJECTS) $(test_namestore_api_lookup_DEPENDENCIES)
+ @rm -f test_namestore_api_lookup$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_lookup_OBJECTS) $(test_namestore_api_lookup_LDADD) $(LIBS)
+test_namestore_api_lookup_specific_type$(EXEEXT): $(test_namestore_api_lookup_specific_type_OBJECTS) $(test_namestore_api_lookup_specific_type_DEPENDENCIES)
+ @rm -f test_namestore_api_lookup_specific_type$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_lookup_specific_type_OBJECTS) $(test_namestore_api_lookup_specific_type_LDADD) $(LIBS)
+test_namestore_api_put$(EXEEXT): $(test_namestore_api_put_OBJECTS) $(test_namestore_api_put_DEPENDENCIES)
+ @rm -f test_namestore_api_put$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_put_OBJECTS) $(test_namestore_api_put_LDADD) $(LIBS)
+test_namestore_api_remove$(EXEEXT): $(test_namestore_api_remove_OBJECTS) $(test_namestore_api_remove_DEPENDENCIES)
+ @rm -f test_namestore_api_remove$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_remove_OBJECTS) $(test_namestore_api_remove_LDADD) $(LIBS)
+test_namestore_api_remove_not_existing_record$(EXEEXT): $(test_namestore_api_remove_not_existing_record_OBJECTS) $(test_namestore_api_remove_not_existing_record_DEPENDENCIES)
+ @rm -f test_namestore_api_remove_not_existing_record$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_remove_not_existing_record_OBJECTS) $(test_namestore_api_remove_not_existing_record_LDADD) $(LIBS)
+test_namestore_api_sign_verify$(EXEEXT): $(test_namestore_api_sign_verify_OBJECTS) $(test_namestore_api_sign_verify_DEPENDENCIES)
+ @rm -f test_namestore_api_sign_verify$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_sign_verify_OBJECTS) $(test_namestore_api_sign_verify_LDADD) $(LIBS)
test_namestore_api_zone_iteration$(EXEEXT): $(test_namestore_api_zone_iteration_OBJECTS) $(test_namestore_api_zone_iteration_DEPENDENCIES)
@rm -f test_namestore_api_zone_iteration$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_OBJECTS) $(test_namestore_api_zone_iteration_LDADD) $(LIBS)
+test_namestore_api_zone_iteration_specific_zone$(EXEEXT): $(test_namestore_api_zone_iteration_specific_zone_OBJECTS) $(test_namestore_api_zone_iteration_specific_zone_DEPENDENCIES)
+ @rm -f test_namestore_api_zone_iteration_specific_zone$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_specific_zone_OBJECTS) $(test_namestore_api_zone_iteration_specific_zone_LDADD) $(LIBS)
+test_namestore_api_zone_iteration_stop$(EXEEXT): $(test_namestore_api_zone_iteration_stop_OBJECTS) $(test_namestore_api_zone_iteration_stop_DEPENDENCIES)
+ @rm -f test_namestore_api_zone_iteration_stop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_stop_OBJECTS) $(test_namestore_api_zone_iteration_stop_LDADD) $(LIBS)
+test_namestore_api_zone_to_name$(EXEEXT): $(test_namestore_api_zone_to_name_OBJECTS) $(test_namestore_api_zone_to_name_DEPENDENCIES)
+ @rm -f test_namestore_api_zone_to_name$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_to_name_OBJECTS) $(test_namestore_api_zone_to_name_LDADD) $(LIBS)
test_namestore_record_serialization$(EXEEXT): $(test_namestore_record_serialization_OBJECTS) $(test_namestore_record_serialization_DEPENDENCIES)
@rm -f test_namestore_record_serialization$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_namestore_record_serialization_OBJECTS) $(test_namestore_record_serialization_LDADD) $(LIBS)
@@ -662,12 +905,24 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-namestore.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-namestore.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_api.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_namestore_sqlite.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_create.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_create_update.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_lookup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_lookup_specific_type.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_put.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_remove.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_remove_not_existing_record.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_sign_verify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration_specific_zone.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration_stop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_to_name.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_record_serialization.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_namestore.Po@am__quote@
@@ -700,6 +955,26 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
+install-pkgcfgDATA: $(pkgcfg_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)"
+ @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \
+ done
+
+uninstall-pkgcfgDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -753,6 +1028,98 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -785,12 +1152,13 @@ distdir: $(DISTFILES)
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
install-binPROGRAMS: install-libLTLIBRARIES
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)"; do \
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -842,7 +1210,7 @@ info: info-am
info-am:
-install-data-am: install-pluginLTLIBRARIES
+install-data-am: install-pkgcfgDATA install-pluginLTLIBRARIES
install-dvi: install-dvi-am
@@ -889,29 +1257,28 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
- uninstall-pluginLTLIBRARIES
+ uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES
.MAKE: check-am install-am install-strip
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
- clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool clean-pluginLTLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-binPROGRAMS install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-pluginLTLIBRARIES install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
- uninstall-pluginLTLIBRARIES
-
-
-@HAVE_EXPERIMENTAL_TRUE@ check_PROGRAMS
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-man install-pdf install-pdf-am install-pkgcfgDATA \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+ uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
new file mode 100644
index 0000000..a0d1de1
--- /dev/null
+++ b/src/namestore/gnunet-namestore.c
@@ -0,0 +1,507 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file gnunet-namestore.c
+ * @brief command line tool to manipulate the local zone
+ * @author Christian Grothoff
+ *
+ * TODO:
+ * - allow users to set record options (not just 'RF_AUTHORITY')
+ * - test
+ * - add options to list/lookup individual records
+ */
+#include "platform.h"
+#include <gnunet_util_lib.h>
+#include <gnunet_dnsparser_lib.h>
+#include <gnunet_namestore_service.h>
+
+/**
+ * Handle to the namestore.
+ */
+static struct GNUNET_NAMESTORE_Handle *ns;
+
+/**
+ * Hash of the public key of our zone.
+ */
+static struct GNUNET_CRYPTO_ShortHashCode zone;
+
+/**
+ * Private key for the our zone.
+ */
+static struct GNUNET_CRYPTO_RsaPrivateKey *zone_pkey;
+
+/**
+ * Keyfile to manipulate.
+ */
+static char *keyfile;
+
+/**
+ * Desired action is to add a record.
+ */
+static int add;
+
+/**
+ * Queue entry for the 'add' operation.
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
+
+/**
+ * Desired action is to list records.
+ */
+static int list;
+
+/**
+ * List iterator for the 'list' operation.
+ */
+static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
+
+/**
+ * Desired action is to remove a record.
+ */
+static int del;
+
+/**
+ * Is record public
+ */
+static int public;
+
+/**
+ * Is record authority
+ */
+static int nonauthority;
+
+/**
+ * Queue entry for the 'del' operation.
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
+
+/**
+ * Name of the records to add/list/remove.
+ */
+static char *name;
+
+/**
+ * Value of the record to add/remove.
+ */
+static char *value;
+
+/**
+ * Type of the record to add/remove, NULL to remove all.
+ */
+static char *typestring;
+
+/**
+ * Desired expiration time.
+ */
+static char *expirationstring;
+
+
+/**
+ * Task run on shutdown. Cleans up everything.
+ *
+ * @param cls unused
+ * @param tc scheduler context
+ */
+static void
+do_shutdown (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (NULL != ns)
+ {
+ GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO);
+ ns = NULL;
+ }
+ if (NULL != zone_pkey)
+ {
+ GNUNET_CRYPTO_rsa_key_free (zone_pkey);
+ zone_pkey = NULL;
+ }
+}
+
+
+/**
+ * Continuation called to notify client about result of the
+ * operation.
+ *
+ * @param cls closure, unused
+ * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ * GNUNET_NO if content was already there
+ * GNUNET_YES (or other positive value) on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+static void
+add_continuation (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ add_qe = NULL;
+ if (success != GNUNET_YES)
+ fprintf (stderr,
+ _("Adding record failed: %s\n"),
+ (success == GNUNET_NO) ? "record exists" : emsg);
+ if ( (NULL == del_qe) &&
+ (NULL == list_it) )
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Continuation called to notify client about result of the
+ * operation.
+ *
+ * @param cls closure, unused
+ * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ * GNUNET_NO if content was already there
+ * GNUNET_YES (or other positive value) on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+static void
+del_continuation (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ del_qe = NULL;
+ if (success != GNUNET_YES)
+ fprintf (stderr,
+ _("Deleting record failed: %s\n"),
+ emsg);
+ if ( (NULL == add_qe) &&
+ (NULL == list_it) )
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Process a record that was stored in the namestore.
+ *
+ * @param cls closure
+ * @param zone_key public key of the zone
+ * @param expire when does the corresponding block in the DHT expire (until
+ * when should we never do a DHT lookup for the same name again)?;
+ * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
+ * or the expiration time of the block in the namestore (even if there are zero
+ * records matching the desired record type)
+ * @param name name that is being mapped (at most 255 characters long)
+ * @param rd_len number of entries in 'rd' array
+ * @param rd array of records with data to store
+ * @param signature signature of the record block, NULL if signature is unavailable (i.e.
+ * because the user queried for a particular record type only)
+ */
+static void
+display_record (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_len,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ const char *typestring;
+ char *s;
+ unsigned int i;
+
+ if (NULL == name)
+ {
+ list_it = NULL;
+ if ( (NULL == del_qe) &&
+ (NULL == add_qe) )
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ FPRINTF (stdout,
+ "%s:\n",
+ name);
+ for (i=0;i<rd_len;i++)
+ {
+ typestring = GNUNET_NAMESTORE_number_to_typename (rd[i].record_type);
+ s = GNUNET_NAMESTORE_value_to_string (rd[i].record_type,
+ rd[i].data,
+ rd[i].data_size);
+ if (NULL == s)
+ {
+ FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
+ (unsigned int) rd[i].record_type);
+ continue;
+ }
+ FPRINTF (stdout, "\t%s: %s\n", typestring, s);
+ GNUNET_free (s);
+ }
+ FPRINTF (stdout, "%s", "\n");
+ GNUNET_NAMESTORE_zone_iterator_next (list_it);
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ uint32_t type;
+ void *data = NULL;
+ size_t data_size = 0;
+ struct GNUNET_TIME_Relative etime;
+ struct GNUNET_NAMESTORE_RecordData rd;
+
+ if (NULL == keyfile)
+ {
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+ "ZONEKEY", &keyfile))
+ {
+ fprintf (stderr,
+ _("Option `%s' not given, but I need a zone key file!\n"),
+ "z");
+ return;
+ }
+ fprintf (stderr,
+ _("Using default zone file `%s'\n"),
+ keyfile);
+ }
+ zone_pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+ GNUNET_free (keyfile);
+ keyfile = NULL;
+ if (! (add|del|list))
+ {
+ /* nothing more to be done */
+ fprintf (stderr,
+ _("No options given\n"));
+ GNUNET_CRYPTO_rsa_key_free (zone_pkey);
+ zone_pkey = NULL;
+ return;
+ }
+ if (NULL == zone_pkey)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to read or create private zone key\n"));
+ return;
+ }
+ GNUNET_CRYPTO_rsa_key_get_public (zone_pkey,
+ &pub);
+ GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &zone);
+
+ ns = GNUNET_NAMESTORE_connect (cfg);
+ if (NULL == ns)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to connect to namestore\n"));
+ return;
+ }
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &do_shutdown, NULL);
+ if (NULL == typestring)
+ type = 0;
+ else
+ type = GNUNET_NAMESTORE_typename_to_number (typestring);
+ if (UINT32_MAX == type)
+ {
+ fprintf (stderr, _("Unsupported type `%s'\n"), typestring);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if ((NULL == typestring) && (add | del))
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-t", _("add/del"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if (NULL != value)
+ {
+ if (GNUNET_OK !=
+ GNUNET_NAMESTORE_string_to_value (type,
+ value,
+ &data,
+ &data_size))
+ {
+ fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
+ value,
+ typestring);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ } else if (add | del)
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-V", _("add/del"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if (NULL != expirationstring)
+ {
+ if (0 == strcmp (expirationstring, "never"))
+ {
+ etime = GNUNET_TIME_UNIT_FOREVER_REL;
+ }
+ else if (GNUNET_OK !=
+ GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
+ &etime))
+ {
+ fprintf (stderr,
+ _("Invalid time format `%s'\n"),
+ expirationstring);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ } else if (add)
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-e", _("add"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if (add)
+ {
+ if (NULL == name)
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-n", _("add"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ rd.data = data;
+ rd.data_size = data_size;
+ rd.record_type = type;
+ rd.expiration = GNUNET_TIME_relative_to_absolute (etime);
+ if (1 != nonauthority)
+ rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
+ if (1 != public)
+ rd.flags |= GNUNET_NAMESTORE_RF_PRIVATE;
+ add_qe = GNUNET_NAMESTORE_record_create (ns,
+ zone_pkey,
+ name,
+ &rd,
+ &add_continuation,
+ NULL);
+ }
+ if (del)
+ {
+ if (NULL == name)
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-n", _("del"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ rd.data = data;
+ rd.data_size = data_size;
+ rd.record_type = type;
+ rd.expiration.abs_value = 0;
+ rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
+ del_qe = GNUNET_NAMESTORE_record_remove (ns,
+ zone_pkey,
+ name,
+ &rd,
+ &del_continuation,
+ NULL);
+ }
+ if (list)
+ {
+ uint32_t must_not_flags = 0;
+
+ if (1 == nonauthority) /* List non-authority records */
+ must_not_flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
+
+ if (1 == public)
+ must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
+
+ list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
+ &zone,
+ 0,
+ must_not_flags,
+ &display_record,
+ NULL);
+ }
+ GNUNET_free_non_null (data);
+}
+
+
+/**
+ * The main function for gnunet-namestore.
+ *
+ * @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)
+{
+ nonauthority = -1;
+ public = -1;
+
+ static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ {'a', "add", NULL,
+ gettext_noop ("add record"), 0,
+ &GNUNET_GETOPT_set_one, &add},
+ {'d', "delete", NULL,
+ gettext_noop ("delete record"), 0,
+ &GNUNET_GETOPT_set_one, &del},
+ {'D', "display", NULL,
+ gettext_noop ("display records"), 0,
+ &GNUNET_GETOPT_set_one, &list},
+ {'e', "expiration", "TIME",
+ gettext_noop ("expiration time for record to use (for adding only), \"never\" is possible"), 1,
+ &GNUNET_GETOPT_set_string, &expirationstring},
+ {'n', "name", "NAME",
+ gettext_noop ("name of the record to add/delete/display"), 1,
+ &GNUNET_GETOPT_set_string, &name},
+ {'t', "type", "TYPE",
+ gettext_noop ("type of the record to add/delete/display"), 1,
+ &GNUNET_GETOPT_set_string, &typestring},
+ {'V', "value", "VALUE",
+ gettext_noop ("value of the record to add/delete"), 1,
+ &GNUNET_GETOPT_set_string, &value},
+ {'p', "public", NULL,
+ gettext_noop ("create or list public record"), 0,
+ &GNUNET_GETOPT_set_one, &public},
+ {'N', "non-authority", NULL,
+ gettext_noop ("create or list non-authority record"), 0,
+ &GNUNET_GETOPT_set_one, &nonauthority},
+ {'z', "zonekey", "FILENAME",
+ gettext_noop ("filename with the zone key"), 1,
+ &GNUNET_GETOPT_set_string, &keyfile},
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ int ret;
+
+ GNUNET_log_setup ("gnunet-namestore", "WARNING", NULL);
+ ret =
+ (GNUNET_OK ==
+ GNUNET_PROGRAM_run (argc, argv, "gnunet-namestore",
+ _("GNUnet zone manipulation tool"),
+ options,
+ &run, NULL)) ? 0 : 1;
+
+ return ret;
+}
+
+/* end of gnunet-namestore.c */
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 92eb218..d6c2998 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -28,9 +28,10 @@
#include "gnunet_service_lib.h"
#include "gnunet_namestore_service.h"
#include "gnunet_namestore_plugin.h"
+#include "gnunet_signatures.h"
#include "namestore.h"
-
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
/**
* A namestore operation.
@@ -42,11 +43,22 @@ struct GNUNET_NAMESTORE_ZoneIteration
struct GNUNET_NAMESTORE_Client * client;
- GNUNET_HashCode zone;
+ int has_zone;
+
+ struct GNUNET_CRYPTO_ShortHashCode zone;
- uint64_t op_id;
+ uint64_t request_id;
uint32_t offset;
+ /**
+ * Which flags must be included
+ */
+ uint16_t must_have_flags;
+
+ /**
+ * Which flags must not be included
+ */
+ uint16_t must_not_have_flags;
};
@@ -64,25 +76,165 @@ struct GNUNET_NAMESTORE_Client
struct GNUNET_NAMESTORE_ZoneIteration *op_tail;
};
+struct GNUNET_NAMESTORE_CryptoContainer
+{
+ char * filename;
+
+ struct GNUNET_CRYPTO_ShortHashCode zone;
+ struct GNUNET_CRYPTO_RsaPrivateKey *privkey;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
+};
/**
- * Configuration handle.
- */
+* Configuration handle.
+*/
const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
-static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
+/**
+* Database handle
+*/
+struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
+
+/**
+* Zonefile directory
+*/
+static char *zonefile_directory;
+
+static char *db_lib_name;
+
/**
* Our notification context.
*/
static struct GNUNET_SERVER_NotificationContext *snc;
-static char *db_lib_name;
-
static struct GNUNET_NAMESTORE_Client *client_head;
static struct GNUNET_NAMESTORE_Client *client_tail;
+struct GNUNET_CONTAINER_MultiHashMap *zonekeys;
+
+
+/**
+ * Write zonefile to disk
+ * @param filename where to write
+ * @param c the crypto container
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on fail
+ */
+
+int
+write_key_to_file (const char *filename, struct GNUNET_NAMESTORE_CryptoContainer *c)
+{
+ struct GNUNET_CRYPTO_RsaPrivateKey *ret = c->privkey;
+ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc;
+ struct GNUNET_DISK_FileHandle *fd;
+
+ if (GNUNET_YES == GNUNET_DISK_file_test (filename))
+ {
+ struct GNUNET_CRYPTO_ShortHashCode zone;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+ struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
+ if (privkey == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("File zone `%s' but corrupt content already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
+ return GNUNET_SYSERR;
+ }
+
+ GNUNET_CRYPTO_rsa_key_get_public (privkey, &pubkey);
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone);
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+
+ if (0 == memcmp (&zone, &c->zone, sizeof(zone)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("File zone `%s' containing this key already exists\n"), GNUNET_short_h2s (&zone));
+ return GNUNET_OK;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("File zone `%s' but different zone key already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
+ return GNUNET_OK;
+ }
+ }
+ fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
+ if (NULL == fd)
+ {
+ if (errno == EEXIST)
+ {
+ if (GNUNET_YES != GNUNET_DISK_file_test (filename))
+ {
+ /* must exist but not be accessible, fail for good! */
+ if (0 != ACCESS (filename, R_OK))
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
+ else
+ GNUNET_break (0); /* what is going on!? */
+ return GNUNET_SYSERR;
+ }
+ }
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
+ return GNUNET_SYSERR;
+ }
+
+ if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_YES))
+ {
+ GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
+ return GNUNET_SYSERR;
+ }
+ enc = GNUNET_CRYPTO_rsa_encode_key (ret);
+ GNUNET_assert (enc != NULL);
+ GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
+ GNUNET_free (enc);
+ GNUNET_DISK_file_sync (fd);
+ if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+ GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Stored zonekey for zone `%s' in file `%s'\n"), GNUNET_short_h2s(&c->zone), c->filename);
+ return GNUNET_OK;
+}
+
+int zone_to_disk_it (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_NAMESTORE_CryptoContainer * c = value;
+ if (c->filename != NULL)
+ write_key_to_file(c->filename, c);
+ else
+ {
+ GNUNET_asprintf(&c->filename, "%s/%s.zkey", zonefile_directory, GNUNET_short_h2s (&c->zone));
+ write_key_to_file(c->filename, c);
+ }
+
+
+ GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value));
+ GNUNET_CRYPTO_rsa_key_free (c->privkey);
+ GNUNET_free (c->pubkey);
+ GNUNET_free (c->filename);
+ GNUNET_free (c);
+
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_TIME_Absolute
+get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+ unsigned int c;
+ struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS;
+
+ if (NULL == rd)
+ return GNUNET_TIME_UNIT_ZERO_ABS;
+ for (c = 0; c < rd_count; c++)
+ expire = GNUNET_TIME_absolute_min (rd[c].expiration, expire);
+ return expire;
+}
/**
* Task run during shutdown.
@@ -94,12 +246,16 @@ static void
cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
-
struct GNUNET_NAMESTORE_ZoneIteration * no;
struct GNUNET_NAMESTORE_ZoneIteration * tmp;
struct GNUNET_NAMESTORE_Client * nc;
struct GNUNET_NAMESTORE_Client * next;
+ GNUNET_SERVER_notification_context_destroy (snc);
+ snc = NULL;
+ GNUNET_CONTAINER_multihashmap_iterate(zonekeys, &zone_to_disk_it, NULL);
+ GNUNET_CONTAINER_multihashmap_destroy(zonekeys);
+
for (nc = client_head; nc != NULL; nc = next)
{
next = nc->next;
@@ -109,17 +265,14 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
tmp = no->next;
GNUNET_free (no);
}
-
+ GNUNET_SERVER_client_drop(nc->client);
GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
GNUNET_free (nc);
-
}
- GNUNET_SERVER_notification_context_destroy (snc);
- snc = NULL;
-
GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
GNUNET_free (db_lib_name);
+ GNUNET_free_non_null(zonefile_directory);
}
static struct GNUNET_NAMESTORE_Client *
@@ -137,7 +290,6 @@ client_lookup (struct GNUNET_SERVER_Client *client)
return nc;
}
-
/**
* Called whenever a client is disconnected. Frees our
* resources associated with that client.
@@ -160,16 +312,22 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
if ((NULL == client) || (NULL == nc))
return;
- for (no = nc->op_head; no != NULL; no = no->next)
+ no = nc->op_head;
+ while (NULL != no)
{
GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
GNUNET_free (no);
+ no = nc->op_head;
}
+ GNUNET_SERVER_client_drop(nc->client);
GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
GNUNET_free (nc);
+ nc = NULL;
}
+
+
static void handle_start (void *cls,
struct GNUNET_SERVER_Client * client,
const struct GNUNET_MessageHeader * message)
@@ -180,18 +338,40 @@ static void handle_start (void *cls,
nc->client = client;
GNUNET_SERVER_notification_context_add (snc, client);
GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc);
-
+ GNUNET_SERVER_client_keep (client);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
struct LookupNameContext
{
struct GNUNET_NAMESTORE_Client *nc;
- uint32_t id;
+ uint32_t request_id;
uint32_t record_type;
+ struct GNUNET_CRYPTO_ShortHashCode *zone;
+ char * name;
};
-
+void drop_iterator (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_len,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ struct GNUNET_CRYPTO_ShortHashCode zone_hash;
+ int * stop = cls;
+ if (NULL != zone_key)
+ {
+ GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting zone `%s'\n", GNUNET_short_h2s (&zone_hash));
+ GSN_database->delete_zone (GSN_database->cls, &zone_hash);
+ }
+ else
+ {
+ (*stop) = GNUNET_YES;
+ }
+}
static void
@@ -206,24 +386,26 @@ handle_lookup_name_it (void *cls,
/* send response */
struct LookupNameContext *lnc = cls;
struct LookupNameResponseMessage *lnr_msg;
-
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp;
- struct GNUNET_NAMESTORE_RecordData * rd_tmp;
+ struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc;
+ struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
+ struct GNUNET_TIME_Absolute e;
+ struct GNUNET_CRYPTO_ShortHashCode zone_key_hash;
+ GNUNET_HashCode long_hash;
+ char *rd_tmp;
char *name_tmp;
- struct GNUNET_CRYPTO_RsaSignature *signature_tmp;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
-
+ size_t rd_ser_len;
size_t r_size = 0;
-
size_t name_len = 0;
- if (NULL != name)
- name_len = strlen(name) + 1;
int copied_elements = 0;
- int contains_signature = 0;
+ int contains_signature = GNUNET_NO;
+ int authoritative = GNUNET_NO;
int c;
+ if (NULL != name)
+ name_len = strlen(name) + 1;
+
/* count records to copy */
if (rd_count != 0)
{
@@ -233,68 +415,114 @@ handle_lookup_name_it (void *cls,
for (c = 0; c < rd_count; c ++)
if (rd[c].record_type == lnc->record_type)
copied_elements++; /* found matching record */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records with type %u for name `%s' in zone `%s'\n",
+ copied_elements, lnc->record_type, lnc->name, GNUNET_short_h2s(lnc->zone));
+ rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ copied_elements = 0;
+ for (c = 0; c < rd_count; c ++)
+ {
+ if (rd[c].record_type == lnc->record_type)
+ {
+ /* found matching record */
+ memcpy (&rd_selected[copied_elements], &rd[c], sizeof (struct GNUNET_NAMESTORE_RecordData));
+ copied_elements++;
+ }
+ }
}
else
+ {
copied_elements = rd_count;
+ rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd;
+ }
+ }
+ else
+ {
+ /* No results */
+ copied_elements = 0;
+ rd_selected = NULL;
+ expire = GNUNET_TIME_UNIT_ZERO_ABS;
}
- if ((copied_elements == rd_count) && (signature != NULL))
- contains_signature = GNUNET_YES;
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(copied_elements, rd_selected);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n",
+ copied_elements, lnc->name, GNUNET_short_h2s(lnc->zone));
+
+ if ((copied_elements == rd_count) && (NULL != signature))
+ contains_signature = GNUNET_YES; /* returning all records, so include signature */
+ else
+ contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */
+
+
+ if ((NULL != zone_key) && (copied_elements == rd_count))
+ {
+ GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
+ GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash);
+ if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
+ {
+ cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
+ e = get_block_expiration_time(rd_count, rd);
+ signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count);
+ GNUNET_assert (signature_new != NULL);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for name `%s' with %u records in zone `%s'\n",name, copied_elements, GNUNET_short_h2s(&zone_key_hash));
+ authoritative = GNUNET_YES;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am not authoritative for name `%s' in zone `%s'\n",name, GNUNET_short_h2s(&zone_key_hash));
+ }
r_size = sizeof (struct LookupNameResponseMessage) +
sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
name_len +
- copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData) +
- contains_signature * sizeof (struct GNUNET_CRYPTO_RsaSignature);
+ rd_ser_len;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
lnr_msg = GNUNET_malloc (r_size);
-
- lnr_msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
- lnr_msg->header.size = ntohs (r_size);
- lnr_msg->op_id = htonl (lnc->id);
- lnr_msg->rc_count = htonl (copied_elements);
+ lnr_msg->gns_header.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
+ lnr_msg->gns_header.header.size = ntohs (r_size);
+ lnr_msg->gns_header.r_id = htonl (lnc->request_id);
+ lnr_msg->rd_count = htons (copied_elements);
+ lnr_msg->rd_len = htons (rd_ser_len);
lnr_msg->name_len = htons (name_len);
- lnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
- lnr_msg->contains_sig = htons (contains_signature);
+ lnr_msg->expire = GNUNET_TIME_absolute_hton(get_block_expiration_time(copied_elements, rd_selected));
-
- zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &lnr_msg[1];
- name_tmp = (char *) &zone_key_tmp[1];
- rd_tmp = (struct GNUNET_NAMESTORE_RecordData *) &name_tmp[name_len];
- signature_tmp = (struct GNUNET_CRYPTO_RsaSignature *) &rd_tmp[copied_elements];
+ if (rd_selected != rd)
+ GNUNET_free (rd_selected);
if (zone_key != NULL)
- memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ lnr_msg->public_key = (*zone_key);
else
+ memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key));
+
+ if (GNUNET_YES == authoritative)
+ { /* use new created signature */
+ lnr_msg->contains_sig = htons (GNUNET_YES);
+ GNUNET_assert (signature_new != NULL);
+ lnr_msg->signature = *signature_new;
+ GNUNET_free (signature_new);
+ }
+ else if (GNUNET_YES == contains_signature)
{
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy;
- memset (&dummy, '0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
- memcpy (zone_key_tmp, &dummy, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ /* use existing signature */
+ lnr_msg->contains_sig = htons (GNUNET_YES);
+ GNUNET_assert (signature != NULL);
+ lnr_msg->signature = *signature;
}
- memcpy (name_tmp, name, name_len);
- /* copy records */
- copied_elements = 0;
- if (rd_count != 0)
+ else
{
- if (lnc->record_type != 0)
- {
- /* special record type needed */
- for (c = 0; c < rd_count; c ++)
- if (rd[c].record_type == lnc->record_type)
- {
- /* found matching record */
- memcpy (&rd_tmp[copied_elements], &rd[c], rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
- copied_elements++;
- }
- }
- else
- memcpy (rd_tmp, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ /* use no signature */
+ memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature));
}
- if (GNUNET_YES == contains_signature)
- memcpy (signature_tmp, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature));
- GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
+ name_tmp = (char *) &lnr_msg[1];
+ rd_tmp = &name_tmp[name_len];
+
+ memcpy (name_tmp, name, name_len);
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+ GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
GNUNET_free (lnr_msg);
}
@@ -305,13 +533,11 @@ static void handle_lookup_name (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME");
struct LookupNameContext lnc;
struct GNUNET_NAMESTORE_Client *nc;
- GNUNET_HashCode name_hash;
size_t name_len;
char * name;
- uint32_t id = 0;
+ uint32_t rid = 0;
uint32_t type = 0;
-
if (ntohs (message->size) < sizeof (struct LookupNameMessage))
{
GNUNET_break_op (0);
@@ -328,7 +554,7 @@ static void handle_lookup_name (void *cls,
}
struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message;
- id = ntohl (ln_msg->op_id);
+ rid = ntohl (ln_msg->gns_header.r_id);
name_len = ntohl (ln_msg->name_len);
type = ntohl (ln_msg->record_type);
@@ -339,17 +565,26 @@ static void handle_lookup_name (void *cls,
return;
}
- name = GNUNET_malloc (name_len);
- memcpy (name, &ln_msg[1], name_len);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up record for name `%s'\n", name);
- GNUNET_CRYPTO_hash(name, name_len-1, &name_hash);
- GNUNET_free (name);
+ name = (char *) &ln_msg[1];
+ if (name[name_len -1] != '\0')
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ if (0 == type)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up all records for name `%s' in zone `%s'\n", name, GNUNET_short_h2s(&ln_msg->zone));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up records with type %u for name `%s' in zone `%s'\n", type, name, GNUNET_short_h2s(&ln_msg->zone));
/* do the actual lookup */
- lnc.id = id;
+ lnc.request_id = rid;
lnc.nc = nc;
lnc.record_type = type;
- GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, &ln_msg->zone, 0, &handle_lookup_name_it, &lnc);
+ lnc.name = name;
+ lnc.zone = &ln_msg->zone;
+ GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, name, 0, &handle_lookup_name_it, &lnc);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -361,8 +596,6 @@ static void handle_record_put (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT");
struct GNUNET_NAMESTORE_Client *nc;
struct GNUNET_TIME_Absolute expire;
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
- struct GNUNET_NAMESTORE_RecordData *rd;
struct GNUNET_CRYPTO_RsaSignature *signature;
struct RecordPutResponseMessage rpr_msg;
size_t name_len;
@@ -370,7 +603,7 @@ static void handle_record_put (void *cls,
size_t msg_size_exp;
char * name;
char * rd_ser;
- uint32_t id = 0;
+ uint32_t rid = 0;
uint32_t rd_ser_len;
uint32_t rd_count;
int res = GNUNET_SYSERR;
@@ -391,12 +624,28 @@ static void handle_record_put (void *cls,
}
struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message;
- id = ntohl (rp_msg->op_id);
+
+ rid = ntohl (rp_msg->gns_header.r_id);
+ msg_size = ntohs (rp_msg->gns_header.header.size);
name_len = ntohs (rp_msg->name_len);
+ rd_count = ntohs (rp_msg->rd_count);
rd_ser_len = ntohs(rp_msg->rd_len);
- msg_size = ntohs (message->size);
- msg_size_exp = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_ser_len;
+ if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ if ((rd_count < 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ msg_size_exp = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
if (msg_size != msg_size_exp)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
@@ -404,25 +653,42 @@ static void handle_record_put (void *cls,
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
+ if ((name_len == 0) || (name_len > 256))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ name = (char *) &rp_msg[1];
- if ((name_len == 0) || (name_len > 256))
+ if (name[name_len -1] != '\0')
{
GNUNET_break_op (0);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
- zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &rp_msg[1];
- name = (char *) &zone_key[1];
expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature;
+
rd_ser = &name[name_len];
- rd_count = GNUNET_NAMESTORE_records_deserialize(&rd, rd_ser, rd_ser_len);
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
+ if (res != GNUNET_OK)
+ {
+ GNUNET_break_op (0);
+ goto send;
+ }
+
+ struct GNUNET_CRYPTO_ShortHashCode zone_hash;
+ GNUNET_CRYPTO_short_hash (&rp_msg->public_key, sizeof (rp_msg->public_key), &zone_hash);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting %u record for name `%s' in zone `%s'\n", rd_count, name, GNUNET_short_h2s(&zone_hash));
/* Database operation */
res = GSN_database->put_records(GSN_database->cls,
- zone_key,
+ &rp_msg->public_key,
expire,
name,
rd_count, rd,
@@ -432,20 +698,157 @@ static void handle_record_put (void *cls,
name, (res == GNUNET_OK) ? "OK" : "FAIL");
/* Send response */
-
+send:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE");
- rpr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
- rpr_msg.op_id = rp_msg->op_id;
- rpr_msg.header.size = htons (sizeof (struct RecordPutResponseMessage));
- if (GNUNET_OK == res)
- rpr_msg.op_result = htons (GNUNET_OK);
- else
- rpr_msg.op_result = htons (GNUNET_NO);
+ rpr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
+ rpr_msg.gns_header.header.size = htons (sizeof (struct RecordPutResponseMessage));
+ rpr_msg.gns_header.r_id = htonl (rid);
+ rpr_msg.op_result = htonl (res);
GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
+struct CreateRecordContext
+{
+ struct GNUNET_NAMESTORE_RecordData *rd;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
+ struct GNUNET_TIME_Absolute expire;
+ char *name;
+ int res;
+};
+
+
+static void
+handle_create_record_it (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ struct CreateRecordContext * crc = cls;
+ struct GNUNET_NAMESTORE_RecordData *rd_new = NULL;
+ struct GNUNET_CRYPTO_RsaSignature dummy_signature;
+ struct GNUNET_TIME_Absolute block_expiration;
+ int res;
+ int exist = GNUNET_SYSERR;
+ int update = GNUNET_NO;
+ int c;
+ int rd_count_new = 0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u existing records for `%s'\n", rd_count, crc->name);
+ for (c = 0; c < rd_count; c++)
+ {
+ if ((crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PKEY) && (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PKEY))
+ {
+ /* Update unique PKEY */
+ exist = c;
+ update = GNUNET_YES;
+ break;
+ }
+ else if ((crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PSEU) && (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PSEU))
+ {
+ /* Update unique PSEU */
+ exist = c;
+ update = GNUNET_YES;
+ break;
+ }
+ else if ((crc->rd->record_type == rd[c].record_type) &&
+ (crc->rd->data_size == rd[c].data_size) &&
+ (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing records for `%s' to update expiration date!\n", crc->name);
+ exist = c;
+ if (crc->rd->expiration.abs_value != rd[c].expiration.abs_value)
+ update = GNUNET_YES;
+ break;
+ }
+ }
+
+ if (exist == GNUNET_SYSERR)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New record does not exist for name `%s'!\n", crc->name);
+
+ if (exist == GNUNET_SYSERR)
+ {
+ rd_new = GNUNET_malloc ((rd_count+1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ rd_count_new = rd_count + 1;
+ rd_new[rd_count] = *(crc->rd);
+ }
+ else if (update == GNUNET_NO)
+ {
+ /* Exact same record already exists */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No update for %s' record required!\n", crc->name);
+ res = GNUNET_NO;
+ goto end;
+ }
+ else if (update == GNUNET_YES)
+ {
+ /* Update record */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating existing records for `%s'!\n", crc->name);
+ rd_new = GNUNET_malloc ((rd_count) * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ rd_count_new = rd_count;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration from %llu to %llu!\n", rd_new[exist].expiration.abs_value, crc->rd->expiration.abs_value);
+ rd_new[exist] = *(crc->rd);
+ }
+
+ block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire);
+ if (block_expiration.abs_value != expire.abs_value)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated block expiration time\n");
+
+ memset (&dummy_signature, '\0', sizeof (dummy_signature));
+
+ /* Database operation */
+ GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0));
+ res = GSN_database->put_records(GSN_database->cls,
+ (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) crc->pubkey,
+ block_expiration,
+ crc->name,
+ rd_count_new, rd_new,
+ &dummy_signature);
+ GNUNET_break (GNUNET_OK == res);
+ if (res == GNUNET_OK)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name);
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to put record for `%s' in database \n", crc->name);
+ res = GNUNET_YES;
+
+end:
+ GNUNET_free_non_null (rd_new);
+
+ switch (res) {
+ case GNUNET_SYSERR:
+ /* failed to create the record */
+ crc->res = GNUNET_SYSERR;
+ break;
+ case GNUNET_YES:
+ /* database operations OK */
+ if (GNUNET_YES == update)
+ {
+ /* we updated an existing record */
+ crc->res = GNUNET_NO;
+ }
+ else
+ {
+ /* we created a new record */
+ crc->res = GNUNET_YES;
+ }
+ break;
+ case GNUNET_NO:
+ /* identical entry existed, so we did nothing */
+ crc->res = GNUNET_NO;
+ break;
+ default:
+ break;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update result for name `%s' %u\n", crc->name, res);
+
+}
static void handle_record_create (void *cls,
struct GNUNET_SERVER_Client * client,
@@ -453,13 +856,26 @@ static void handle_record_create (void *cls,
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
struct GNUNET_NAMESTORE_Client *nc;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc;
+ struct CreateRecordContext crc;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
struct RecordCreateResponseMessage rcr_msg;
+ struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
+ GNUNET_HashCode long_hash;
size_t name_len;
size_t msg_size;
size_t msg_size_exp;
- uint32_t id = 0;
+ size_t rd_ser_len;
+ size_t key_len;
+ uint32_t rid = 0;
+ char *pkey_tmp;
+ char *name_tmp;
+ char *rd_ser;
+ int rd_count;
int res = GNUNET_SYSERR;
+ crc.res = GNUNET_SYSERR;
if (ntohs (message->size) < sizeof (struct RecordCreateMessage))
{
@@ -477,10 +893,13 @@ static void handle_record_create (void *cls,
}
struct RecordCreateMessage * rp_msg = (struct RecordCreateMessage *) message;
- id = ntohl (rp_msg->op_id);
+ rid = ntohl (rp_msg->gns_header.r_id);
name_len = ntohs (rp_msg->name_len);
msg_size = ntohs (message->size);
- msg_size_exp = sizeof (struct RecordCreateMessage) + name_len + sizeof (struct GNUNET_NAMESTORE_RecordData);
+ rd_count = ntohs (rp_msg->rd_count);
+ rd_ser_len = ntohs (rp_msg->rd_len);
+ key_len = ntohs (rp_msg->pkey_len);
+ msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
if (msg_size != msg_size_exp)
{
@@ -490,7 +909,6 @@ static void handle_record_create (void *cls,
return;
}
-
if ((name_len == 0) || (name_len > 256))
{
GNUNET_break_op (0);
@@ -498,23 +916,195 @@ static void handle_record_create (void *cls,
return;
}
- /* DO WORK HERE */
+ pkey_tmp = (char *) &rp_msg[1];
+ name_tmp = &pkey_tmp[key_len];
+ rd_ser = &name_tmp[name_len];
- /* Send response */
+ if (name_tmp[name_len -1] != '\0')
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
+ if ((res != GNUNET_OK) || (rd_count != 1))
+ {
+ GNUNET_break_op (0);
+ goto send;
+ }
+ /* Extracting and converting private key */
+ pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ GNUNET_assert (pkey != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
+ GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
+ GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
+
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash));
+
+ cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
+ cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ cc->pubkey = GNUNET_malloc(sizeof (pub));
+ memcpy (cc->pubkey, &pub, sizeof(pub));
+ cc->zone = pubkey_hash;
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+
+ crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
+ crc.res = GNUNET_SYSERR;
+ crc.pkey = pkey;
+ crc.pubkey = &pub;
+ crc.rd = rd;
+ crc.name = name_tmp;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
+
+ /* Get existing records for name */
+ res = GSN_database->iterate_records(GSN_database->cls, &pubkey_hash, name_tmp, 0, &handle_create_record_it, &crc);
+ if (res != GNUNET_SYSERR)
+ res = GNUNET_OK;
+ GNUNET_CRYPTO_rsa_key_free(pkey);
+ pkey = NULL;
+
+ /* Send response */
+send:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_CREATE_RESPONSE");
- rcr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
- rcr_msg.op_id = rp_msg->op_id;
- rcr_msg.header.size = htons (sizeof (struct RecordCreateResponseMessage));
- if (GNUNET_OK == res)
- rcr_msg.op_result = htons (GNUNET_OK);
+ rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
+ rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage));
+ rcr_msg.gns_header.r_id = htonl (rid);
+ if ((GNUNET_OK == res) && (crc.res == GNUNET_YES))
+ rcr_msg.op_result = htonl (GNUNET_YES);
+ else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO))
+ rcr_msg.op_result = htonl (GNUNET_NO);
else
- rcr_msg.op_result = htons (GNUNET_NO);
+ rcr_msg.op_result = htonl (GNUNET_SYSERR);
GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rcr_msg, GNUNET_NO);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
+
+struct RemoveRecordContext
+{
+ struct GNUNET_NAMESTORE_RecordData *rd;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
+ int remove_name;
+ uint16_t op_res;
+};
+
+static void
+handle_record_remove_it (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ struct RemoveRecordContext *rrc = cls;
+ unsigned int c;
+ int res;
+ int found;
+ unsigned int rd_count_new;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s 'currently has %u records\n", name, rd_count);
+
+ if (rd_count == 0)
+ {
+ /* Could not find record to remove */
+ rrc->op_res = 1;
+ return;
+ }
+
+ /* Find record to remove */
+ found = GNUNET_SYSERR;
+ for (c = 0; c < rd_count; c++)
+ {
+ /*
+ if (rd[c].flags != rrc->rd->flags)
+ continue;*/
+ if (rd[c].record_type != rrc->rd->record_type)
+ continue;
+ /*
+ if (rd[c].data_size != rrc->rd->data_size)
+ continue;
+ GNUNET_break(0);
+ if (0 != memcmp (rd[c].data, rrc->rd->data, rrc->rd->data_size))
+ continue;
+ GNUNET_break(0); */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count);
+ found = c;
+ break;
+ }
+ if (GNUNET_SYSERR == found)
+ {
+ /* Could not find record to remove */
+ rrc->op_res = 2;
+ return;
+ }
+
+ if (rd_count-1 == 0)
+ {
+ struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
+ GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
+ res = GSN_database->remove_records (GSN_database->cls,
+ &pubkey_hash,
+ name);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "No records left for name `%s', removing name\n",
+ name, res);
+ if (GNUNET_OK != res)
+ {
+ /* Could put records into database */
+ rrc->op_res = 4;
+ return;
+ }
+ rrc->op_res = 0;
+ return;
+ }
+
+ rd_count_new = rd_count -1;
+ struct GNUNET_NAMESTORE_RecordData rd_new[rd_count_new];
+
+ unsigned int c2 = 0;
+ for (c = 0; c < rd_count; c++)
+ {
+ if (c != found)
+ {
+ GNUNET_assert (c2 < rd_count_new);
+ rd_new[c2] = rd[c];
+ c2++;
+ }
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new);
+
+ /* Create dummy signature */
+ struct GNUNET_CRYPTO_RsaSignature dummy_signature;
+ memset (&dummy_signature, '\0', sizeof (dummy_signature));
+
+
+ /* Put records */
+ res = GSN_database->put_records(GSN_database->cls,
+ zone_key,
+ expire,
+ name,
+ rd_count_new, rd_new,
+ &dummy_signature);
+ if (GNUNET_OK != res)
+ {
+ /* Could put records into database */
+ rrc->op_res = 4;
+ return;
+ }
+
+ rrc->op_res = 0;
+}
+
static void handle_record_remove (void *cls,
struct GNUNET_SERVER_Client * client,
const struct GNUNET_MessageHeader * message)
@@ -522,10 +1112,21 @@ static void handle_record_remove (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_REMOVE");
struct GNUNET_NAMESTORE_Client *nc;
struct RecordRemoveResponseMessage rrr_msg;
- size_t name_len;
- size_t msg_size;
- size_t msg_size_exp;
- uint32_t id = 0;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc = NULL;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
+ GNUNET_HashCode long_hash;
+ char * pkey_tmp = NULL;
+ char * name_tmp = NULL;
+ char * rd_ser = NULL;
+ size_t key_len = 0;
+ size_t name_len = 0;
+ size_t rd_ser_len = 0;
+ size_t msg_size = 0;
+ size_t msg_size_exp = 0;
+ uint32_t rd_count;
+ uint32_t rid = 0;
int res = GNUNET_SYSERR;
@@ -544,12 +1145,29 @@ static void handle_record_remove (void *cls,
return;
}
- struct RecordRemoveMessage * rp_msg = (struct RecordRemoveMessage *) message;
- id = ntohl (rp_msg->op_id);
- name_len = ntohs (rp_msg->name_len);
+ struct RecordRemoveMessage * rr_msg = (struct RecordRemoveMessage *) message;
+ rid = ntohl (rr_msg->gns_header.r_id);
+ name_len = ntohs (rr_msg->name_len);
+ rd_ser_len = ntohs (rr_msg->rd_len);
+ rd_count = ntohs (rr_msg->rd_count);
+ key_len = ntohs (rr_msg->pkey_len);
msg_size = ntohs (message->size);
- msg_size_exp = sizeof (struct RecordRemoveMessage) + name_len + sizeof (struct GNUNET_NAMESTORE_RecordData);
+ if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ if ((name_len >=256) || (name_len == 0))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
if (msg_size != msg_size_exp)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
@@ -558,6 +1176,10 @@ static void handle_record_remove (void *cls,
return;
}
+ pkey_tmp = (char *) &rr_msg[1];
+ name_tmp = &pkey_tmp[key_len];
+ rd_ser = &name_tmp[name_len];
+
if ((name_len == 0) || (name_len > 256))
{
@@ -566,41 +1188,268 @@ static void handle_record_remove (void *cls,
return;
}
- /* DO WORK HERE */
+ if (name_tmp[name_len -1] != '\0')
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
- /* Send response */
+ /* Extracting and converting private key */
+ pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ GNUNET_assert (pkey != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
+ GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
+ GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE");
- rrr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
- rrr_msg.op_id = rp_msg->op_id;
- rrr_msg.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
- if (GNUNET_OK == res)
- rrr_msg.op_result = htons (GNUNET_OK);
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash));
+ cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
+ cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ cc->pubkey = GNUNET_malloc(sizeof (pub));
+ memcpy (cc->pubkey, &pub, sizeof(pub));
+ cc->zone = pubkey_hash;
+
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+
+
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
+ if ((res != GNUNET_OK) || (rd_count > 1))
+ {
+ GNUNET_break_op (0);
+ goto send;
+ }
+
+ if (0 == rd_count)
+ {
+ /* remove the whole name and all records */
+ /* Database operation */
+ res = GSN_database->remove_records (GSN_database->cls,
+ &pubkey_hash,
+ name_tmp);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing name `%s': %s\n",
+ name_tmp, (GNUNET_OK == res) ? "OK" : "FAIL");
+
+ if (GNUNET_OK != res)
+ /* Could not remove entry from database */
+ res = 4;
+ else
+ res = 0;
+ }
else
- rrr_msg.op_result = htons (GNUNET_NO);
+ {
+ /* remove a single record */
+ struct RemoveRecordContext rrc;
+ rrc.rd = rd;
+ rrc.pkey = pkey;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
+
+ /* Database operation */
+ res = GSN_database->iterate_records (GSN_database->cls,
+ &pubkey_hash,
+ name_tmp,
+ 0,
+ handle_record_remove_it, &rrc);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s': %s\n",
+ name_tmp, (rrc.op_res == 0) ? "OK" : "FAIL");
+ res = rrc.op_res;
+ }
+ /* Send response */
+send:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE");
+ rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
+ rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
+ rrr_msg.gns_header.r_id = htonl (rid);
+ rrr_msg.op_result = htonl (res);
GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rrr_msg, GNUNET_NO);
+ GNUNET_CRYPTO_rsa_key_free (pkey);
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+struct ZoneToNameCtx
+{
+ struct GNUNET_NAMESTORE_Client *nc;
+ uint32_t rid;
+};
+
+static void
+handle_zone_to_name_it (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ struct ZoneToNameCtx * ztn_ctx = cls;
+ struct ZoneToNameResponseMessage *ztnr_msg;
+ int16_t res = GNUNET_SYSERR;
+ uint16_t name_len = 0;
+ uint16_t rd_ser_len = 0 ;
+ int32_t contains_sig = 0;
+ size_t msg_size = 0;
+
+ char *rd_ser = NULL;
+ char *name_tmp;
+ char *rd_tmp;
+ char *sig_tmp;
+
+ if ((zone_key != NULL) && (name != NULL))
+ {
+ /* found result */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found results: name is `%s', has %u records\n", name, rd_count);
+ res = GNUNET_YES;
+ name_len = strlen (name) +1;
+ }
+ else
+ {
+ /* no result found */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found no results\n");
+ res = GNUNET_NO;
+ name_len = 0;
+ }
+
+ if (rd_count > 0)
+ {
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+ rd_ser = GNUNET_malloc (rd_ser_len);
+ GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
+ }
+ else
+ rd_ser_len = 0;
+
+ if (signature != NULL)
+ contains_sig = GNUNET_YES;
+ else
+ contains_sig = GNUNET_NO;
+
+
+
+ msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature);
+ ztnr_msg = GNUNET_malloc (msg_size);
+
+ name_tmp = (char *) &ztnr_msg[1];
+ rd_tmp = &name_tmp[name_len];
+ sig_tmp = &rd_tmp[rd_ser_len];
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_TO_NAME_RESPONSE");
+ ztnr_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE);
+ ztnr_msg->gns_header.header.size = htons (msg_size);
+ ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
+ ztnr_msg->res = htons (res);
+ ztnr_msg->rd_len = htons (rd_ser_len);
+ ztnr_msg->rd_count = htons (rd_count);
+ ztnr_msg->name_len = htons (name_len);
+ ztnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
+ if (zone_key != NULL)
+ ztnr_msg->zone_key = *zone_key;
+ else
+ memset (&ztnr_msg->zone_key, '\0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+
+ if ((name_len > 0) && (name != NULL))
+ memcpy (name_tmp, name, name_len);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name is `%s', has %u records, rd ser len %u msg_size %u\n", name, rd_count, rd_ser_len, msg_size);
+ if ((rd_ser_len > 0) && (rd_ser != NULL))
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+ if ((GNUNET_YES == contains_sig) && (signature != NULL))
+ memcpy (sig_tmp, signature, contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature));
+
+ GNUNET_SERVER_notification_context_unicast (snc, ztn_ctx->nc->client, (const struct GNUNET_MessageHeader *) ztnr_msg, GNUNET_NO);
+ GNUNET_free (ztnr_msg);
+ GNUNET_free_non_null (rd_ser);
+}
+
+
+static void handle_zone_to_name (void *cls,
+ struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader * message)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_TO_NAME");
+ struct GNUNET_NAMESTORE_Client *nc;
+ struct ZoneToNameCtx ztn_ctx;
+ size_t msg_size = 0;
+ uint32_t rid = 0;
+
+ if (ntohs (message->size) != sizeof (struct ZoneToNameMessage))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ nc = client_lookup(client);
+ if (nc == NULL)
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ struct ZoneToNameMessage *ztn_msg = (struct ZoneToNameMessage *) message;
+
+ if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
+ rid = ntohl (ztn_msg->gns_header.r_id);
+
+ ztn_ctx.rid = rid;
+ ztn_ctx.nc = nc;
+
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded z_tmp;
+ GNUNET_CRYPTO_short_hash_to_enc(&ztn_msg->zone, &z_tmp);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up name for zone `%s' in zone `%s'\n",
+ (char *) &z_tmp,
+ GNUNET_short_h2s (&ztn_msg->value_zone));
+
+ GSN_database->zone_to_name (GSN_database->cls, &ztn_msg->zone, &ztn_msg->value_zone, &handle_zone_to_name_it, &ztn_ctx);
+
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
+
+/**
+ * Copy record, data has to be free separetely
+ */
+void
+copy_record (const struct GNUNET_NAMESTORE_RecordData *src, struct GNUNET_NAMESTORE_RecordData *dest)
+{
+
+ memcpy (dest, src, sizeof (struct GNUNET_NAMESTORE_RecordData));
+ dest->data = GNUNET_malloc (src->data_size);
+ memcpy ((void *) dest->data, src->data, src->data_size);
+}
+
struct ZoneIterationProcResult
{
- int have_zone_key;
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
+ struct GNUNET_NAMESTORE_ZoneIteration *zi;
- int have_signature;
+ int res_iteration_finished;
+ int records_included;
+ int has_signature;
+
+ char *name;
+ struct GNUNET_CRYPTO_ShortHashCode zone_hash;
+ struct GNUNET_NAMESTORE_RecordData *rd;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
struct GNUNET_CRYPTO_RsaSignature signature;
struct GNUNET_TIME_Absolute expire;
-
- int have_name;
- char name[256];
-
- unsigned int rd_count;
- char *rd_ser;
};
-void zone_iteration_proc (void *cls,
+void zone_iteraterate_proc (void *cls,
const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
struct GNUNET_TIME_Absolute expire,
const char *name,
@@ -608,40 +1457,230 @@ void zone_iteration_proc (void *cls,
const struct GNUNET_NAMESTORE_RecordData *rd,
const struct GNUNET_CRYPTO_RsaSignature *signature)
{
- struct ZoneIterationProcResult *zipr = cls;
- size_t len;
- if (zone_key != NULL)
+ struct ZoneIterationProcResult *proc = cls;
+ struct GNUNET_NAMESTORE_RecordData *rd_filtered;
+ struct GNUNET_CRYPTO_RsaSignature * new_signature;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc;
+ struct GNUNET_CRYPTO_ShortHashCode hash;
+ GNUNET_HashCode long_hash;
+ struct GNUNET_TIME_Absolute e;
+ unsigned int rd_count_filtered = 0;
+ int include;
+ int c;
+
+ proc->res_iteration_finished = GNUNET_NO;
+ proc->records_included = 0;
+
+ if ((zone_key == NULL) && (name == NULL))
{
- zipr->zone_key = *zone_key;
- zipr->have_zone_key = GNUNET_YES;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
+ proc->res_iteration_finished = GNUNET_YES;
+ proc->rd = NULL;
+ proc->name = NULL;
}
- else
- zipr->have_zone_key = GNUNET_NO;
+ else if ((zone_key != NULL) && (name != NULL)) /* just a safety check */
+ {
+ rd_filtered = GNUNET_malloc (rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for zone iteration: `%s'\n", name);
+ for (c = 0; c < rd_count; c++)
+ {
+ include = GNUNET_YES;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must have 0x%x \n",
+ c, rd[c].flags, proc->zi->must_have_flags);
+ /* Checking must have flags */
+ if ((rd[c].flags & proc->zi->must_have_flags) == proc->zi->must_have_flags)
+ {
+ /* Include */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
+ include = GNUNET_NO;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must not have 0x%x\n",
+ c, rd[c].flags, proc->zi->must_not_have_flags);
+ if ((rd[c].flags & proc->zi->must_not_have_flags) != 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
+ include = GNUNET_NO;
+ }
+ else
+ {
+ /* Include */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
+ }
+ if (GNUNET_YES == include)
+ {
+ copy_record (&rd[c], &rd_filtered[rd_count_filtered]);
+ rd_count_filtered++;
+ }
+
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Included %i of %i records \n", rd_count_filtered, rd_count);
+
+ proc->records_included = rd_count_filtered;
+ if (0 == rd_count_filtered)
+ {
+ GNUNET_free (rd_filtered);
+ rd_filtered = NULL;
+ }
+ proc->rd = rd_filtered;
+ proc->name = GNUNET_strdup(name);
+ memcpy (&proc->zone_key, zone_key, sizeof (proc->zone_key));
- zipr->expire = expire;
+ /* Signature */
+ proc->has_signature = GNUNET_NO;
+ GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &hash);
+ GNUNET_CRYPTO_short_hash_double(&hash, &long_hash);
+ proc->zone_hash = hash;
- if (name != NULL)
+ if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
+ {
+ cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
+ e = get_block_expiration_time(rd_count_filtered, rd_filtered);
+ proc->expire = e;
+ new_signature = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd_filtered, rd_count_filtered);
+ GNUNET_assert (signature != NULL);
+ proc->signature = (*new_signature);
+ GNUNET_free (new_signature);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
+ name, GNUNET_short_h2s(&hash), rd_count_filtered, e.abs_value);
+ proc->has_signature = GNUNET_YES;
+ }
+ else if (rd_count_filtered == rd_count)
+ {
+ proc->expire = expire;
+ if (NULL != signature)
+ {
+ proc->signature = (*signature);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n",
+ name, GNUNET_short_h2s(&hash), rd_count_filtered, expire.abs_value);
+ proc->has_signature = GNUNET_YES;
+ }
+ else
+ {
+ memset (&proc->signature, '\0', sizeof (proc->signature));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No signature provided for `%s'\n", name);
+ }
+ }
+ }
+ else
{
- memcpy (zipr->name, name, strlen(name) + 1);
- zipr->have_name = GNUNET_YES;
+ GNUNET_break (0);
+ return;
}
+
+}
+
+void find_next_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+
+ struct GNUNET_CRYPTO_ShortHashCode *zone;
+
+ if (GNUNET_YES == proc->zi->has_zone)
+ zone = &proc->zi->zone;
else
- zipr->have_name = GNUNET_NO;
+ zone = NULL;
+
+ do
+ {
+ GSN_database->iterate_records (GSN_database->cls, zone , NULL, proc->zi->offset, &zone_iteraterate_proc, proc);
+ proc->zi->offset++;
+ }
+ while ((proc->records_included == 0) && (GNUNET_NO == proc->res_iteration_finished));
+}
- zipr->rd_count = rd_count;
- if (signature != NULL)
+void send_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+ struct GNUNET_NAMESTORE_ZoneIteration *zi = proc->zi;
+
+ if (GNUNET_YES == proc->res_iteration_finished)
{
- zipr->signature = *signature;
- zipr->have_signature = GNUNET_YES;
+ struct ZoneIterationResponseMessage zir_msg;
+ if (zi->has_zone == GNUNET_YES)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", GNUNET_short_h2s(&zi->zone));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for all zones\n");
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message\n", "ZONE_ITERATION_RESPONSE");
+ zir_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
+ zir_msg.gns_header.header.size = htons (sizeof (struct ZoneIterationResponseMessage));
+ zir_msg.gns_header.r_id = htonl(zi->request_id);
+ zir_msg.expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_ZERO_ABS);
+ zir_msg.name_len = htons (0);
+ zir_msg.reserved = htons (0);
+ zir_msg.rd_count = htons (0);
+ zir_msg.rd_len = htons (0);
+ memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key));
+ memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature));
+ GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n");
+ GNUNET_CONTAINER_DLL_remove (zi->client->op_head, zi->client->op_tail, zi);
+ GNUNET_free (zi);
+ return;
}
else
- zipr->have_signature = GNUNET_NO;
+ {
+ GNUNET_assert (proc->records_included > 0);
+
+ struct ZoneIterationResponseMessage *zir_msg;
+ if (zi->has_zone == GNUNET_YES)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over zone `%s'\n",
+ proc->name, GNUNET_short_h2s(&zi->zone));
+ if (zi->has_zone == GNUNET_NO)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over all zones\n",
+ proc->name);
+
+ size_t name_len;
+ size_t rd_ser_len;
+ size_t msg_size;
+ char *name_tmp;
+ char *rd_tmp;
+ name_len = strlen (proc->name) +1;
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(proc->records_included, proc->rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(proc->records_included, proc->rd, rd_ser_len, rd_ser);
+ msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_ser_len;
+ zir_msg = GNUNET_malloc(msg_size);
+
+ name_tmp = (char *) &zir_msg[1];
+ rd_tmp = &name_tmp[name_len];
+
+ zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
+ zir_msg->gns_header.header.size = htons (msg_size);
+ zir_msg->gns_header.r_id = htonl(zi->request_id);
+ zir_msg->expire = GNUNET_TIME_absolute_hton(proc->expire);
+ zir_msg->reserved = htons (0);
+ zir_msg->name_len = htons (name_len);
+ zir_msg->rd_count = htons (proc->records_included);
+ zir_msg->rd_len = htons (rd_ser_len);
+ zir_msg->signature = proc->signature;
+ zir_msg->public_key = proc->zone_key;
+ memcpy (name_tmp, proc->name, name_len);
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with size %u\n", "ZONE_ITERATION_RESPONSE", msg_size);
+ GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
+ GNUNET_free (zir_msg);
+ }
+}
- if ((rd_count > 0) && (rd != NULL))
+void clean_up_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+ int c;
+ GNUNET_free_non_null (proc->name);
+ for (c = 0; c < proc->records_included; c++)
{
- len = GNUNET_NAMESTORE_records_serialize (&zipr->rd_ser, rd_count, rd);
+ GNUNET_free ((void *) proc->rd[c].data);
}
+ GNUNET_free_non_null (proc->rd);
+ proc->name = NULL;
+ proc->rd = NULL;
}
static void handle_iteration_start (void *cls,
@@ -653,9 +1692,6 @@ static void handle_iteration_start (void *cls,
struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message;
struct GNUNET_NAMESTORE_Client *nc;
struct GNUNET_NAMESTORE_ZoneIteration *zi;
- struct ZoneIterationResponseMessage zir_msg;
- struct ZoneIterationProcResult zipr;
- int res;
nc = client_lookup(client);
if (nc == NULL)
@@ -666,22 +1702,43 @@ static void handle_iteration_start (void *cls,
}
zi = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIteration));
- zi->op_id = ntohl (zis_msg->op_id);
+ zi->request_id = ntohl (zis_msg->gns_header.r_id);
zi->offset = 0;
zi->client = nc;
- zi->zone = zis_msg->zone;
-
- GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
+ zi->must_have_flags = ntohs (zis_msg->must_have_flags);
+ zi->must_not_have_flags = ntohs (zis_msg->must_not_have_flags);
- res = GSN_database->iterate_records (GSN_database->cls, &zis_msg->zone, NULL, zi->offset , &zone_iteration_proc, &zipr);
+ struct GNUNET_CRYPTO_ShortHashCode dummy;
+ memset (&dummy, '\0', sizeof (dummy));
+ if (0 == memcmp (&dummy, &zis_msg->zone, sizeof (dummy)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over all zones\n");
+ zi->zone = zis_msg->zone;
+ zi->has_zone = GNUNET_NO;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over zone `%s'\n", GNUNET_short_h2s (&zis_msg->zone));
+ zi->zone = zis_msg->zone;
+ zi->has_zone = GNUNET_YES;
+ }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_RESPONSE");
- zir_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
- zir_msg.op_id = htonl(zi->op_id);
- zir_msg.header.size = htons (sizeof (struct ZoneIterationResponseMessage));
+ GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
- GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
+ struct ZoneIterationProcResult proc;
+ proc.zi = zi;
+ find_next_zone_iteration_result (&proc);
+ if (GNUNET_YES == proc.res_iteration_finished)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
+ }
+ else if (proc.records_included != 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
+ }
+ send_zone_iteration_result (&proc);
+ clean_up_zone_iteration_result (&proc);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -695,7 +1752,7 @@ static void handle_iteration_stop (void *cls,
struct GNUNET_NAMESTORE_Client *nc;
struct GNUNET_NAMESTORE_ZoneIteration *zi;
struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
- uint32_t id;
+ uint32_t rid;
nc = client_lookup(client);
if (nc == NULL)
@@ -705,10 +1762,10 @@ static void handle_iteration_stop (void *cls,
return;
}
- id = ntohl (zis_msg->op_id);
+ rid = ntohl (zis_msg->gns_header.r_id);
for (zi = nc->op_head; zi != NULL; zi = zi->next)
{
- if (zi->op_id == id)
+ if (zi->request_id == rid)
break;
}
if (zi == NULL)
@@ -719,7 +1776,10 @@ static void handle_iteration_stop (void *cls,
}
GNUNET_CONTAINER_DLL_remove(nc->op_head, nc->op_tail, zi);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_h2s (&zi->zone));
+ if (GNUNET_YES == zi->has_zone)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_short_h2s (&zi->zone));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration all zones\n");
GNUNET_free (zi);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -734,8 +1794,7 @@ static void handle_iteration_next (void *cls,
struct GNUNET_NAMESTORE_Client *nc;
struct GNUNET_NAMESTORE_ZoneIteration *zi;
struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
- uint32_t id;
- int res;
+ uint32_t rid;
nc = client_lookup(client);
if (nc == NULL)
@@ -745,10 +1804,10 @@ static void handle_iteration_next (void *cls,
return;
}
- id = ntohl (zis_msg->op_id);
+ rid = ntohl (zis_msg->gns_header.r_id);
for (zi = nc->op_head; zi != NULL; zi = zi->next)
{
- if (zi->op_id == id)
+ if (zi->request_id == rid)
break;
}
if (zi == NULL)
@@ -758,10 +1817,49 @@ static void handle_iteration_next (void *cls,
return;
}
- zi->offset++;
- res = GSN_database->iterate_records (GSN_database->cls, &zi->zone, NULL, zi->offset , &zone_iteration_proc, zi);
+ struct ZoneIterationProcResult proc;
+ proc.zi = zi;
+
+ find_next_zone_iteration_result (&proc);
+ if (GNUNET_YES == proc.res_iteration_finished)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
+ }
+ else if (proc.records_included != 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
+ }
+ send_zone_iteration_result (&proc);
+ clean_up_zone_iteration_result (&proc);
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
+int zonekey_file_it (void *cls, const char *filename)
+{
+ GNUNET_HashCode long_hash;
+ int *counter = cls;
+ if ((filename != NULL) && (NULL != strstr(filename, ".zkey")))
+ {
+ struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+ struct GNUNET_NAMESTORE_CryptoContainer *c;
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
+ if (privkey == NULL)
+ return GNUNET_OK;
+
+ c = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
+ c->pubkey = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ c->privkey = privkey;
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, c->pubkey);
+ GNUNET_CRYPTO_short_hash(c->pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &c->zone);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found zonefile for zone `%s'\n", GNUNET_short_h2s (&c->zone));
+ GNUNET_CRYPTO_short_hash_double (&c->zone, &long_hash);
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ (*counter) ++;
+ }
+ return GNUNET_OK;
+}
/**
@@ -776,7 +1874,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
char * database;
-
+ int counter = 0;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
@@ -790,17 +1888,45 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0},
{&handle_record_remove, NULL,
GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0},
+ {&handle_zone_to_name, NULL,
+ GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, 0},
{&handle_iteration_start, NULL,
GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, sizeof (struct ZoneIterationStartMessage)},
- {&handle_iteration_stop, NULL,
- GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, sizeof (struct ZoneIterationStopMessage)},
{&handle_iteration_next, NULL,
GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, 0},
+ {&handle_iteration_stop, NULL,
+ GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, 0},
{NULL, NULL, 0, 0}
};
GSN_cfg = cfg;
+ /* Load private keys from disk */
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore", "zonefile_directory",
+ &zonefile_directory))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("No directory to load zonefiles specified in configuration\n"));
+ GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
+ return;
+ }
+
+ if (GNUNET_NO == GNUNET_DISK_file_test (zonefile_directory))
+ {
+ if (GNUNET_SYSERR == GNUNET_DISK_directory_create (zonefile_directory))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Creating directory `%s' for zone files failed!\n"), zonefile_directory);
+ GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created directory `%s' for zone files\n", zonefile_directory);
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scanning directory `%s' for zone files\n", zonefile_directory);
+ zonekeys = GNUNET_CONTAINER_multihashmap_create (10);
+ GNUNET_DISK_directory_scan (zonefile_directory, zonekey_file_it, &counter);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u zone files\n", counter);
+
/* Loading database plugin */
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database",
@@ -809,10 +1935,14 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
+ GNUNET_free (database);
if (GSN_database == NULL)
+ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n",
db_lib_name);
- GNUNET_free (database);
+ GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
+ return;
+ }
/* Configuring server handles */
GNUNET_SERVER_add_handlers (server, handlers);
@@ -843,3 +1973,4 @@ main (int argc, char *const *argv)
}
/* end of gnunet-service-namestore.c */
+
diff --git a/src/namestore/namestore.conf.in b/src/namestore/namestore.conf.in
index c9b9984..d93aea6 100644
--- a/src/namestore/namestore.conf.in
+++ b/src/namestore/namestore.conf.in
@@ -11,6 +11,7 @@ BINARY = gnunet-service-namestore
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
DATABASE = sqlite
+ZONEFILE_DIRECTORY = $SERVICEHOME/namestore/zonefiles
[namestore-sqlite]
FILENAME = $SERVICEHOME/namestore/sqlite.db
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 22fc860..5a42c14 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -29,6 +29,7 @@
/*
* Collect message types here, move to protocols later
*/
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_START 430
#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431
#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433
@@ -37,23 +38,64 @@
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE 437
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE 438
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE 440
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 439
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE 440
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 441
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 442
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 445
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE 446
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 447
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 448
-size_t
-GNUNET_NAMESTORE_records_serialize (char ** dest,
- unsigned int rd_count,
- const struct GNUNET_NAMESTORE_RecordData *rd);
+/**
+ * Convert a short hash to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
+ *
+ * @param hc the short hash code
+ * @return string form; will be overwritten by next call to GNUNET_h2s.
+ */
+const char *
+GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc);
+
+
+/**
+ * Sign name and records
+ *
+ * @param key the private key
+ * @param expire block expiration
+ * @param name the name
+ * @param rd record data
+ * @param rd_count number of records
+ *
+ * @return the signature
+ */
+struct GNUNET_CRYPTO_RsaSignature *
+GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ unsigned int rd_count);
+
+
+/**
+ * Compares if two records are equal
+ *
+ * @param a Record a
+ * @param b Record b
+ *
+ * @return GNUNET_YES or GNUNET_NO
+ */
int
-GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len);
+GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a,
+ const struct GNUNET_NAMESTORE_RecordData *b);
+
+GNUNET_NETWORK_STRUCT_BEGIN
/**
* A GNS record serialized for network transmission.
- * layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data]
+ *
+ * Layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data]
*/
struct GNUNET_NAMESTORE_NetworkRecord
{
@@ -80,9 +122,8 @@ struct GNUNET_NAMESTORE_NetworkRecord
-GNUNET_NETWORK_STRUCT_BEGIN
/**
- * Connect to namestore service
+ * Connect to namestore service. FIXME: UNNECESSARY.
*/
struct StartMessage
{
@@ -93,329 +134,451 @@ struct StartMessage
struct GNUNET_MessageHeader header;
};
-GNUNET_NETWORK_STRUCT_END
-GNUNET_NETWORK_STRUCT_BEGIN
/**
* Generic namestore message with op id
*/
-struct GenericMessage
+struct GNUNET_NAMESTORE_Header
{
/**
- * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_*
+ * header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_*
+ * header.size will be message size
*/
struct GNUNET_MessageHeader header;
/**
- * Operation ID in NBO
+ * Request ID in NBO
*/
- uint32_t op_id;
+ uint32_t r_id;
};
-GNUNET_NETWORK_STRUCT_END
/**
- * Connect to namestore service
+ * Lookup a name in the namestore
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct LookupNameMessage
{
+ struct GNUNET_NAMESTORE_Header gns_header;
+
/**
- * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME
+ * The zone
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
/**
- * Operation ID in NBO
+ * Requested record type
*/
- uint32_t op_id;
-
- /* The zone */
- GNUNET_HashCode zone;
-
- /* Requested record type */
uint32_t record_type;
- /* Requested record type */
+ /**
+ * Length of the name
+ */
uint32_t name_len;
+
+ /* 0-terminated name here */
};
-GNUNET_NETWORK_STRUCT_END
/**
* Lookup response
- * Memory layout:
- * [struct LookupNameResponseMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData][struct GNUNET_CRYPTO_RsaSignature]
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct LookupNameResponseMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * Operation ID in NBO
+ * Expiration time
*/
- uint32_t op_id;
-
struct GNUNET_TIME_AbsoluteNBO expire;
+
+ /**
+ * Name length
+ */
uint16_t name_len;
- uint16_t contains_sig;
+ /**
+ * Bytes of serialized record data
+ */
+ uint16_t rd_len;
+
+ /**
+ * Number of records contained
+ */
+ uint16_t rd_count;
+
+ /**
+ * Is the signature valid
+ * GNUNET_YES or GNUNET_NO
+ */
+ int16_t contains_sig;
- /* Requested record type */
- uint32_t rc_count;
+ /**
+ * All zeros if 'contains_sig' is GNUNET_NO.
+ */
+ struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * The public key for the name
+ */
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key;
+
+ /* 0-terminated name and serialized record data */
+ /* rd_len bytes serialized record data */
};
-GNUNET_NETWORK_STRUCT_END
/**
* Put a record to the namestore
- * Memory layout:
- * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData]
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordPutMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * Operation ID in NBO
+ * Expiration time
*/
- uint32_t op_id;
-
- /* Contenct starts here */
+ struct GNUNET_TIME_AbsoluteNBO expire;
- /* name length */
+ /**
+ * Name length
+ */
uint16_t name_len;
- /* Length of serialized rd data */
+ /**
+ * Length of serialized record data
+ */
uint16_t rd_len;
- struct GNUNET_TIME_AbsoluteNBO expire;
+ /**
+ * Number of records contained
+ */
+ uint16_t rd_count;
+
+ /**
+ * always zero (for alignment)
+ */
+ uint16_t reserved;
+ /**
+ * The signature
+ */
struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * The public key
+ */
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key;
+
+ /* name (0-terminated) followed by "rd_count" serialized records */
+
};
-GNUNET_NETWORK_STRUCT_END
+
/**
* Put a record to the namestore response
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordPutResponseMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE
*/
- struct GNUNET_MessageHeader header;
-
- /**
- * Operation ID in NBO
- */
- uint32_t op_id;
-
- /* Contenct starts here */
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success
+ * result:
+ * GNUNET_SYSERR on failure
+ * GNUNET_OK on success
*/
- uint16_t op_result;
+ int32_t op_result;
};
-GNUNET_NETWORK_STRUCT_END
/**
- * Put a record to the namestore
+ * Create a record and put it to the namestore
* Memory layout:
- * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData]
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordCreateMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
+
+ struct GNUNET_TIME_AbsoluteNBO expire;
/**
- * Operation ID in NBO
+ * Name length
*/
- uint32_t op_id;
+ uint16_t name_len;
- /* Contenct starts here */
+ /**
+ * Length of serialized record data
+ */
+ uint16_t rd_len;
- /* name length */
- uint16_t name_len;
+ /**
+ * Record count
+ */
+ uint16_t rd_count;
- struct GNUNET_CRYPTO_RsaSignature signature;
+ /**
+ * private key length
+ */
+ uint16_t pkey_len;
+
+ /* followed by:
+ * GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded private key with length pkey_len
+ * name with length name_len
+ * serialized record data with length rd_len
+ * */
};
-GNUNET_NETWORK_STRUCT_END
/**
* Create a record to the namestore response
- * Memory layout:
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordCreateResponseMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE
*/
- struct GNUNET_MessageHeader header;
-
- /**
- * Operation ID in NBO
- */
- uint32_t op_id;
-
- /* Contenct starts here */
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success
+ * name length: GNUNET_NO already exists, GNUNET_YES on success, GNUNET_SYSERR error
*/
- uint16_t op_result;
+ int32_t op_result;
};
-GNUNET_NETWORK_STRUCT_END
+
/**
* Remove a record from the namestore
* Memory layout:
- * [struct RecordRemoveMessage][char *name][struct GNUNET_NAMESTORE_RecordData]
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordRemoveMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * Operation ID in NBO
+ * Name length
*/
- uint32_t op_id;
+ uint16_t name_len;
- /* Contenct starts here */
+ /**
+ * Length of serialized rd data
+ */
+ uint16_t rd_len;
- /* name length */
- uint16_t name_len;
+ /**
+ * Number of records contained
+ */
+ uint16_t rd_count;
- struct GNUNET_CRYPTO_RsaSignature signature;
+ /**
+ * Length of private key
+ */
+ uint16_t pkey_len;
+
+ /* followed by:
+ * GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded private key with length pkey_len
+ * name with length name_len
+ * serialized record data with length rd_len
+ * */
};
-GNUNET_NETWORK_STRUCT_END
/**
* Remove a record from the namestore response
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct RecordRemoveResponseMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * Operation ID in NBO
+ * result:
+ * 0 : successful
+ * 1 : no records for entry
+ * 2 : Could not find record to remove
+ * 3 : Failed to create new signature
+ * 4 : Failed to put new set of records in database
+ */
+ int32_t op_result;
+};
+
+
+/**
+ * Lookup a name for a zone hash
+ */
+struct ZoneToNameMessage
+{
+ /**
+ * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
*/
- uint32_t op_id;
+ struct GNUNET_NAMESTORE_Header gns_header;
- /* Contenct starts here */
+ /**
+ * The hash of public key of the zone to look up in
+ */
+ struct GNUNET_CRYPTO_ShortHashCode zone;
/**
- * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success
+ * The hash of the public key of the target zone
*/
- uint16_t op_result;
+ struct GNUNET_CRYPTO_ShortHashCode value_zone;
};
-GNUNET_NETWORK_STRUCT_END
+
+/**
+ * Respone for zone to name lookup
+ */
+struct ZoneToNameResponseMessage
+{
+ /**
+ * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
+ */
+ struct GNUNET_NAMESTORE_Header gns_header;
+
+ /**
+ * Record block expiration
+ */
+ struct GNUNET_TIME_AbsoluteNBO expire;
+
+ /**
+ * Length of the name
+ */
+ uint16_t name_len;
+
+ /**
+ * Length of serialized record data
+ */
+ uint16_t rd_len;
+
+ /**
+ * Number of records contained
+ */
+ uint16_t rd_count;
+
+ /* result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error */
+ int16_t res;
+
+ /**
+ * Signature
+ */
+ struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * Publik key
+ */
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
+
+};
+
/**
* Start a zone iteration for the given zone
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct ZoneIterationStartMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
/**
- * Operation ID in NBO
+ * Zone hash
*/
- uint32_t op_id;
-
- /* Contenct starts here */
+ struct GNUNET_CRYPTO_ShortHashCode zone;
+ /**
+ * Which flags must be included
+ */
uint16_t must_have_flags;
- uint16_t must_not_have_flags;
- GNUNET_HashCode zone;
+ /**
+ * Which flags must not be included
+ */
+ uint16_t must_not_have_flags;
};
-GNUNET_NETWORK_STRUCT_END
+
/**
* Ask for next result of zone iteration for the given operation
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct ZoneIterationNextMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
*/
- struct GNUNET_MessageHeader header;
-
- /**
- * Operation ID in NBO
- */
- uint32_t op_id;
+ struct GNUNET_NAMESTORE_Header gns_header;
};
-GNUNET_NETWORK_STRUCT_END
/**
* Stop zone iteration for the given operation
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct ZoneIterationStopMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP
*/
- struct GNUNET_MessageHeader header;
-
- /**
- * Operation ID in NBO
- */
- uint32_t op_id;
+ struct GNUNET_NAMESTORE_Header gns_header;
};
-GNUNET_NETWORK_STRUCT_END
/**
- * Ask for next result of zone iteration for the given operation
+ * Next result of zone iteration for the given operation
+ * // FIXME: use 'struct LookupResponseMessage' instead? (identical except
+ * for having 'contains_sig' instead of 'reserved', but fully compatible otherwise).
*/
-GNUNET_NETWORK_STRUCT_BEGIN
struct ZoneIterationResponseMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE
*/
- struct GNUNET_MessageHeader header;
+ struct GNUNET_NAMESTORE_Header gns_header;
+
+ struct GNUNET_TIME_AbsoluteNBO expire;
+
+ uint16_t name_len;
+
+ /* Record data length */
+ uint16_t rd_len;
/**
- * Operation ID in NBO
+ * Number of records contained
*/
- uint32_t op_id;
+ uint16_t rd_count;
+
+ /**
+ * always zero (for alignment)
+ */
+ uint16_t reserved;
+
+ /**
+ * All zeros if 'contains_sig' is GNUNET_NO.
+ */
+ struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * The public key
+ */
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key;
+
+
+
};
GNUNET_NETWORK_STRUCT_END
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 1d41399..151fb97 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -27,11 +27,14 @@
#include "platform.h"
#include "gnunet_util_lib.h"
+#include "gnunet_crypto_lib.h"
#include "gnunet_constants.h"
+#include "gnunet_dnsparser_lib.h"
#include "gnunet_arm_service.h"
+#include "gnunet_signatures.h"
#include "gnunet_namestore_service.h"
#include "namestore.h"
-#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
+
#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
@@ -40,7 +43,15 @@
*/
struct GNUNET_NAMESTORE_QueueEntry
{
+
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_NAMESTORE_QueueEntry *next;
+
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_NAMESTORE_QueueEntry *prev;
struct GNUNET_NAMESTORE_Handle *nsh;
@@ -62,7 +73,15 @@ struct GNUNET_NAMESTORE_QueueEntry
*/
struct GNUNET_NAMESTORE_ZoneIterator
{
+
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_NAMESTORE_ZoneIterator *next;
+
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_NAMESTORE_ZoneIterator *prev;
uint32_t op_id;
@@ -70,9 +89,10 @@ struct GNUNET_NAMESTORE_ZoneIterator
struct GNUNET_NAMESTORE_Handle *h;
GNUNET_NAMESTORE_RecordProcessor proc;
void* proc_cls;
- GNUNET_HashCode zone;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
uint32_t no_flags;
uint32_t flags;
+ int has_zone;
};
@@ -172,7 +192,7 @@ struct GNUNET_NAMESTORE_SimpleRecord
struct GNUNET_NAMESTORE_SimpleRecord *prev;
const char *name;
- const GNUNET_HashCode *zone;
+ const struct GNUNET_CRYPTO_ShortHashCode *zone;
uint32_t record_type;
struct GNUNET_TIME_Absolute expiration;
enum GNUNET_NAMESTORE_RecordFlags flags;
@@ -181,6 +201,7 @@ struct GNUNET_NAMESTORE_SimpleRecord
};
+
/**
* Disconnect from service and then reconnect.
*
@@ -198,57 +219,77 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
"LOOKUP_NAME_RESPONSE");
struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
+
+ /* Operation done, remove */
+ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
+
+
char *name;
- struct GNUNET_NAMESTORE_RecordData *rd = NULL;
+ char * rd_tmp;
+
struct GNUNET_CRYPTO_RsaSignature *signature = NULL;
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy;
struct GNUNET_TIME_Absolute expire;
- unsigned int rd_count = 0;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key_tmp;
+ size_t exp_msg_len;
size_t msg_len = 0;
size_t name_len = 0;
+ size_t rd_len = 0;
int contains_sig = GNUNET_NO;
+ int rd_count = 0;
- rd_count = ntohl (msg->rc_count);
- msg_len = ntohs (msg->header.size);
+ rd_len = ntohs (msg->rd_len);
+ rd_count = ntohs (msg->rd_count);
+ msg_len = ntohs (msg->gns_header.header.size);
name_len = ntohs (msg->name_len);
contains_sig = ntohs (msg->contains_sig);
expire = GNUNET_TIME_absolute_ntoh(msg->expire);
- if (msg_len != sizeof (struct LookupNameResponseMessage) +
+ exp_msg_len = sizeof (struct LookupNameResponseMessage) +
sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
- name_len +
- rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData) +
- contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature))
+ name_len + rd_len;
+
+ if (msg_len != exp_msg_len)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
+ msg_len, exp_msg_len);
+ GNUNET_break_op (0);
+ return;
+ }
+
+ name = (char *) &msg[1];
+ if (name_len > 0)
+ {
+ GNUNET_assert ('\0' == name[name_len -1]);
+ GNUNET_assert ((name_len - 1) == strlen(name));
+ }
+ rd_tmp = &name[name_len];
+
+ /* deserialize records */
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
{
GNUNET_break_op (0);
return;
}
- zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1];
- name = (char *) &zone_key[1];
- rd = (struct GNUNET_NAMESTORE_RecordData *) &name[name_len];
/* reset values if values not contained */
if (contains_sig == GNUNET_NO)
signature = NULL;
else
- signature = (struct GNUNET_CRYPTO_RsaSignature *) &rd[rd_count];
- if (rd_count == 0)
- rd = NULL;
+ signature = &msg->signature;
if (name_len == 0)
name = NULL;
- memset (&dummy, '0', sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
- if (0 == memcmp (zone_key, &dummy, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
- zone_key = NULL;
+ if (name != NULL)
+ public_key_tmp = &msg->public_key;
+ else
+ public_key_tmp = NULL;
if (qe->proc != NULL)
{
- qe->proc (qe->proc_cls, zone_key, expire, name, rd_count, rd, signature);
+ qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, (rd_count > 0) ? rd : NULL, signature);
}
- /* Operation done, remove */
- GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
GNUNET_free (qe);
}
@@ -262,20 +303,21 @@ handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
"RECORD_PUT_RESPONSE");
struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
- int res = GNUNET_OK;
+ /* Operation done, remove */
+ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
+
+ int res = ntohl (msg->op_result);
- if (ntohs (msg->op_result) == GNUNET_OK)
+ if (res == GNUNET_OK)
{
- res = GNUNET_OK;
if (qe->cont != NULL)
{
qe->cont (qe->cont_cls, res, _("Namestore added record successfully"));
}
}
- else if (ntohs (msg->op_result) == GNUNET_NO)
+ else if (res == GNUNET_SYSERR)
{
- res = GNUNET_SYSERR;
if (qe->cont != NULL)
{
qe->cont (qe->cont_cls, res, _("Namestore failed to add record"));
@@ -287,9 +329,6 @@ handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
return;
}
- /* Operation done, remove */
- GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
-
GNUNET_free (qe);
}
@@ -303,34 +342,165 @@ handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
"RECORD_CREATE_RESPONSE");
struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
- int res = GNUNET_OK;
+ /* Operation done, remove */
+ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
- if (ntohs (msg->op_result) == GNUNET_OK)
+ int res = ntohl (msg->op_result);
+ if (res == GNUNET_YES)
{
- res = GNUNET_OK;
if (qe->cont != NULL)
{
qe->cont (qe->cont_cls, res, _("Namestore added record successfully"));
}
}
- else if (ntohs (msg->op_result) == GNUNET_NO)
+ else if (res == GNUNET_NO)
{
- res = GNUNET_SYSERR;
if (qe->cont != NULL)
{
- qe->cont (qe->cont_cls, res, _("Namestore failed to add record"));
+ qe->cont (qe->cont_cls, res, _("Namestore record already existed"));
}
}
else
{
- GNUNET_break_op (0);
- return;
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Namestore failed to add record\n"));
+ }
+ }
+
+ GNUNET_free (qe);
+}
+
+
+static void
+handle_record_remove_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+ struct RecordRemoveResponseMessage* msg,
+ size_t size)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
+ "RECORD_REMOVE_RESPONSE");
+
+ struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
+ /* Operation done, remove */
+ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
+
+ int res = ntohl (msg->op_result);
+ /**
+ * result:
+ * 0 : successful
+ * 1 : No records for entry
+ * 2 : Could not find record to remove
+ * 3 : Failed to create new signature
+ * 4 : Failed to put new set of records in database
+ */
+ switch (res) {
+ case 0:
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_YES, _("Namestore removed record successfully"));
+ }
+
+ break;
+ case 1:
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_NO, _("No records for entry"));
+ }
+
+ break;
+ case 2:
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_NO, _("Could not find record to remove"));
+ }
+
+ break;
+ case 3:
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to create new signature"));
+ }
+
+ break;
+ case 4:
+ if (qe->cont != NULL)
+ {
+ qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to put new set of records in database"));
+ }
+ break;
+ default:
+ GNUNET_break_op (0);
+ break;
}
+ GNUNET_free (qe);
+}
+
+static void
+handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+ struct ZoneToNameResponseMessage* msg,
+ size_t size)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
+ "ZONE_TO_NAME_RESPONSE");
+
+ struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
/* Operation done, remove */
GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
+ int res = ntohs (msg->res);
+
+ struct GNUNET_TIME_Absolute expire;
+ size_t name_len;
+ size_t rd_ser_len;
+ unsigned int rd_count;
+
+ char * name_tmp;
+ char * rd_tmp;
+
+ if (res == GNUNET_SYSERR)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "An error occured during zone to name operation\n");
+ if (qe->proc != NULL)
+ qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
+ }
+ else if (res == GNUNET_NO)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has no result for zone to name mapping \n");
+ if (qe->proc != NULL)
+ qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
+ }
+ else if (res == GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has result for zone to name mapping \n");
+
+ name_len = ntohs (msg->name_len);
+ rd_count = ntohs (msg->rd_count);
+ rd_ser_len = ntohs (msg->rd_len);
+ expire = GNUNET_TIME_absolute_ntoh(msg->expire);
+
+ name_tmp = (char *) &msg[1];
+ if (name_len > 0)
+ {
+ GNUNET_assert ('\0' == name_tmp[name_len -1]);
+ GNUNET_assert (name_len -1 == strlen(name_tmp));
+ }
+ rd_tmp = &name_tmp[name_len];
+
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+
+ if (qe->proc != NULL)
+ qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, &msg->signature);
+ }
+ else
+ GNUNET_break_op (0);
+
GNUNET_free (qe);
}
@@ -367,6 +537,22 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
}
handle_record_create_response (qe, (struct RecordCreateResponseMessage *) msg, size);
break;
+ case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE:
+ if (size != sizeof (struct RecordRemoveResponseMessage))
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ handle_record_remove_response (qe, (struct RecordRemoveResponseMessage *) msg, size);
+ break;
+ case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
+ if (size < sizeof (struct ZoneToNameResponseMessage))
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ handle_zone_to_name_response (qe, (struct ZoneToNameResponseMessage *) msg, size);
+ break;
default:
GNUNET_break_op (0);
break;
@@ -381,12 +567,67 @@ handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
"ZONE_ITERATION_RESPONSE");
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubdummy;
+ size_t msg_len = 0;
+ size_t exp_msg_len = 0;
+ size_t name_len = 0;
+ size_t rd_len = 0;
+ unsigned rd_count = 0;
- if (ze->proc != NULL)
+ char *name_tmp;
+ char *rd_ser_tmp;
+ struct GNUNET_TIME_Absolute expire;
+
+ msg_len = ntohs (msg->gns_header.header.size);
+ rd_len = ntohs (msg->rd_len);
+ rd_count = ntohs (msg->rd_count);
+ name_len = ntohs (msg->name_len);
+ expire = GNUNET_TIME_absolute_ntoh (msg->expire);
+
+ exp_msg_len = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_len;
+ if (msg_len != exp_msg_len)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
+ msg_len, exp_msg_len);
+ GNUNET_break_op (0);
+ return;
+ }
+ if (0 != ntohs (msg->reserved))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+
+ memset (&pubdummy, '\0', sizeof (pubdummy));
+ if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof (pubdummy)))))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n");
+
+ GNUNET_CONTAINER_DLL_remove(ze->h->z_head, ze->h->z_tail, ze);
+
+ if (ze->proc != NULL)
+ ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, NULL);
+
+ GNUNET_free (ze);
+ return;
+ }
+
+ name_tmp = (char *) &msg[1];
+ if ((name_tmp[name_len -1] != '\0') || (name_len > 256))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ rd_ser_tmp = (char *) &name_tmp[name_len];
+ struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd))
{
- // FIXME
- ze->proc(ze->proc_cls, NULL, GNUNET_TIME_absolute_get_forever(), "dummy", 0, NULL, NULL);
+ GNUNET_break_op (0);
+ return;
}
+
+ if (ze->proc != NULL)
+ ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, &msg->signature);
}
@@ -423,12 +664,12 @@ static void
process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_NAMESTORE_Handle *h = cls;
- struct GenericMessage * gm;
+ struct GNUNET_NAMESTORE_Header * gm;
struct GNUNET_NAMESTORE_QueueEntry *qe;
struct GNUNET_NAMESTORE_ZoneIterator *ze;
uint16_t size;
uint16_t type;
- uint32_t op_id = UINT32_MAX;
+ uint32_t r_id = UINT32_MAX;
if (NULL == msg)
{
@@ -439,7 +680,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
size = ntohs (msg->size);
type = ntohs (msg->type);
- if (size < sizeof (struct GenericMessage))
+ if (size < sizeof (struct GNUNET_NAMESTORE_Header))
{
GNUNET_break_op (0);
GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
@@ -447,13 +688,13 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
return;
}
- gm = (struct GenericMessage *) msg;
- op_id = ntohl (gm->op_id);
+ gm = (struct GNUNET_NAMESTORE_Header *) msg;
+ r_id = ntohl (gm->r_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message type %i size %i op %u\n", type, size, op_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message type %i size %i op %u\n", type, size, r_id);
/* Find matching operation */
- if (op_id > h->op_id)
+ if (r_id > h->op_id)
{
/* No matching pending operation found */
GNUNET_break_op (0);
@@ -465,7 +706,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
/* Is it a record related operation ? */
for (qe = h->op_head; qe != NULL; qe = qe->next)
{
- if (qe->op_id == op_id)
+ if (qe->op_id == r_id)
break;
}
if (qe != NULL)
@@ -476,7 +717,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
/* Is it a zone iteration operation ? */
for (ze = h->z_head; ze != NULL; ze = ze->next)
{
- if (ze->op_id == op_id)
+ if (ze->op_id == r_id)
break;
}
if (ze != NULL)
@@ -622,7 +863,7 @@ static void
force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
{
h->reconnect = GNUNET_NO;
- GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (h->client);
h->client = NULL;
h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
&reconnect_task,
@@ -655,23 +896,15 @@ GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
return h;
}
-
-/**
- * Disconnect from the namestore service (and free associated
- * resources).
- *
- * @param h handle to the namestore
- * @param drop set to GNUNET_YES to delete all data in namestore (!)
- */
-void
-GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop)
+static void
+clean_up_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct PendingMessage *p;
struct GNUNET_NAMESTORE_QueueEntry *q;
struct GNUNET_NAMESTORE_ZoneIterator *z;
-
+ struct GNUNET_NAMESTORE_Handle *h = cls;
GNUNET_assert (h != NULL);
-
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
while (NULL != (p = h->pending_head))
{
GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
@@ -692,7 +925,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop)
if (NULL != h->client)
{
- GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (h->client);
h->client = NULL;
}
if (GNUNET_SCHEDULER_NO_TASK != h->reconnect_task)
@@ -706,6 +939,21 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop)
/**
+ * Disconnect from the namestore service (and free associated
+ * resources).
+ *
+ * @param h handle to the namestore
+ * @param drop set to GNUNET_YES to delete all data in namestore (!)
+ */
+void
+GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from namestore service\n");
+ GNUNET_SCHEDULER_add_now (&clean_up_task, h);
+}
+
+
+/**
* Store an item in the namestore. If the item is already present,
* the expiration time is updated to the max of the existing time and
* the new time. This API is used when we cache signatures from other
@@ -714,7 +962,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop)
* @param h handle to the namestore
* @param zone_key public key of the zone
* @param name name that is being mapped (at most 255 characters long)
- * @param expire when does the corresponding block in the DHT expire (until
+ * @param freshness when does the corresponding block in the DHT expire (until
* when should we never do a DHT lookup for the same name again)?
* @param rd_count number of entries in 'rd' array
* @param rd array of records with data to store
@@ -727,7 +975,7 @@ struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
const char *name,
- struct GNUNET_TIME_Absolute expire,
+ struct GNUNET_TIME_Absolute freshness,
unsigned int rd_count,
const struct GNUNET_NAMESTORE_RecordData *rd,
const struct GNUNET_CRYPTO_RsaSignature *signature,
@@ -738,52 +986,63 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
struct PendingMessage *pe;
/* pointer to elements */
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp;
char * rd_tmp;
- char * rd_ser;
char * name_tmp;
size_t msg_size = 0;
- size_t name_len = strlen(name) + 1;
+ size_t name_len = 0;
size_t rd_ser_len = 0;
- uint32_t id = 0;
+ uint32_t rid = 0;
GNUNET_assert (NULL != h);
- id = get_op_id(h);
+ GNUNET_assert (NULL != zone_key);
+ GNUNET_assert (NULL != name);
+ GNUNET_assert (NULL != rd);
+ GNUNET_assert (NULL != signature);
+
+ name_len = strlen(name) + 1;
+ if (name_len > 256)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+
+ rid = get_op_id(h);
qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
qe->nsh = h;
qe->cont = cont;
qe->cont_cls = cont_cls;
- qe->op_id = id;
+ qe->op_id = rid;
GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
/* set msg_size*/
- rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, rd_count, rd);
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
struct RecordPutMessage * msg;
- msg_size = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_ser_len;
+ msg_size = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
/* create msg here */
pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
pe->size = msg_size;
pe->is_init = GNUNET_NO;
msg = (struct RecordPutMessage *) &pe[1];
- zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1];
- name_tmp = (char *) &zone_key_tmp[1];
+ name_tmp = (char *) &msg[1];
rd_tmp = &name_tmp[name_len];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (id);
- memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
msg->signature = *signature;
msg->name_len = htons (name_len);
- memcpy (name_tmp, name, name_len);
- msg->expire = GNUNET_TIME_absolute_hton (expire);
+ msg->expire = GNUNET_TIME_absolute_hton (freshness);
msg->rd_len = htons (rd_ser_len);
+ msg->rd_count = htons (rd_count);
+ msg->public_key = *zone_key;
+ memcpy (name_tmp, name, name_len);
memcpy (rd_tmp, rd_ser, rd_ser_len);
- GNUNET_free (rd_ser);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size);
@@ -799,6 +1058,7 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
* to validate signatures received from the network.
*
* @param public_key public key of the zone
+ * @param expire block expiration
* @param name name that is being mapped (at most 255 characters long)
* @param rd_count number of entries in 'rd' array
* @param rd array of records with data to store
@@ -807,12 +1067,53 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
*/
int
GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
+ const struct GNUNET_TIME_Absolute expire,
const char *name,
unsigned int rd_count,
const struct GNUNET_NAMESTORE_RecordData *rd,
const struct GNUNET_CRYPTO_RsaSignature *signature)
{
- return GNUNET_SYSERR;
+ int res = GNUNET_SYSERR;
+ size_t rd_ser_len = 0;
+ size_t name_len = 0;
+ char * name_tmp;
+ char * rd_tmp;
+ struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
+ struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
+ struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire);
+
+ GNUNET_assert (public_key != NULL);
+ GNUNET_assert (name != NULL);
+ GNUNET_assert (rd != NULL);
+ GNUNET_assert (signature != NULL);
+
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
+
+ name_len = strlen (name) + 1;
+ if (name_len > 256)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len);
+ sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len);
+ sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
+ name_tmp = (char *) &expire_tmp[1];
+ rd_tmp = &name_tmp[name_len];
+ memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
+ memcpy (name_tmp, name, name_len);
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+
+ res = GNUNET_CRYPTO_rsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key);
+
+ GNUNET_free (sig_purpose);
+
+ return res;
}
/**
@@ -839,26 +1140,45 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
struct GNUNET_NAMESTORE_QueueEntry *qe;
struct PendingMessage *pe;
char * name_tmp;
+ char * pkey_tmp;
char * rd_tmp;
- char * rd_ser;
size_t rd_ser_len = 0;
size_t msg_size = 0;
size_t name_len = 0;
- uint32_t id = 0;
+ size_t key_len = 0;
+ uint32_t rid = 0;
GNUNET_assert (NULL != h);
+ GNUNET_assert (NULL != pkey);
+ GNUNET_assert (NULL != name);
+ GNUNET_assert (NULL != rd);
+
+ name_len = strlen(name) + 1;
+ if (name_len > 256)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
- id = get_op_id(h);
+ rid = get_op_id(h);
qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
qe->nsh = h;
qe->cont = cont;
qe->cont_cls = cont_cls;
- qe->op_id = id;
+ qe->op_id = rid;
+ GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
/* set msg_size*/
- rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, 1, rd);
+ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey);
+ GNUNET_assert (pkey_enc != NULL);
+ key_len = ntohs (pkey_enc->len);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(1, rd, rd_ser_len, rd_ser);
+
struct RecordCreateMessage * msg;
- msg_size = sizeof (struct RecordCreateMessage) + name_len + rd_ser_len;
+ msg_size = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
/* create msg here */
pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
@@ -866,17 +1186,22 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
pe->is_init = GNUNET_NO;
msg = (struct RecordCreateMessage *) &pe[1];
- name_tmp = (char *) &msg[1];
+ pkey_tmp = (char *) &msg[1];
+ name_tmp = &pkey_tmp[key_len];
rd_tmp = &name_tmp[name_len];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (id);
- //msg->signature = *signature;
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
msg->name_len = htons (name_len);
+ msg->rd_count = htons (1);
+ msg->rd_len = htons (rd_ser_len);
+ msg->pkey_len = htons (key_len);
+ msg->expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_FOREVER_ABS);
+ memcpy (pkey_tmp, pkey_enc, key_len);
memcpy (name_tmp, name, name_len);
memcpy (rd_tmp, rd_ser, rd_ser_len);
- GNUNET_free (rd_ser);
+ GNUNET_free (pkey_enc);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_CREATE", name, msg_size);
@@ -896,7 +1221,7 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
* @param h handle to the namestore
* @param pkey private key of the zone
* @param name name that is being mapped (at most 255 characters long)
- * @param rd record data
+ * @param rd record data, remove specific record, NULL to remove the name and all records
* @param cont continuation to call when done
* @param cont_cls closure for cont
* @return handle to abort the request
@@ -911,27 +1236,43 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
{
struct GNUNET_NAMESTORE_QueueEntry *qe;
struct PendingMessage *pe;
- char * rd_tmp;
- char * rd_ser;
- char * name_tmp;
+ char *pkey_tmp;
+ char *rd_tmp;
+ char *name_tmp;
size_t rd_ser_len = 0;
size_t msg_size = 0;
size_t name_len = 0;
- uint32_t id = 0;
+ size_t key_len = 0;
+ uint32_t rid = 0;
+ uint16_t rd_count = 1;
GNUNET_assert (NULL != h);
- id = get_op_id(h);
+ rid = get_op_id(h);
qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
qe->nsh = h;
qe->cont = cont;
qe->cont_cls = cont_cls;
- qe->op_id = id;
+ qe->op_id = rid;
+ GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
/* set msg_size*/
- rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, 1, rd);
+ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey);
+ GNUNET_assert (pkey_enc != NULL);
+ key_len = ntohs (pkey_enc->len);
+
+ if (NULL == rd)
+ rd_count = 0;
+ else
+ rd_count = 1;
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
+
+ name_len = strlen (name) + 1;
+
struct RecordRemoveMessage * msg;
- msg_size = sizeof (struct RecordRemoveMessage) + name_len + rd_ser_len;
+ msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
/* create msg here */
pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
@@ -939,17 +1280,22 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
pe->is_init = GNUNET_NO;
msg = (struct RecordRemoveMessage *) &pe[1];
- name_tmp = (char *) &msg[1];
+ pkey_tmp = (char *) &msg[1];
+ name_tmp = &pkey_tmp[key_len];
rd_tmp = &name_tmp[name_len];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (id);
- //msg->signature = *signature;
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
msg->name_len = htons (name_len);
+ msg->rd_len = htons (rd_ser_len);
+ msg->rd_count = htons (rd_count);
+ msg->pkey_len = htons (key_len);
+ memcpy (pkey_tmp, pkey_enc, key_len);
memcpy (name_tmp, name, name_len);
memcpy (rd_tmp, rd_ser, rd_ser_len);
- GNUNET_free (rd_ser);
+
+ GNUNET_free (pkey_enc);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_REMOVE", name, msg_size);
@@ -975,7 +1321,7 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
*/
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
- const GNUNET_HashCode *zone,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
const char *name,
uint32_t record_type,
GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
@@ -984,7 +1330,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
struct PendingMessage *pe;
size_t msg_size = 0;
size_t name_len = 0;
- uint32_t id = 0;
+ uint32_t rid = 0;
GNUNET_assert (NULL != h);
GNUNET_assert (NULL != zone);
@@ -997,12 +1343,12 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
return NULL;
}
- id = get_op_id(h);
+ rid = get_op_id(h);
qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
qe->nsh = h;
qe->proc = proc;
qe->proc_cls = proc_cls;
- qe->op_id = id;
+ qe->op_id = rid;
GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
/* set msg_size*/
@@ -1014,12 +1360,12 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
pe->size = msg_size;
pe->is_init = GNUNET_NO;
msg = (struct LookupNameMessage *) &pe[1];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (id);
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
msg->record_type = htonl (record_type);
- msg->zone = *zone;
msg->name_len = htonl (name_len);
+ msg->zone = *zone;
memcpy (&msg[1], name, name_len);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name);
@@ -1032,6 +1378,72 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
}
+/**
+ * Look for an existing PKEY delegation record for a given public key.
+ * Returns at most one result to the processor.
+ *
+ * @param h handle to the namestore
+ * @param zone hash of public key of the zone to look up in, never NULL
+ * @param value_zone hash of the public key of the target zone (value), never NULL
+ * @param proc function to call on the matching records, or with
+ * NULL (rd_count == 0) if there are no matching records
+ * @param proc_cls closure for proc
+ * @return a handle that can be used to
+ * cancel
+ */
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
+ const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
+ GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
+{
+ struct GNUNET_NAMESTORE_QueueEntry *qe;
+ struct PendingMessage *pe;
+ size_t msg_size = 0;
+ uint32_t rid = 0;
+
+ GNUNET_assert (NULL != h);
+ GNUNET_assert (NULL != zone);
+ GNUNET_assert (NULL != value_zone);
+
+ rid = get_op_id(h);
+ qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
+ qe->nsh = h;
+ qe->proc = proc;
+ qe->proc_cls = proc_cls;
+ qe->op_id = rid;
+ GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
+
+ /* set msg_size*/
+ msg_size = sizeof (struct ZoneToNameMessage);
+ pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+
+ /* create msg here */
+ struct ZoneToNameMessage * msg;
+ pe->size = msg_size;
+ pe->is_init = GNUNET_NO;
+ msg = (struct ZoneToNameMessage *) &pe[1];
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
+ msg->zone = *zone;
+ msg->value_zone = *value_zone;
+
+ char * z_tmp = GNUNET_strdup (GNUNET_short_h2s (zone));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s' in zone `%s'\n",
+ "NAMESTORE_ZONE_TO_NAME",
+ z_tmp,
+ GNUNET_short_h2s (value_zone));
+ GNUNET_free (z_tmp);
+
+ /* transmit message */
+ GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
+ do_transmit(h);
+
+ return qe;
+}
+
+
/**
* Starts a new zone iteration (used to periodically PUT all of our
@@ -1053,7 +1465,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
*/
struct GNUNET_NAMESTORE_ZoneIterator *
GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
- const GNUNET_HashCode *zone,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
enum GNUNET_NAMESTORE_RecordFlags must_have_flags,
enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
GNUNET_NAMESTORE_RecordProcessor proc,
@@ -1062,18 +1474,28 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
struct GNUNET_NAMESTORE_ZoneIterator *it;
struct PendingMessage *pe;
size_t msg_size = 0;
- uint32_t id = 0;
+ uint32_t rid = 0;
GNUNET_assert (NULL != h);
- GNUNET_assert (NULL != zone);
- id = get_op_id(h);
+
+ rid = get_op_id(h);
it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator));
it->h = h;
it->proc = proc;
- it->proc_cls = proc;
- it->op_id = id;
- it->zone = *zone;
+ it->proc_cls = proc_cls;
+ it->op_id = rid;
+
+ if (NULL != zone)
+ {
+ it->zone = *zone;
+ it->has_zone = GNUNET_YES;
+ }
+ else
+ {
+ memset (&it->zone, '\0', sizeof (it->zone));
+ it->has_zone = GNUNET_NO;
+ }
GNUNET_CONTAINER_DLL_insert_tail(h->z_head, h->z_tail, it);
/* set msg_size*/
@@ -1085,14 +1507,23 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
pe->size = msg_size;
pe->is_init = GNUNET_NO;
msg = (struct ZoneIterationStartMessage *) &pe[1];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (id);
- msg->zone = *zone;
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (rid);
+ if (NULL != zone)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_START", GNUNET_short_h2s(zone));
+ msg->zone = *zone;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_START");
+ memset (&msg->zone, '\0', sizeof (msg->zone));
+ }
msg->must_have_flags = ntohs (must_have_flags);
msg->must_not_have_flags = ntohs (must_not_have_flags);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_START", GNUNET_h2s(zone));
+
/* transmit message */
GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
@@ -1117,6 +1548,15 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
GNUNET_assert (NULL != it);
h = it->h;
+ struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head;
+
+ while (tmp != NULL)
+ {
+ if (tmp == it)
+ break;
+ tmp = tmp->next;
+ }
+ GNUNET_assert (NULL != tmp);
/* set msg_size*/
msg_size = sizeof (struct ZoneIterationNextMessage);
@@ -1127,11 +1567,11 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
pe->size = msg_size;
pe->is_init = GNUNET_NO;
msg = (struct ZoneIterationNextMessage *) &pe[1];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (it->op_id);
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (it->op_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "ZONE_ITERATION_NEXT", GNUNET_h2s(&it->zone));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_NEXT");
/* transmit message */
GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
@@ -1151,6 +1591,15 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
struct PendingMessage *pe;
size_t msg_size = 0;
struct GNUNET_NAMESTORE_Handle *h = it->h;
+ struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head;
+
+ while (tmp != NULL)
+ {
+ if (tmp == it)
+ break;
+ tmp = tmp->next;
+ }
+ GNUNET_assert (NULL != tmp);
/* set msg_size*/
msg_size = sizeof (struct ZoneIterationStopMessage);
@@ -1161,11 +1610,14 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
pe->size = msg_size;
pe->is_init = GNUNET_NO;
msg = (struct ZoneIterationStopMessage *) &pe[1];
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
- msg->header.size = htons (msg_size);
- msg->op_id = htonl (it->op_id);
+ msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
+ msg->gns_header.header.size = htons (msg_size);
+ msg->gns_header.r_id = htonl (it->op_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "ZONE_ITERATION_STOP", GNUNET_h2s(&it->zone));
+ if (GNUNET_YES == it->has_zone)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_short_h2s(&it->zone));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");
/* transmit message */
GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c
index 37f0eab..95f6364 100644
--- a/src/namestore/namestore_common.c
+++ b/src/namestore/namestore_common.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -28,132 +28,536 @@
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_constants.h"
+#include "gnunet_signatures.h"
#include "gnunet_arm_service.h"
#include "gnunet_namestore_service.h"
+#include "gnunet_dnsparser_lib.h"
#include "namestore.h"
-#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
+
#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
+
+
+/**
+ * Internal format of a record in the serialized form.
+ */
+struct NetworkRecord
+{
+
+ /**
+ * Expiration time for the DNS record.
+ */
+ struct GNUNET_TIME_AbsoluteNBO expiration;
+
+ /**
+ * Number of bytes in 'data', network byte order.
+ */
+ uint32_t data_size;
+
+ /**
+ * Type of the GNS/DNS record, network byte order.
+ */
+ uint32_t record_type;
+
+ /**
+ * Flags for the record, network byte order.
+ */
+ uint32_t flags;
+
+};
+
+
/**
- * Serialize an array of GNUNET_NAMESTORE_RecordData *rd to transmit over the
- * network
+ * Convert a short hash to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
*
- * @param dest where to write the serialized data
- * @param rd_count number of elements in array
- * @param rd array
+ * @param hc the short hash code
+ * @return string form; will be overwritten by next call to GNUNET_h2s.
+ */
+const char *
+GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc)
+{
+ static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret;
+
+ GNUNET_CRYPTO_short_hash_to_enc (hc, &ret);
+ return (const char *) &ret;
+}
+
+
+/**
+ * Calculate how many bytes we will need to serialize the given
+ * records.
+ *
+ * @param rd_count number of records in the rd array
+ * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements
+ *
+ * @return the required size to serialize
*
- * @return number of bytes written to destination dest
*/
size_t
-GNUNET_NAMESTORE_records_serialize (char ** dest,
- unsigned int rd_count,
- const struct GNUNET_NAMESTORE_RecordData *rd)
+GNUNET_NAMESTORE_records_get_size (unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd)
{
- //size_t len = 0;
- struct GNUNET_NAMESTORE_NetworkRecord * nr;
- char * d = (*dest);
- int c = 0;
- int offset;
+ unsigned int i;
+ size_t ret;
+ ret = sizeof (struct NetworkRecord) * rd_count;
+ for (i=0;i<rd_count;i++)
+ {
+ GNUNET_assert ((ret + rd[i].data_size) >= ret);
+ ret += rd[i].data_size;
+ }
+ return ret;
+}
- size_t total_len = rd_count * sizeof (struct GNUNET_NAMESTORE_NetworkRecord);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Struct size: %u\n", total_len);
- /* figure out total len required */
- for (c = 0; c < rd_count; c ++)
+/**
+ * Serialize the given records to the given destination buffer.
+ *
+ * @param rd_count number of records in the rd array
+ * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements
+ * @param dest_size size of the destination array
+ * @param dest where to write the result
+ *
+ * @return the size of serialized records
+ */
+ssize_t
+GNUNET_NAMESTORE_records_serialize (unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ size_t dest_size,
+ char *dest)
+{
+ struct NetworkRecord rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<rd_count;i++)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data size record[%i] : %u\n", c, rd[c].data_size);
- total_len += rd[c].data_size;
+ rec.expiration = GNUNET_TIME_absolute_hton (rd[i].expiration);
+ rec.data_size = htonl ((uint32_t) rd[i].data_size);
+ rec.record_type = htonl (rd[i].record_type);
+ rec.flags = htonl (rd[i].flags);
+ if (off + sizeof (rec) > dest_size)
+ return -1;
+ memcpy (&dest[off], &rec, sizeof (rec));
+ off += sizeof (rec);
+ if (off + rd[i].data_size > dest_size)
+ return -1;
+ memcpy (&dest[off], rd[i].data, rd[i].data_size);
+ off += rd[i].data_size;
}
+ return off;
+}
+
+/**
+ * Compares if two records are equal
+ *
+ * @param a record
+ * @param b record
+ *
+ * @return GNUNET_YES or GNUNET_NO
+ */
+int
+GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a,
+ const struct GNUNET_NAMESTORE_RecordData *b)
+{
+ if ((a->record_type == b->record_type) &&
+ (a->expiration.abs_value == b->expiration.abs_value) &&
+ (a->data_size == b->data_size) &&
+ (0 == memcmp (a->data, b->data, a->data_size)))
+ return GNUNET_YES;
+ else
+ return GNUNET_NO;
+}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serializing %i records with total length of %llu\n", rd_count, total_len);
- (*dest) = GNUNET_malloc (total_len);
- d = (*dest);
+/**
+ * Deserialize the given records to the given destination.
+ *
+ * @param len size of the serialized record data
+ * @param src the serialized record data
+ * @param rd_count number of records in the rd array
+ * @param dest where to put the data
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_NAMESTORE_records_deserialize (size_t len,
+ const char *src,
+ unsigned int rd_count,
+ struct GNUNET_NAMESTORE_RecordData *dest)
+{
+ struct NetworkRecord rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<rd_count;i++)
+ {
+ if (off + sizeof (rec) > len)
+ return GNUNET_SYSERR;
+ memcpy (&rec, &src[off], sizeof (rec));
+ dest[i].expiration = GNUNET_TIME_absolute_ntoh (rec.expiration);
+ dest[i].data_size = ntohl ((uint32_t) rec.data_size);
+ dest[i].record_type = ntohl (rec.record_type);
+ dest[i].flags = ntohl (rec.flags);
+ off += sizeof (rec);
- /* copy records */
- offset = 0;
+ if (off + dest[i].data_size > len)
+ return GNUNET_SYSERR;
+ dest[i].data = &src[off];
+ off += dest[i].data_size;
+ }
+ return GNUNET_OK;
+}
- for (c = 0; c < rd_count; c ++)
+/**
+ * Sign name and records
+ *
+ * @param key the private key
+ * @param expire block expiration
+ * @param name the name
+ * @param rd record data
+ * @param rd_count number of records
+ *
+ * @return the signature
+ */
+struct GNUNET_CRYPTO_RsaSignature *
+GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ unsigned int rd_count)
+{
+ struct GNUNET_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature));
+ struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
+ struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire);
+ size_t rd_ser_len;
+ size_t name_len;
+
+ struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
+ char * name_tmp;
+ char * rd_tmp;
+ int res;
+
+ if (name == NULL)
+ {
+ GNUNET_break (0);
+ GNUNET_free (sig);
+ return NULL;
+ }
+ name_len = strlen (name) + 1;
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
+
+ sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len);
+ sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len);
+ sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
+ name_tmp = (char *) &expire_tmp[1];
+ rd_tmp = &name_tmp[name_len];
+ memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
+ memcpy (name_tmp, name, name_len);
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+
+ res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig);
+
+ GNUNET_free (sig_purpose);
+
+ if (GNUNET_OK != res)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized record [%i]: data_size %i\n", c,rd[c].data_size);
-
- nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &d[offset];
- nr->data_size = htonl (rd[c].data_size);
- nr->flags = htonl (rd[c].flags);
- nr->record_type = htonl (rd[c].record_type);
- nr->expiration = GNUNET_TIME_absolute_hton(rd[c].expiration);
-
- /*put data here */
- offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord);
- memcpy (&d[offset], rd[c].data, rd[c].data_size);
- offset += rd[c].data_size;
+ GNUNET_break (0);
+ GNUNET_free (sig);
+ return NULL;
}
+ return sig;
+}
- GNUNET_assert (offset == total_len);
- return total_len;
+/**
+ * Checks if a name is wellformed
+ *
+ * @param name the name to check
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_NAMESTORE_check_name (const char * name)
+{
+ if (name == NULL)
+ return GNUNET_SYSERR;
+ if (strlen (name) > 63)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
}
/**
- * Deserialize an array of GNUNET_NAMESTORE_RecordData *rd after transmission
- * over the network
+ * Convert the 'value' of a record to a string.
*
- * @param source where to read the data to deserialize
- * @param rd_count number of elements in array
- * @param rd array
+ * @param type type of the record
+ * @param data value in binary encoding
+ * @param data_size number of bytes in data
+ * @return NULL on error, otherwise human-readable representation of the value
+ */
+char *
+GNUNET_NAMESTORE_value_to_string (uint32_t type,
+ const void *data,
+ size_t data_size)
+{
+ char tmp[INET6_ADDRSTRLEN];
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
+ uint16_t mx_pref;
+ char* result;
+ char* soa_rname;
+ char* soa_mname;
+ uint32_t* soa_data;
+ uint32_t soa_serial;
+ uint32_t soa_refresh;
+ uint32_t soa_retry;
+ uint32_t soa_expire;
+ uint32_t soa_min;
+
+ switch (type)
+ {
+ case 0:
+ return NULL;
+ case GNUNET_DNSPARSER_TYPE_A:
+ if (data_size != sizeof (struct in_addr))
+ return NULL;
+ if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp)))
+ return NULL;
+ return GNUNET_strdup (tmp);
+ case GNUNET_DNSPARSER_TYPE_NS:
+ return GNUNET_strndup (data, data_size);
+ case GNUNET_DNSPARSER_TYPE_CNAME:
+ return GNUNET_strndup (data, data_size);
+ case GNUNET_DNSPARSER_TYPE_SOA:
+ soa_rname = (char*)data;
+ soa_mname = (char*)data+strlen(soa_rname)+1;
+ soa_data = (uint32_t*)(soa_mname+strlen(soa_mname)+1);
+ soa_serial = ntohl(soa_data[0]);
+ soa_refresh = ntohl(soa_data[1]);
+ soa_retry = ntohl(soa_data[2]);
+ soa_expire = ntohl(soa_data[3]);
+ soa_min = ntohl(soa_data[4]);
+ if (GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
+ soa_rname, soa_mname,
+ soa_serial, soa_refresh, soa_retry, soa_expire, soa_min))
+ return result;
+ else
+ return NULL;
+ case GNUNET_DNSPARSER_TYPE_PTR:
+ return GNUNET_strndup (data, data_size);
+ case GNUNET_DNSPARSER_TYPE_MX:
+ mx_pref = ntohs(*((uint16_t*)data));
+ if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t))
+ != 0)
+ return result;
+ else
+ return NULL;
+ case GNUNET_DNSPARSER_TYPE_TXT:
+ return GNUNET_strndup (data, data_size);
+ case GNUNET_DNSPARSER_TYPE_AAAA:
+ if (data_size != sizeof (struct in6_addr))
+ return NULL;
+ if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp)))
+ return NULL;
+ return GNUNET_strdup (tmp);
+ case GNUNET_NAMESTORE_TYPE_PKEY:
+ if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode))
+ return NULL;
+ GNUNET_CRYPTO_short_hash_to_enc (data,
+ &enc);
+ return GNUNET_strdup ((const char*) enc.short_encoding);
+ case GNUNET_NAMESTORE_TYPE_PSEU:
+ return GNUNET_strndup (data, data_size);
+ case GNUNET_NAMESTORE_TYPE_LEHO:
+ return GNUNET_strndup (data, data_size);
+ default:
+ GNUNET_break (0);
+ }
+ GNUNET_break (0); // not implemented
+ return NULL;
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of a record to the binary
+ * representation.
*
- * @return number of elements deserialized
+ * @param type type of the record
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in data
+ * @return GNUNET_OK on success
*/
int
-GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len)
+GNUNET_NAMESTORE_string_to_value (uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
{
- struct GNUNET_NAMESTORE_NetworkRecord * nr;
- struct GNUNET_NAMESTORE_RecordData *d = (*dest);
- int elements;
- size_t offset;
- uint32_t data_size;
- int c;
-
- offset = 0;
- elements = 0;
- while (offset < len)
+ struct in_addr value_a;
+ struct in6_addr value_aaaa;
+ struct GNUNET_CRYPTO_ShortHashCode pkey;
+ uint16_t mx_pref;
+ uint16_t mx_pref_n;
+ uint32_t soa_data[5];
+ char result[253];
+ char soa_rname[63];
+ char soa_mname[63];
+ uint32_t soa_serial;
+ uint32_t soa_refresh;
+ uint32_t soa_retry;
+ uint32_t soa_expire;
+ uint32_t soa_min;
+
+ switch (type)
{
- nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset];
- offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord);
+ case 0:
+ return GNUNET_SYSERR;
+ case GNUNET_DNSPARSER_TYPE_A:
+ if (1 != inet_pton (AF_INET, s, &value_a))
+ return GNUNET_SYSERR;
+ *data = GNUNET_malloc (sizeof (struct in_addr));
+ memcpy (*data, &value_a, sizeof (value_a));
+ *data_size = sizeof (value_a);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_NS:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_CNAME:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_SOA:
+
+ if (SSCANF(s, "rname=%s mname=%s %u,%u,%u,%u,%u",
+ soa_rname, soa_mname,
+ &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)
+ != 7)
+ return GNUNET_SYSERR;
+
+ *data_size = sizeof (soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
+ *data = GNUNET_malloc (*data_size);
+ soa_data[0] = htonl(soa_serial);
+ soa_data[1] = htonl(soa_refresh);
+ soa_data[2] = htonl(soa_retry);
+ soa_data[3] = htonl(soa_expire);
+ soa_data[4] = htonl(soa_min);
+ strcpy(*data, soa_rname);
+ strcpy(*data+strlen(*data)+1, soa_mname);
+ memcpy(*data+strlen(*data)+1+strlen(soa_mname)+1,
+ soa_data, sizeof(soa_data));
+ return GNUNET_OK;
- data_size = ntohl (nr->data_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datasize record[%i]: %u\n", elements, data_size);
- offset += data_size;
- elements ++;
+ case GNUNET_DNSPARSER_TYPE_PTR:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_MX:
+ if (SSCANF(s, "%hu,%s", &mx_pref, result) != 2)
+ return GNUNET_SYSERR;
+ *data_size = sizeof (uint16_t)+strlen(result)+1;
+ *data = GNUNET_malloc (*data_size);
+ mx_pref_n = htons(mx_pref);
+ memcpy(*data, &mx_pref_n, sizeof (uint16_t));
+ strcpy((*data)+sizeof (uint16_t), result);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_TXT:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_AAAA:
+ if (1 != inet_pton (AF_INET6, s, &value_aaaa))
+ return GNUNET_SYSERR;
+ *data = GNUNET_malloc (sizeof (struct in6_addr));
+ *data_size = sizeof (struct in6_addr);
+ memcpy (*data, &value_aaaa, sizeof (value_aaaa));
+ return GNUNET_OK;
+ case GNUNET_NAMESTORE_TYPE_PKEY:
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_short_hash_from_string (s, &pkey))
+ return GNUNET_SYSERR;
+ *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ memcpy (*data, &pkey, sizeof (pkey));
+ *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
+ return GNUNET_OK;
+ case GNUNET_NAMESTORE_TYPE_PSEU:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ case GNUNET_NAMESTORE_TYPE_LEHO:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ default:
+ GNUNET_break (0);
}
+ return GNUNET_SYSERR;
+}
- GNUNET_assert (len == offset);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserializing %i records with total length of %u\n", elements, len);
- (*dest) = GNUNET_malloc (elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
- d = (*dest);
+static struct {
+ const char *name;
+ uint32_t number;
+} name_map[] = {
+ { "A", GNUNET_DNSPARSER_TYPE_A },
+ { "NS", GNUNET_DNSPARSER_TYPE_NS },
+ { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME },
+ { "SOA", GNUNET_DNSPARSER_TYPE_SOA },
+ { "PTR", GNUNET_DNSPARSER_TYPE_PTR },
+ { "MX", GNUNET_DNSPARSER_TYPE_MX },
+ { "TXT", GNUNET_DNSPARSER_TYPE_TXT },
+ { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA },
+ { "PKEY", GNUNET_NAMESTORE_TYPE_PKEY },
+ { "PSEU", GNUNET_NAMESTORE_TYPE_PSEU },
+ { "LEHO", GNUNET_NAMESTORE_TYPE_LEHO },
+ { NULL, UINT32_MAX }
+};
- offset = 0;
- for (c = 0; c < elements; c++)
- {
- nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset];
- d[c].expiration = GNUNET_TIME_absolute_ntoh(nr->expiration);
- d[c].record_type = ntohl (nr->record_type);
- d[c].flags = ntohl (nr->flags);
- d[c].data_size = ntohl (nr->data_size);
- d[c].data = GNUNET_malloc (d[c].data_size);
- GNUNET_assert (d[c].data != NULL);
-
- offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord);
- memcpy((char *) d[c].data, &src[offset], d[c].data_size);
-
- offset += d[c].data_size;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized record[%i] /w data_size %i\n", c, d[c].data_size);
- }
- GNUNET_assert(offset == len);
- return elements;
+/**
+ * Convert a type name (i.e. "AAAA") to the corresponding number.
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_NAMESTORE_typename_to_number (const char *typename)
+{
+ unsigned int i;
+
+ i=0;
+ while ( (name_map[i].name != NULL) &&
+ (0 != strcasecmp (typename, name_map[i].name)) )
+ i++;
+ return name_map[i].number;
+}
+
+
+/**
+ * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
+ *
+ * @param type number of a type to convert
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_NAMESTORE_number_to_typename (uint32_t type)
+{
+ unsigned int i;
+
+ i=0;
+ while ( (name_map[i].name != NULL) &&
+ (type != name_map[i].number) )
+ i++;
+ return name_map[i].name;
}
-/* end of namestore_api.c */
+
+
+/* end of namestore_common.c */
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index c297216..f685887 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -26,6 +26,8 @@
#include "platform.h"
#include "gnunet_namestore_plugin.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
#include <sqlite3.h>
/**
@@ -100,39 +102,15 @@ struct Plugin
sqlite3_stmt *iterate_records;
/**
- * Precompiled SQL for delete zone
+ * Precompiled SQL to get the name for a given zone-value.
*/
- sqlite3_stmt *delete_zone;
-
-};
-
-
-/**
- * Internal format of a record in the BLOB in the database.
- */
-struct DbRecord
-{
+ sqlite3_stmt *zone_to_name;
/**
- * Expiration time for the DNS record.
- */
- struct GNUNET_TIME_AbsoluteNBO expiration;
-
- /**
- * Number of bytes in 'data', network byte order.
- */
- uint32_t data_size;
-
- /**
- * Type of the GNS/DNS record, network byte order.
+ * Precompiled SQL for delete zone
*/
- uint32_t record_type;
+ sqlite3_stmt *delete_zone;
- /**
- * Flags for the record, network byte order.
- */
- uint32_t flags;
-
};
@@ -169,19 +147,22 @@ create_indices (sqlite3 * dbh)
{
/* create indices */
if ( (SQLITE_OK !=
- sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns090records (zone_hash,record_name_hash,rvalue)",
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)",
+ NULL, NULL, NULL)) ||
+ (SQLITE_OK !=
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON ns091records (zone_hash,zone_delegation)",
NULL, NULL, NULL)) ||
(SQLITE_OK !=
- sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns090records (zone_hash,rvalue)",
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns091records (zone_hash,rvalue)",
NULL, NULL, NULL)) ||
(SQLITE_OK !=
- sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns090records (zone_hash)",
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records (zone_hash)",
NULL, NULL, NULL)) ||
(SQLITE_OK !=
- sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns090records (record_name_hash,rvalue)",
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns091records (record_name_hash,rvalue)",
NULL, NULL, NULL)) ||
(SQLITE_OK !=
- sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns090records (rvalue)",
+ sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records (rvalue)",
NULL, NULL, NULL)) )
LOG (GNUNET_ERROR_TYPE_ERROR,
"Failed to create indices: %s\n", sqlite3_errmsg (dbh));
@@ -280,13 +261,14 @@ database_setup (struct Plugin *plugin)
/* Create tables */
CHECK (SQLITE_OK ==
sq_prepare (plugin->dbh,
- "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns090records'",
+ "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns091records'",
&stmt));
if ((sqlite3_step (stmt) == SQLITE_DONE) &&
(sqlite3_exec
(plugin->dbh,
- "CREATE TABLE ns090records ("
+ "CREATE TABLE ns091records ("
" zone_key BLOB NOT NULL DEFAULT '',"
+ " zone_delegation BLOB NOT NULL DEFAULT '',"
" zone_hash BLOB NOT NULL DEFAULT '',"
" record_count INT NOT NULL DEFAULT 0,"
" record_data BLOB NOT NULL DEFAULT '',"
@@ -309,36 +291,41 @@ database_setup (struct Plugin *plugin)
#define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature"
if ((sq_prepare
(plugin->dbh,
- "INSERT INTO ns090records (" ALL ", zone_hash, record_name_hash, rvalue) VALUES "
- "(?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ "INSERT INTO ns091records (" ALL ", zone_delegation, zone_hash, record_name_hash, rvalue) VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
&plugin->put_records) != SQLITE_OK) ||
(sq_prepare
(plugin->dbh,
- "DELETE FROM ns090records WHERE zone_hash=? AND record_name_hash=?",
+ "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?",
&plugin->remove_records) != SQLITE_OK) ||
(sq_prepare
(plugin->dbh,
"SELECT " ALL
- " FROM ns090records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
+ " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
&plugin->iterate_records) != SQLITE_OK) ||
(sq_prepare
(plugin->dbh,
"SELECT " ALL
- " FROM ns090records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
+ " FROM ns091records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
&plugin->iterate_by_zone) != SQLITE_OK) ||
(sq_prepare
(plugin->dbh,
"SELECT " ALL
- " FROM ns090records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
+ " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?",
&plugin->iterate_by_name) != SQLITE_OK) ||
(sq_prepare
(plugin->dbh,
"SELECT " ALL
- " FROM ns090records ORDER BY rvalue LIMIT 1 OFFSET ?",
+ " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?",
&plugin->iterate_all) != SQLITE_OK) ||
(sq_prepare
+ (plugin->dbh,
+ "SELECT " ALL
+ " FROM ns091records WHERE zone_hash=? AND zone_delegation=?",
+ &plugin->zone_to_name) != SQLITE_OK) ||
+ (sq_prepare
(plugin->dbh,
- "DELETE FROM ns090records WHERE zone_hash=?",
+ "DELETE FROM ns091records WHERE zone_hash=?",
&plugin->delete_zone) != SQLITE_OK) )
{
LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
@@ -366,12 +353,14 @@ database_shutdown (struct Plugin *plugin)
sqlite3_finalize (plugin->remove_records);
if (NULL != plugin->iterate_records)
sqlite3_finalize (plugin->iterate_records);
- if (NULL != plugin->iterate_records)
+ if (NULL != plugin->iterate_by_zone)
sqlite3_finalize (plugin->iterate_by_zone);
- if (NULL != plugin->iterate_records)
+ if (NULL != plugin->iterate_by_name)
sqlite3_finalize (plugin->iterate_by_name);
- if (NULL != plugin->iterate_records)
+ if (NULL != plugin->iterate_all)
sqlite3_finalize (plugin->iterate_all);
+ if (NULL != plugin->zone_to_name)
+ sqlite3_finalize (plugin->zone_to_name);
if (NULL != plugin->delete_zone)
sqlite3_finalize (plugin->delete_zone);
result = sqlite3_close (plugin->dbh);
@@ -409,19 +398,18 @@ database_shutdown (struct Plugin *plugin)
*/
static int
namestore_sqlite_remove_records (void *cls,
- const GNUNET_HashCode *zone,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
const char *name)
{
struct Plugin *plugin = cls;
- GNUNET_HashCode nh;
+ struct GNUNET_CRYPTO_ShortHashCode nh;
size_t name_len;
int n;
-
name_len = strlen (name);
- GNUNET_CRYPTO_hash (name, name_len, &nh);
+ GNUNET_CRYPTO_short_hash (name, name_len, &nh);
- if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) ||
- (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)))
+ if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
+ (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)))
{
LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sqlite3_bind_XXXX");
@@ -478,22 +466,30 @@ namestore_sqlite_put_records (void *cls,
{
struct Plugin *plugin = cls;
int n;
- GNUNET_HashCode zone;
- GNUNET_HashCode nh;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
+ struct GNUNET_CRYPTO_ShortHashCode zone_delegation;
+ struct GNUNET_CRYPTO_ShortHashCode nh;
size_t name_len;
uint64_t rvalue;
size_t data_size;
- size_t off;
unsigned int i;
- GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone);
+ GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone);
(void) namestore_sqlite_remove_records (plugin, &zone, name);
name_len = strlen (name);
- GNUNET_CRYPTO_hash (name, name_len, &nh);
+ GNUNET_CRYPTO_short_hash (name, name_len, &nh);
+ memset (&zone_delegation, 0, sizeof (zone_delegation));
+ for (i=0;i<rd_count;i++)
+ if (rd[i].record_type == GNUNET_NAMESTORE_TYPE_PKEY)
+ {
+ GNUNET_assert (sizeof (struct GNUNET_CRYPTO_ShortHashCode) == rd[i].data_size);
+ memcpy (&zone_delegation,
+ rd[i].data,
+ sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ break;
+ }
rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
- data_size = rd_count * sizeof (struct DbRecord);
- for (i=0;i<rd_count;i++)
- data_size += rd[i].data_size;
+ data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
if (data_size > 64 * 65536)
{
GNUNET_break (0);
@@ -501,20 +497,12 @@ namestore_sqlite_put_records (void *cls,
}
{
char data[data_size];
- struct DbRecord *rec;
-
- rec = (struct DbRecord *) data;
- off = rd_count * sizeof (struct DbRecord);
- for (i=0;i<rd_count;i++)
+
+ if (data_size != GNUNET_NAMESTORE_records_serialize (rd_count, rd,
+ data_size, data))
{
- rec[i].expiration = GNUNET_TIME_absolute_hton (rd[i].expiration);
- rec[i].data_size = htonl ((uint32_t) rd[i].data_size);
- rec[i].record_type = htonl (rd[i].record_type);
- rec[i].flags = htonl (rd[i].flags);
- memcpy (&data[off],
- rd[i].data,
- rd[i].data_size);
- off += rd[i].data_size;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 1, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), SQLITE_STATIC)) ||
(SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, SQLITE_STATIC)) ||
@@ -522,9 +510,10 @@ namestore_sqlite_put_records (void *cls,
(SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) ||
(SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value)) ||
(SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) ||
- (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) ||
- (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) ||
- (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 9, rvalue)) )
+ (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone_delegation, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
+ (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
+ (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
+ (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) )
{
LOG_SQLITE (plugin,
GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -556,6 +545,83 @@ namestore_sqlite_put_records (void *cls,
return GNUNET_SYSERR;
}
}
+
+
+/**
+ * The given 'sqlite' statement has been prepared to be run.
+ * It will return a record which should be given to the iterator.
+ * Runs the statement and parses the returned record.
+ *
+ * @param plugin plugin context
+ * @param stmt to run (and then clean up)
+ * @param iter iterator to call with the result
+ * @param iter_cls closure for 'iter'
+ * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
+ */
+static int
+get_record_and_call_iterator (struct Plugin *plugin,
+ sqlite3_stmt *stmt,
+ GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
+{
+ int ret;
+ int sret;
+ unsigned int record_count;
+ size_t data_size;
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
+ const struct GNUNET_CRYPTO_RsaSignature *sig;
+ struct GNUNET_TIME_Absolute expiration;
+ const char *data;
+ const char *name;
+
+ ret = GNUNET_NO;
+ if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
+ {
+ ret = GNUNET_YES;
+ zone_key = sqlite3_column_blob (stmt, 0);
+ name = (const char*) sqlite3_column_text (stmt, 1);
+ record_count = sqlite3_column_int (stmt, 2);
+ data_size = sqlite3_column_bytes (stmt, 3);
+ data = sqlite3_column_blob (stmt, 3);
+ expiration.abs_value = (uint64_t) sqlite3_column_int64 (stmt, 4);
+ sig = sqlite3_column_blob (stmt, 5);
+
+ if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (stmt, 0)) ||
+ (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (stmt, 5)) )
+ {
+ GNUNET_break (0);
+ ret = GNUNET_SYSERR;
+ }
+ else
+ {
+ struct GNUNET_NAMESTORE_RecordData rd[record_count];
+
+ if (GNUNET_OK !=
+ GNUNET_NAMESTORE_records_deserialize (data_size, data,
+ record_count, rd))
+ {
+ GNUNET_break (0);
+ ret = GNUNET_SYSERR;
+ record_count = 0;
+ }
+ else
+ {
+ iter (iter_cls, zone_key, expiration, name,
+ record_count, rd, sig);
+ }
+ }
+ }
+ else
+ {
+ if (SQLITE_DONE != sret)
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
+ iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
+ }
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ LOG_SQLITE (plugin,
+ GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "sqlite3_reset");
+ return ret;
+}
/**
@@ -564,7 +630,7 @@ namestore_sqlite_put_records (void *cls,
*
* @param cls closure (internal context for the plugin)
* @param zone hash of public key of the zone, NULL to iterate over all zones
- * @param name_hash hash of name, NULL to iterate over all records of the zone
+ * @param name name as string, NULL to iterate over all records of the zone
* @param offset offset in the list of all matching records
* @param iter function to call with the result
* @param iter_cls closure for iter
@@ -572,32 +638,37 @@ namestore_sqlite_put_records (void *cls,
*/
static int
namestore_sqlite_iterate_records (void *cls,
- const GNUNET_HashCode *zone,
- const GNUNET_HashCode *name_hash,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
+ const char *name,
uint64_t offset,
GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
{
struct Plugin *plugin = cls;
sqlite3_stmt *stmt;
+ struct GNUNET_CRYPTO_ShortHashCode name_hase;
unsigned int boff;
- int ret;
- int sret;
if (NULL == zone)
- if (NULL == name_hash)
+ if (NULL == name)
stmt = plugin->iterate_all;
else
+ {
+ GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
stmt = plugin->iterate_by_name;
+ }
else
- if (NULL == name_hash)
+ if (NULL == name)
stmt = plugin->iterate_by_zone;
else
+ {
+ GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
stmt = plugin->iterate_records;
+ }
boff = 0;
if ( (NULL != zone) &&
(SQLITE_OK != sqlite3_bind_blob (stmt, ++boff,
- zone, sizeof (GNUNET_HashCode),
+ zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
SQLITE_STATIC)) )
{
LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -608,11 +679,12 @@ namestore_sqlite_iterate_records (void *cls,
"sqlite3_reset");
return GNUNET_SYSERR;
}
- if ( (NULL != name_hash) &&
+ if ( (NULL != name) &&
(SQLITE_OK != sqlite3_bind_blob (stmt, ++boff,
- name_hash, sizeof (GNUNET_HashCode),
+ &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
SQLITE_STATIC)) )
{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ITERATE NAME HASH: `%8s'", GNUNET_short_h2s(&name_hase));
LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sqlite3_bind_XXXX");
if (SQLITE_OK != sqlite3_reset (stmt))
@@ -633,72 +705,49 @@ namestore_sqlite_iterate_records (void *cls,
"sqlite3_reset");
return GNUNET_SYSERR;
}
- ret = GNUNET_NO;
- if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
- {
- unsigned int record_count;
- size_t data_size;
- const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
- const struct GNUNET_CRYPTO_RsaSignature *sig;
- struct GNUNET_TIME_Absolute expiration;
- const char *data;
- const char *name;
-
- ret = GNUNET_YES;
- zone_key = sqlite3_column_blob (stmt, 0);
- name = (const char*) sqlite3_column_text (stmt, 1);
- record_count = sqlite3_column_int (stmt, 2);
- data_size = sqlite3_column_bytes (stmt, 3);
- data = sqlite3_column_blob (stmt, 3);
- expiration.abs_value = (uint64_t) sqlite3_column_int64 (stmt, 4);
- sig = sqlite3_column_blob (stmt, 5);
- if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (stmt, 0)) ||
- (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (stmt, 5)) ||
- (sizeof (struct DbRecord) * record_count > data_size) )
- {
- GNUNET_break (0);
- ret = GNUNET_SYSERR;
- }
- else
- {
- const struct DbRecord *db = (const struct DbRecord*) data;
- struct GNUNET_NAMESTORE_RecordData rd[record_count];
- unsigned int i;
- size_t off;
+ return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
+}
- off = record_count * sizeof (struct DbRecord);
- for (i=0;i<record_count;i++)
- {
- if (off + ntohl (db[i].data_size) > data_size)
- {
- GNUNET_break (0);
- ret = GNUNET_SYSERR;
- record_count = i;
- break;
- }
- rd[i].expiration = GNUNET_TIME_absolute_ntoh (db[i].expiration);
- rd[i].data_size = ntohl (db[i].data_size);
- rd[i].data = &data[off];
- rd[i].record_type = ntohl (db[i].record_type);
- rd[i].flags = ntohl (db[i].flags);
- off += rd[i].data_size;
- }
- iter (iter_cls, zone_key, expiration, name,
- record_count, rd, sig);
- }
- }
- else
+
+/**
+ * Look for an existing PKEY delegation record for a given public key.
+ * Returns at most one result to the iterator.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param zone hash of public key of the zone to look up in, never NULL
+ * @param value_zone hash of the public key of the target zone (value), never NULL
+ * @param iter function to call with the result
+ * @param iter_cls closure for iter
+ * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
+ */
+static int
+namestore_sqlite_zone_to_name (void *cls,
+ const struct GNUNET_CRYPTO_ShortHashCode *zone,
+ const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
+ GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt;
+
+ stmt = plugin->zone_to_name;
+ if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1,
+ zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
+ SQLITE_STATIC)) ||
+ (SQLITE_OK != sqlite3_bind_blob (stmt, 2,
+ value_zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
+ SQLITE_STATIC)) )
{
- if (SQLITE_DONE != sret)
- LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
- iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
- }
- if (SQLITE_OK != sqlite3_reset (stmt))
- LOG_SQLITE (plugin,
- GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
- "sqlite3_reset");
- return ret;
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "sqlite3_bind_XXXX");
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ LOG_SQLITE (plugin,
+ GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "sqlite3_reset");
+ return GNUNET_SYSERR;
+ }
+
+ return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
}
@@ -710,13 +759,13 @@ namestore_sqlite_iterate_records (void *cls,
*/
static void
namestore_sqlite_delete_zone (void *cls,
- const GNUNET_HashCode *zone)
+ const struct GNUNET_CRYPTO_ShortHashCode *zone)
{
struct Plugin *plugin = cls;
sqlite3_stmt *stmt = plugin->delete_zone;
int n;
- if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC))
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC))
{
LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sqlite3_bind_XXXX");
@@ -774,6 +823,7 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
api->put_records = &namestore_sqlite_put_records;
api->remove_records = &namestore_sqlite_remove_records;
api->iterate_records = &namestore_sqlite_iterate_records;
+ api->zone_to_name = &namestore_sqlite_zone_to_name;
api->delete_zone = &namestore_sqlite_delete_zone;
LOG (GNUNET_ERROR_TYPE_INFO,
_("Sqlite database running\n"));
diff --git a/src/namestore/test_hostkey b/src/namestore/test_hostkey
new file mode 100644
index 0000000..2ffb55f
--- /dev/null
+++ b/src/namestore/test_hostkey
Binary files differ
diff --git a/src/namestore/test_namestore_api.c b/src/namestore/test_namestore_api.c
index ebd8be3..039f1b9 100644
--- a/src/namestore/test_namestore_api.c
+++ b/src/namestore/test_namestore_api.c
@@ -36,7 +36,7 @@ static struct GNUNET_OS_Process *arm;
static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
-static GNUNET_HashCode zone;
+static struct GNUNET_CRYPTO_ShortHashCode zone;
static int res;
@@ -66,7 +66,7 @@ stop_arm ()
if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
GNUNET_OS_process_wait (arm);
- GNUNET_OS_process_close (arm);
+ GNUNET_OS_process_destroy (arm);
arm = NULL;
}
}
@@ -142,20 +142,45 @@ void put_cont (void *cls, int32_t success, const char *emsg)
GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL);
}
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
static void
run (void *cls, char *const *args, const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ delete_existing_db(cfg);
endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
- privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey");
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
GNUNET_assert (privkey != NULL);
GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone);
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (pubkey), &zone);
struct GNUNET_CRYPTO_RsaSignature signature;
+ memset (&signature, '\0', sizeof (signature));
struct GNUNET_NAMESTORE_RecordData rd;
rd.expiration = GNUNET_TIME_absolute_get();
@@ -172,7 +197,7 @@ run (void *cls, char *const *args, const char *cfgfile,
GNUNET_break (NULL != nsh);
GNUNET_NAMESTORE_record_put (nsh, &pubkey, name,
- GNUNET_TIME_absolute_get_forever(),
+ GNUNET_TIME_UNIT_FOREVER_ABS,
1, &rd, &signature, put_cont, name);
GNUNET_free ((void *)rd.data);
diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf
index 1b83e8f..33e07a4 100644
--- a/src/namestore/test_namestore_api.conf
+++ b/src/namestore/test_namestore_api.conf
@@ -4,12 +4,12 @@ DEFAULTSERVICES = namestore
UNIXPATH = /tmp/gnunet-p1-service-arm.sock
[namestore]
-#PREFIX = valgrind --leak-check=full
+#PREFIX = valgrind --leak-check=full --track-origins=yes
AUTOSTART = YES
UNIXPATH = /tmp/gnunet-service-namestore.sock
UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
-# PORT = 2099
+PORT = 2099
HOSTNAME = localhost
HOME = $SERVICEHOME
CONFIG = $DEFAULTCONFIG
@@ -17,9 +17,10 @@ BINARY = gnunet-service-namestore
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
DATABASE = sqlite
+ZONEFILE_DIRECTORY = zonefiles
[namestore-sqlite]
-FILENAME = $SERVICEHOME/namestore/sqlite.db
+FILENAME = $SERVICEHOME/namestore/sqlite_test.db
[namestore-postgres]
CONFIG = connect_timeout=10; dbname=gnunet
diff --git a/src/namestore/test_namestore_api_create.c b/src/namestore/test_namestore_api_create.c
new file mode 100644
index 0000000..131c934
--- /dev/null
+++ b/src/namestore/test_namestore_api_create.c
@@ -0,0 +1,478 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 1
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_CREATE_RECORD_TYPE 4321
+#define TEST_CREATE_RECORD_DATALEN 255
+#define TEST_CREATE_RECORD_DATA 'b'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+struct GNUNET_CRYPTO_RsaSignature *s_signature_updated;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_first_record;
+struct GNUNET_NAMESTORE_RecordData *s_second_record;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_free ((void *) s_first_record->data);
+ GNUNET_free (s_first_record);
+ GNUNET_free_non_null (s_second_record);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void name_lookup_second_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ static int found = GNUNET_NO;
+ int failed = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (2 != rd_count)
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ for (c = 0; c < rd_count; c++)
+ {
+ if ((GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_first_record)) &&
+ (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_second_record)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ struct GNUNET_NAMESTORE_RecordData rd_new[2];
+ rd_new[0] = *s_first_record;
+ rd_new[1] = *s_second_record;
+ s_signature_updated = GNUNET_NAMESTORE_create_signature(privkey, expire, s_name, rd_new, 2);
+
+ if (0 != memcmp (s_signature_updated, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ found = GNUNET_YES;
+ if (failed == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+
+void
+create_second_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create second record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_second_proc, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void name_lookup_initial_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ char * name = cls;
+ static int found = GNUNET_NO;
+ int failed = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (RECORDS != rd_count)
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], &s_first_record[c]))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire,n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != memcmp (s_signature, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ found = GNUNET_YES;
+ if (failed == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+
+ /* create a second record */
+ s_second_record = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN);
+ s_second_record->expiration = GNUNET_TIME_UNIT_FOREVER_ABS;
+ s_second_record->record_type = TEST_CREATE_RECORD_TYPE;
+ s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY;
+ s_second_record->data = &s_second_record[1];
+ s_second_record->data_size = TEST_CREATE_RECORD_DATALEN;
+ memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN);
+
+ GNUNET_NAMESTORE_record_create (nsh, privkey, name, s_second_record, &create_second_cont, name);
+
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+}
+
+void
+create_first_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ /* check if record was created correct */
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_initial_proc, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < count; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+ size_t rd_ser_len;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_first_record = create_record (1);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, s_first_record);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(1, s_first_record, rd_ser_len, rd_ser);
+
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_first_record->expiration, s_name, s_first_record, 1);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone));
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_first_record != NULL);
+ GNUNET_break (s_name != NULL);
+
+ /* create initial record */
+ GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name);
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_create_update.c b/src/namestore/test_namestore_api_create_update.c
new file mode 100644
index 0000000..93570e4
--- /dev/null
+++ b/src/namestore/test_namestore_api_create_update.c
@@ -0,0 +1,517 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c for updating an existing record
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 1
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_CREATE_RECORD_TYPE 4321
+#define TEST_CREATE_RECORD_DATALEN 255
+#define TEST_CREATE_RECORD_DATA 'b'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+struct GNUNET_CRYPTO_RsaSignature *s_signature_updated;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_first_record;
+struct GNUNET_NAMESTORE_RecordData *s_second_record;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_free ((void *) s_first_record->data);
+ GNUNET_free (s_first_record);
+ GNUNET_free_non_null (s_second_record);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void name_lookup_second_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ static int found = GNUNET_NO;
+ int failed = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (2 != rd_count)
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ for (c = 0; c < rd_count; c++)
+ {
+ if ((GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_first_record)) &&
+ (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_second_record)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ struct GNUNET_NAMESTORE_RecordData rd_new[2];
+ rd_new[0] = *s_first_record;
+ rd_new[1] = *s_second_record;
+ s_signature_updated = GNUNET_NAMESTORE_create_signature(privkey, expire, s_name, rd_new, 2);
+
+ if (0 != memcmp (s_signature_updated, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ found = GNUNET_YES;
+ if (failed == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+
+void
+create_second_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create second record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_second_proc, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void name_lookup_initial_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ char * name = cls;
+ static int found = GNUNET_NO;
+ int failed = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (RECORDS != rd_count)
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], &s_first_record[c]))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != memcmp (s_signature, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ found = GNUNET_YES;
+ if (failed == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+
+ /* create a second record */
+ s_second_record = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN);
+ s_second_record->expiration = GNUNET_TIME_UNIT_FOREVER_ABS;
+ s_second_record->record_type = TEST_CREATE_RECORD_TYPE;
+ s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY;
+ s_second_record->data = &s_second_record[1];
+ s_second_record->data_size = TEST_CREATE_RECORD_DATALEN;
+ memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN);
+
+ GNUNET_NAMESTORE_record_create (nsh, privkey, name, s_second_record, &create_second_cont, name);
+
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+}
+
+
+void
+create_updated_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration for record `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg);
+ if (success == GNUNET_NO)
+ {
+ res = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated record for name `%s'\n", name);
+ }
+ else if (success == GNUNET_OK)
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "FAIL, Create new record for name `%s'\n", name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create records for name `%s'\n", name);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+void
+create_identical_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating identical record for `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg);
+ if (success == GNUNET_NO)
+ {
+ res = 0;
+ s_first_record->expiration = GNUNET_TIME_absolute_get ();
+ GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_updated_cont, s_name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating identical record for `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void
+create_first_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create record for `%s': %s `%s'\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL", emsg);
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ /* check if record was created correct */
+ GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_identical_cont, s_name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s `%s'\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL", emsg);
+ if (success == GNUNET_OK)
+ {
+
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < count; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS;
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+ size_t rd_ser_len;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_first_record = create_record (1);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, s_first_record);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(1, s_first_record, rd_ser_len, rd_ser);
+
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_first_record->expiration, s_name, s_first_record, 1);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone));
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_first_record != NULL);
+ GNUNET_break (s_name != NULL);
+
+ /* create initial record */
+ GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name);
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_lookup.c b/src/namestore/test_namestore_api_lookup.c
new file mode 100644
index 0000000..818e710
--- /dev/null
+++ b/src/namestore/test_namestore_api_lookup.c
@@ -0,0 +1,317 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ int c;
+ for (c = 0; c < RECORDS; c++)
+ GNUNET_free_non_null((void *) s_rd[c].data);
+ GNUNET_free (s_rd);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void name_lookup_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ static int found = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ }
+
+ if (0 != memcmp (signature, s_signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ GNUNET_break (0);
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ }
+
+ if (RECORDS != rd_count)
+ {
+ GNUNET_break (0);
+ }
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_rd[c]))
+ {
+ GNUNET_break (0);
+ }
+ }
+ found = GNUNET_YES;
+ res = 0;
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char * name = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, NULL);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+
+ size_t rd_ser_len;
+
+ /* load privat key from file not included in zonekey dir */
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file("test_hostkey");
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
+
+ /* sign */
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_rd != NULL);
+ GNUNET_break (s_name != NULL);
+
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ RECORDS, s_rd, s_signature, put_cont, s_name);
+}
+
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_lookup_specific_type.c b/src/namestore/test_namestore_api_lookup_specific_type.c
new file mode 100644
index 0000000..981e252
--- /dev/null
+++ b/src/namestore/test_namestore_api_lookup_specific_type.c
@@ -0,0 +1,399 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING 11111
+#define TEST_RECORD_LOOKUP_TYPE_EXISTING 22222
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ int c;
+ for (c = 0; c < RECORDS; c++)
+ {
+ GNUNET_free_non_null((void *) s_rd[c].data);
+ }
+ GNUNET_free (s_rd);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+
+void name_lookup_existing_record_type (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ int failed = GNUNET_NO;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned %u records\n", rd_count);
+
+ if ((NULL == n) || (0 != memcmp(zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if ((NULL == n) || (0 != strcmp(n, s_name)))
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (1 != rd_count)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (NULL == rd)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (NULL != signature)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+
+ if (failed == GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n");
+ res = 1;
+ }
+ else
+ {
+ res = 0;
+ }
+
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+
+void name_lookup_non_existing_record_type (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ int failed = GNUNET_NO;
+ /* We expect zone key != NULL, name != NULL, rd_count 0, rd NULL, signature NULL */
+ if (NULL == zone_key)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (NULL == n)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name %s!\n", n);
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (0 != rd_count)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (NULL != rd)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+ if (NULL != signature)
+ {
+ GNUNET_break(0);
+ failed = GNUNET_YES;
+ }
+
+ if ((rd_count == 1) && (rd != NULL))
+ {
+ if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(rd, &rd[RECORDS-1]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are not equal!\n");
+ failed = GNUNET_YES;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are equal!\n");
+ }
+ }
+
+ if (failed == GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n");
+ res = 1;
+
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned valid response\n");
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, s_name, TEST_RECORD_LOOKUP_TYPE_EXISTING, &name_lookup_existing_record_type, NULL);
+ res = 0;
+ }
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char * name = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up non-existing record type %u for name `%s'\n", TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, name);
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, &name_lookup_non_existing_record_type, NULL);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < RECORDS-1; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS;
+ rd[c].record_type = 1;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_LOOKUP_TYPE_EXISTING;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+
+ size_t rd_ser_len;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
+
+ /* sign */
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[RECORDS -1].expiration, s_name, s_rd, RECORDS);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_rd != NULL);
+ GNUNET_break (s_name != NULL);
+
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ RECORDS, s_rd, s_signature, put_cont, s_name);
+
+
+
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_put.c b/src/namestore/test_namestore_api_put.c
new file mode 100644
index 0000000..9315fd3
--- /dev/null
+++ b/src/namestore/test_namestore_api_put.c
@@ -0,0 +1,249 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char * name = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ res = 0;
+ else
+ res = 1;
+
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ struct GNUNET_CRYPTO_RsaSignature *signature;
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ /* create record */
+ char * s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS);
+
+ GNUNET_break (s_rd != NULL);
+ GNUNET_break (s_name != NULL);
+
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ RECORDS, s_rd, signature, put_cont, s_name);
+
+ GNUNET_free (signature);
+
+ int c;
+ for (c = 0; c < RECORDS; c++)
+ GNUNET_free_non_null((void *) s_rd[c].data);
+ GNUNET_free (s_rd);
+
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c
new file mode 100644
index 0000000..57bb4a8
--- /dev/null
+++ b/src/namestore/test_namestore_api_remove.c
@@ -0,0 +1,366 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_REMOVE_RECORD_TYPE 4321
+#define TEST_REMOVE_RECORD_DATALEN 255
+#define TEST_REMOVE_RECORD_DATA 'b'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ int c;
+ for (c = 0; c < RECORDS; c++)
+ GNUNET_free_non_null((void *) s_rd[c].data);
+ GNUNET_free (s_rd);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void name_lookup_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ static int found = GNUNET_NO;
+ int failed = GNUNET_NO;
+ int c;
+
+ if (n != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup for name `%s' returned %u records\n", n, rd_count);
+ if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (0 != strcmp(n, s_name))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (RECORDS-1 != rd_count)
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ for (c = 0; c < rd_count; c++)
+ {
+ if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_rd[c+1]))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature))
+ {
+ GNUNET_break (0);
+ failed = GNUNET_YES;
+ }
+
+ if (failed == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+ }
+ else
+ {
+ if (found != GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name);
+ res = 1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+void
+remove_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg);
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove record for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name);
+
+ GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &s_rd[0], &remove_cont, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ rd[0].expiration = GNUNET_TIME_absolute_get();
+ rd[0].record_type = 0;
+ rd[0].data_size = TEST_REMOVE_RECORD_DATALEN;
+ rd[0].data = GNUNET_malloc(TEST_REMOVE_RECORD_DATALEN);
+ memset ((char *) rd[0].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+
+ for (c = 1; c < RECORDS; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS;
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+ size_t rd_ser_len;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
+
+ /* sign */
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone));
+
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_rd != NULL);
+ GNUNET_break (s_name != NULL);
+
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ RECORDS, s_rd, s_signature, put_cont, s_name);
+
+
+
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c
new file mode 100644
index 0000000..8c32278
--- /dev/null
+++ b/src/namestore/test_namestore_api_remove_not_existing_record.c
@@ -0,0 +1,299 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api.c
+ * @brief testcase for namestore_api.c
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_REMOVE_RECORD_TYPE 4321
+#define TEST_REMOVE_RECORD_DATALEN 255
+#define TEST_REMOVE_RECORD_DATA 'b'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+static GNUNET_HashCode s_zone;
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+static char *s_name;
+
+
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ int c;
+ for (c = 0; c < RECORDS; c++)
+ GNUNET_free_non_null((void *) s_rd[c].data);
+ GNUNET_free (s_rd);
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void
+remove_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s `%s'\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg);
+ if (GNUNET_NO == success)
+ {
+ res = 0;
+ }
+ else
+ {
+ res = 1;
+ GNUNET_break (0);
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing non existing record for `%s'\n", name);
+
+ struct GNUNET_NAMESTORE_RecordData rd;
+ char data[TEST_REMOVE_RECORD_DATALEN];
+ rd.expiration = GNUNET_TIME_absolute_get();
+ rd.record_type = TEST_REMOVE_RECORD_TYPE;
+ rd.data_size = TEST_REMOVE_RECORD_DATALEN;
+ rd.data = &data;
+
+ GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &rd, &remove_cont, name);
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+ size_t rd_ser_len;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
+ char rd_ser[rd_ser_len];
+ GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
+
+ /* sign */
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS);
+
+ /* create random zone hash */
+ GNUNET_CRYPTO_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_h2s_full(&s_zone));
+
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_break (s_rd != NULL);
+ GNUNET_break (s_name != NULL);
+
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ RECORDS, s_rd, s_signature, put_cont, s_name);
+
+
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ GNUNET_free (s_signature);
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_api_sign_verify.c b/src/namestore/test_namestore_api_sign_verify.c
new file mode 100644
index 0000000..17bfb1e
--- /dev/null
+++ b/src/namestore/test_namestore_api_sign_verify.c
@@ -0,0 +1,150 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api_sign_verify.c
+ * @brief testcase for signing and verifying
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TEST_REMOVE_RECORD_TYPE 4321
+#define TEST_REMOVE_RECORD_DATALEN 255
+#define TEST_REMOVE_RECORD_DATA 'b'
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+struct GNUNET_CRYPTO_RsaSignature s_signature;
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+static char *s_name;
+
+static int res;
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < RECORDS; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = TEST_RECORD_TYPE;
+ rd[c].data_size = TEST_RECORD_DATALEN;
+ rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
+ memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
+ }
+
+ return rd;
+}
+
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_CRYPTO_RsaSignature * signature;
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get();
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ int res_c;
+ int res_w;
+
+ /* create record */
+ s_name = "dummy.dummy.gnunet";
+ s_rd = create_record (RECORDS);
+
+ signature = GNUNET_NAMESTORE_create_signature (privkey, expire, s_name, s_rd, RECORDS);
+ GNUNET_assert (signature != NULL);
+
+ res_c = GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name, RECORDS, s_rd, signature);
+ GNUNET_break (res == GNUNET_OK);
+
+ GNUNET_free (signature);
+
+ signature = GNUNET_NAMESTORE_create_signature (privkey, expire, s_name, s_rd, RECORDS);
+ GNUNET_break (signature != NULL);
+
+ GNUNET_log_skip(1, GNUNET_NO);
+ res_w = GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name, RECORDS - 1, s_rd, signature);
+ GNUNET_break (res_w == GNUNET_SYSERR);
+
+ GNUNET_free (signature);
+
+ if ((res_c == GNUNET_OK) && (res_w == GNUNET_SYSERR))
+ res = 0;
+ else
+ res = 1;
+
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+
+ return ret;
+}
+
+/* end of test_namestore_api_sign_verify.c */
diff --git a/src/namestore/test_namestore_api_zone_iteration.c b/src/namestore/test_namestore_api_zone_iteration.c
index c0ef8c8..0665541 100644
--- a/src/namestore/test_namestore_api_zone_iteration.c
+++ b/src/namestore/test_namestore_api_zone_iteration.c
@@ -19,11 +19,12 @@
*/
/**
* @file namestore/test_namestore_api_zone_iteration.c
- * @brief testcase for namestore_api.c zone iteration functionality
+ * @brief testcase for zone iteration functionality: iterate of a specific zone
*/
#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_namestore_service.h"
+#include "namestore.h"
#define VERBOSE GNUNET_NO
@@ -39,8 +40,25 @@ static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
static GNUNET_HashCode zone;
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2;
+static GNUNET_HashCode zone2;
+
static struct GNUNET_NAMESTORE_ZoneIterator *zi;
static int res;
+static int returned_records;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_1;
+char * s_name_1;
+struct GNUNET_NAMESTORE_RecordData *s_rd_1;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_2;
+char * s_name_2;
+struct GNUNET_NAMESTORE_RecordData *s_rd_2;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_3;
+char * s_name_3;
+struct GNUNET_NAMESTORE_RecordData *s_rd_3;
static void
start_arm (const char *cfgname)
@@ -63,7 +81,7 @@ stop_arm ()
if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
GNUNET_OS_process_wait (arm);
- GNUNET_OS_process_close (arm);
+ GNUNET_OS_process_destroy (arm);
arm = NULL;
}
}
@@ -87,10 +105,37 @@ endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
nsh = NULL;
+ GNUNET_free_non_null(sig_1);
+ GNUNET_free_non_null(sig_2);
+ GNUNET_free_non_null(sig_3);
+ GNUNET_free_non_null(s_name_1);
+ GNUNET_free_non_null(s_name_2);
+ GNUNET_free_non_null(s_name_3);
+
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
if (privkey != NULL)
GNUNET_CRYPTO_rsa_key_free (privkey);
privkey = NULL;
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
if (NULL != arm)
stop_arm();
@@ -113,11 +158,36 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
endbadly_task = GNUNET_SCHEDULER_NO_TASK;
}
-
if (privkey != NULL)
GNUNET_CRYPTO_rsa_key_free (privkey);
privkey = NULL;
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
+ GNUNET_free (sig_1);
+ GNUNET_free (sig_2);
+ GNUNET_free (sig_3);
+ GNUNET_free (s_name_1);
+ GNUNET_free (s_name_2);
+ GNUNET_free (s_name_3);
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
if (nsh != NULL)
GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
nsh = NULL;
@@ -125,19 +195,6 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
if (NULL != arm)
stop_arm();
-
- res = 0;
-}
-
-static void
-stop_iteration (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping iteration for zone `%s'\n", GNUNET_h2s (&zone));
- GNUNET_NAMESTORE_zone_iteration_stop (zi);
-
- GNUNET_SCHEDULER_add_now (&end, NULL);
}
void zone_proc (void *cls,
@@ -148,22 +205,226 @@ void zone_proc (void *cls,
const struct GNUNET_NAMESTORE_RecordData *rd,
const struct GNUNET_CRYPTO_RsaSignature *signature)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_h2s (&zone));
+ int failed = GNUNET_NO;
+ if ((zone_key == NULL) && (name == NULL))
+ {
+ GNUNET_break (3 == returned_records);
+ if (3 == returned_records)
+ res = 0;
+ else
+ res = 1;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records );
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ else
+ {
+ /* verify signature returned from name store */
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature (zone_key, expire, name, rd_count, rd, signature))
+ {
+ GNUNET_HashCode zone_key_hash;
+ GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Verifying signature for `%s' in zone `%s' with %u records and expiration %llu failed\n", name, GNUNET_h2s(&zone_key_hash), rd_count, expire.abs_value);
+
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name);
+ if (0 == strcmp (name, s_name_1))
+ {
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (0 != memcmp (signature, sig_1, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else if (0 == strcmp (name, s_name_2))
+ {
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (0 != memcmp (signature, sig_2, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else if (0 == strcmp (name, s_name_3))
+ {
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+
+ if (0 != memcmp (signature, sig_3, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name);
+ res = 1;
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+
+ if (failed == GNUNET_NO)
+ {
+ returned_records ++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n");
+ GNUNET_NAMESTORE_zone_iterator_next (zi);
+ }
+ else
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ }
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
- stopiteration_task = GNUNET_SCHEDULER_add_now (&stop_iteration, NULL);
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ static int c = 0;
+
+ if (success == GNUNET_OK)
+ {
+ c++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+
+ if (c == 3)
+ {
+ res = 1;
+ returned_records = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over all zones \n");
+ zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
+ NULL,
+ GNUNET_NAMESTORE_RF_NONE,
+ GNUNET_NAMESTORE_RF_NONE,
+ zone_proc,
+ &zone);
+ if (zi == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < count; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = 1111;
+ rd[c].data_size = 50;
+ rd[c].data = GNUNET_malloc(50);
+ memset ((char *) rd[c].data, 'a', 50);
+ }
+ return rd;
}
static void
run (void *cls, char *const *args, const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ delete_existing_db(cfg);
endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL);
- privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey");
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
GNUNET_assert (privkey != NULL);
GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+ GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone);
+
+
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+
+ GNUNET_assert (privkey2 != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2);
+ GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2);
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone);
start_arm (cfgfile);
GNUNET_assert (arm != NULL);
@@ -171,18 +432,27 @@ run (void *cls, char *const *args, const char *cfgfile,
nsh = GNUNET_NAMESTORE_connect (cfg);
GNUNET_break (NULL != nsh);
- zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
- &zone,
- GNUNET_NAMESTORE_RF_NONE,
- GNUNET_NAMESTORE_RF_NONE,
- zone_proc,
- &zone);
- if (zi == NULL)
- {
- GNUNET_break (0);
- GNUNET_SCHEDULER_cancel (endbadly_task);
- endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
- }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
+
+ GNUNET_asprintf(&s_name_1, "dummy1");
+ s_rd_1 = create_record(1);
+ sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1->expiration, s_name_1, s_rd_1, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL);
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
+ GNUNET_asprintf(&s_name_2, "dummy2");
+ s_rd_2 = create_record(1);
+
+ sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2->expiration, s_name_2, s_rd_2, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
+ /* name in different zone */
+ GNUNET_asprintf(&s_name_3, "dummy3");
+ s_rd_3 = create_record(1);
+ sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, s_rd_3->expiration, s_name_3, s_rd_3, 1);
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL);
}
static int
diff --git a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c
new file mode 100644
index 0000000..b21c860
--- /dev/null
+++ b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c
@@ -0,0 +1,451 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api_zone_iteration_specific_zone.c
+ * @brief testcase for zone iteration functionality: iterate of a specific zone
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+
+#define VERBOSE GNUNET_NO
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static GNUNET_SCHEDULER_TaskIdentifier stopiteration_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+static struct GNUNET_CRYPTO_ShortHashCode zone;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2;
+static struct GNUNET_CRYPTO_ShortHashCode zone2;
+
+static struct GNUNET_NAMESTORE_ZoneIterator *zi;
+static int res;
+static int returned_records;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_1;
+char * s_name_1;
+struct GNUNET_NAMESTORE_RecordData *s_rd_1;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_2;
+char * s_name_2;
+struct GNUNET_NAMESTORE_RecordData *s_rd_2;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_3;
+char * s_name_3;
+struct GNUNET_NAMESTORE_RecordData *s_rd_3;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (stopiteration_task);
+ stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ GNUNET_free_non_null(sig_1);
+ GNUNET_free_non_null(sig_2);
+ GNUNET_free_non_null(sig_3);
+ GNUNET_free_non_null(s_name_1);
+ GNUNET_free_non_null(s_name_2);
+ GNUNET_free_non_null(s_name_3);
+
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (stopiteration_task);
+ stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
+ GNUNET_free (sig_1);
+ GNUNET_free (sig_2);
+ GNUNET_free (sig_3);
+ GNUNET_free (s_name_1);
+ GNUNET_free (s_name_2);
+ GNUNET_free (s_name_3);
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void zone_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ int failed = GNUNET_NO;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_short_h2s (&zone));
+ if ((zone_key == NULL) && (name == NULL))
+ {
+ GNUNET_break (2 == returned_records);
+ if (2 == returned_records)
+ res = 0;
+ else
+ res = 1;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after %u records\n", returned_records);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name);
+ if (0 == strcmp (name, s_name_1))
+ {
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (0 != memcmp (signature, sig_1, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else if (0 == strcmp (name, s_name_2))
+ {
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (0 != memcmp (signature, sig_2, sizeof (struct GNUNET_CRYPTO_RsaSignature)))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name);
+ res = 1;
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+
+ if (failed == GNUNET_NO)
+ {
+ returned_records ++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n");
+ GNUNET_NAMESTORE_zone_iterator_next (zi);
+ }
+ else
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ }
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ static int c = 0;
+
+ if (success == GNUNET_OK)
+ {
+ c++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+
+ if (c == 3)
+ {
+ res = 1;
+ returned_records = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over zone `%s'\n",
+ GNUNET_short_h2s(&zone));
+ zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
+ &zone,
+ GNUNET_NAMESTORE_RF_NONE,
+ GNUNET_NAMESTORE_RF_NONE,
+ zone_proc,
+ &zone);
+ if (zi == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < count; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = 1111;
+ rd[c].data_size = 50;
+ rd[c].data = GNUNET_malloc(50);
+ memset ((char *) rd[c].data, 'a', 50);
+ }
+ return rd;
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL);
+
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (pubkey), &zone);
+
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey2 != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2);
+ GNUNET_CRYPTO_short_hash (&pubkey2, sizeof (pubkey), &zone2);
+
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
+
+ GNUNET_asprintf(&s_name_1, "dummy1");
+ s_rd_1 = create_record(1);
+ sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1[0].expiration ,s_name_1, s_rd_1, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL);
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
+ GNUNET_asprintf(&s_name_2, "dummy2");
+ s_rd_2 = create_record(1);
+
+ sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2[0].expiration, s_name_2, s_rd_2, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
+ /* name in different zone */
+ GNUNET_asprintf(&s_name_3, "dummy3");
+ s_rd_3 = create_record(1);
+ sig_3 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_3[0].expiration, s_name_3, s_rd_3, 1);
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL);
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test_namestore_api_zone_iteration",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test_namestore_api_zone_iteration",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+
+ return ret;
+}
+
+/* end of test_namestore_api_zone_iteration_specific_zone.c */
diff --git a/src/namestore/test_namestore_api_zone_iteration_stop.c b/src/namestore/test_namestore_api_zone_iteration_stop.c
new file mode 100644
index 0000000..9f62c73
--- /dev/null
+++ b/src/namestore/test_namestore_api_zone_iteration_stop.c
@@ -0,0 +1,501 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api_zone_iteration.c
+ * @brief testcase for zone iteration functionality: iterate of a specific zone
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+
+#define VERBOSE GNUNET_NO
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static GNUNET_SCHEDULER_TaskIdentifier stopiteration_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+static GNUNET_HashCode zone;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2;
+static GNUNET_HashCode zone2;
+
+static struct GNUNET_NAMESTORE_ZoneIterator *zi;
+static int res;
+static int returned_records;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_1;
+char * s_name_1;
+struct GNUNET_NAMESTORE_RecordData *s_rd_1;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_2;
+char * s_name_2;
+struct GNUNET_NAMESTORE_RecordData *s_rd_2;
+
+struct GNUNET_CRYPTO_RsaSignature *sig_3;
+char * s_name_3;
+struct GNUNET_NAMESTORE_RecordData *s_rd_3;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (stopiteration_task);
+ stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ GNUNET_free_non_null(sig_1);
+ GNUNET_free_non_null(sig_2);
+ GNUNET_free_non_null(sig_3);
+ GNUNET_free_non_null(s_name_1);
+ GNUNET_free_non_null(s_name_2);
+ GNUNET_free_non_null(s_name_3);
+
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (stopiteration_task);
+ stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (privkey2 != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey2);
+ privkey2 = NULL;
+
+ GNUNET_free (sig_1);
+ GNUNET_free (sig_2);
+ GNUNET_free (sig_3);
+ GNUNET_free (s_name_1);
+ GNUNET_free (s_name_2);
+ GNUNET_free (s_name_3);
+ if (s_rd_1 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_1->data);
+ GNUNET_free (s_rd_1);
+ }
+ if (s_rd_2 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_2->data);
+ GNUNET_free (s_rd_2);
+ }
+ if (s_rd_3 != NULL)
+ {
+ GNUNET_free ((void *)s_rd_3->data);
+ GNUNET_free (s_rd_3);
+ }
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+ if (returned_records == 1)
+ res = 0;
+ else
+ res = 1;
+
+}
+
+void zone_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ int failed = GNUNET_NO;
+
+ if ((zone_key == NULL) && (name == NULL))
+ {
+ GNUNET_break (3 == returned_records);
+ if (3 == returned_records)
+ res = 0;
+ else
+ res = 1;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records );
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ else
+ {
+
+ /* verify signature returned from name store */
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name);
+ if (0 == strcmp (name, s_name_1))
+ { /* name_1 */
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_1, 1, s_rd_1, signature))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else if (0 == strcmp (name, s_name_2))
+ { /* name_2 */
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_2, 1, s_rd_2, signature))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else if (0 == strcmp (name, s_name_3))
+ { /* name_3 */
+ if (rd_count == 1)
+ {
+ if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey2, expire, s_name_3, 1, s_rd_3, signature))
+ {
+ failed = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name);
+ res = 1;
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+
+ if (failed == GNUNET_NO)
+ {
+ returned_records ++;
+
+ if (1 == returned_records)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping zone iteration after %u received record \n",returned_records );
+ GNUNET_NAMESTORE_zone_iteration_stop (zi);
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3), &end , NULL);
+ return;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n");
+ GNUNET_NAMESTORE_zone_iterator_next (zi);
+ }
+ }
+ else
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+ }
+}
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ static int c = 0;
+
+ if (success == GNUNET_OK)
+ {
+ c++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+
+ if (c == 3)
+ {
+ res = 1;
+ returned_records = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over all zones \n");
+ zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
+ NULL,
+ GNUNET_NAMESTORE_RF_NONE,
+ GNUNET_NAMESTORE_RF_NONE,
+ zone_proc,
+ &zone);
+ if (zi == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n");
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+ }
+ }
+}
+
+static struct GNUNET_NAMESTORE_RecordData *
+create_record (int count)
+{
+ int c;
+ struct GNUNET_NAMESTORE_RecordData * rd;
+ rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+ for (c = 0; c < count; c++)
+ {
+ rd[c].expiration = GNUNET_TIME_absolute_get();
+ rd[c].record_type = 1111;
+ rd[c].data_size = 50;
+ rd[c].data = GNUNET_malloc(50);
+ memset ((char *) rd[c].data, 'a', 50);
+ }
+ return rd;
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL);
+
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+ GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone);
+
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey2 != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2);
+ GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2);
+
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
+
+ GNUNET_asprintf(&s_name_1, "dummy1");
+ s_rd_1 = create_record(1);
+ sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1[0].expiration, s_name_1, s_rd_1, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL);
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
+ GNUNET_asprintf(&s_name_2, "dummy2");
+ s_rd_2 = create_record(1);
+
+ sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2[0].expiration, s_name_2, s_rd_2, 1);
+ GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
+ /* name in different zone */
+ GNUNET_asprintf(&s_name_3, "dummy3");
+ s_rd_3 = create_record(1);
+ sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, s_rd_3[0].expiration, s_name_3, s_rd_3, 1);
+ GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL);
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test_namestore_api_zone_iteration",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test_namestore_api_zone_iteration",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+
+ return ret;
+}
+
+/* end of test_namestore_api_zone_iteration.c */
diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c
new file mode 100644
index 0000000..6efbaf5
--- /dev/null
+++ b/src/namestore/test_namestore_api_zone_to_name.c
@@ -0,0 +1,288 @@
+/*
+ This file is part of GNUnet.
+ (C) 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file namestore/test_namestore_api_zone_to_name.c
+ * @brief testcase for zone to name translation
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_namestore_service.h"
+#include "namestore.h"
+#include "gnunet_signatures.h"
+
+#define VERBOSE GNUNET_NO
+
+#define RECORDS 5
+#define TEST_RECORD_TYPE 1234
+#define TEST_RECORD_DATALEN 123
+#define TEST_RECORD_DATA 'a'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_NAMESTORE_Handle * nsh;
+
+static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_OS_Process *arm;
+
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+
+struct GNUNET_TIME_Absolute expire;
+
+static struct GNUNET_CRYPTO_ShortHashCode s_zone;
+static struct GNUNET_CRYPTO_ShortHashCode s_zone_value;
+
+char * s_name;
+
+struct GNUNET_NAMESTORE_RecordData *s_rd;
+struct GNUNET_CRYPTO_RsaSignature *s_signature;
+
+static int res;
+
+static void
+start_arm (const char *cfgname)
+{
+ arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm", "-c", cfgname,
+#if VERBOSE_PEERS
+ "-L", "DEBUG",
+#else
+ "-L", "ERROR",
+#endif
+ NULL);
+}
+
+static void
+stop_arm ()
+{
+ if (NULL != arm)
+ {
+ if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (arm);
+ GNUNET_OS_process_destroy (arm);
+ arm = NULL;
+ }
+}
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ * @param tc scheduler context
+ */
+static void
+endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+
+ res = 1;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (endbadly_task);
+ endbadly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (privkey != NULL)
+ GNUNET_CRYPTO_rsa_key_free (privkey);
+ privkey = NULL;
+
+ if (nsh != NULL)
+ GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
+ nsh = NULL;
+
+ if (NULL != arm)
+ stop_arm();
+}
+
+void zone_to_name_proc (void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *n,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ int fail = GNUNET_NO;
+
+ if ((zone_key == NULL) && (n == NULL) && (rd_count == 0) && (rd == NULL) && (signature == NULL))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No result found\n");
+ res = 1;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result found: `%s'\n", n);
+ if ((n == NULL) || (0 != strcmp(n, s_name)))
+ {
+ fail = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (rd_count != 1)
+ {
+ fail = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if ((zone_key == NULL) || (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
+ {
+ fail = GNUNET_YES;
+ GNUNET_break (0);
+ }
+ if (fail == GNUNET_NO)
+ res = 0;
+ else
+ res = 1;
+ }
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+}
+
+
+void
+delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *afsdir;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
+ "FILENAME", &afsdir))
+ {
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
+ if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
+ GNUNET_free (afsdir);
+ }
+
+}
+
+
+void
+put_cont (void *cls, int32_t success, const char *emsg)
+{
+ char *name = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+ if (success == GNUNET_OK)
+ {
+ res = 0;
+
+ /* create initial record */
+ GNUNET_NAMESTORE_zone_to_name (nsh, &s_zone, &s_zone_value, zone_to_name_proc, NULL);
+
+ }
+ else
+ {
+ res = 1;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
+ GNUNET_SCHEDULER_add_now(&end, NULL);
+ }
+}
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ delete_existing_db(cfg);
+
+ endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
+ GNUNET_asprintf(&s_name, "dummy");
+
+
+ /* load privat key */
+ char *hostkey_file;
+ GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
+ "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
+ privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
+ GNUNET_free (hostkey_file);
+ GNUNET_assert (privkey != NULL);
+ /* get public key */
+ GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+ /* zone hash */
+ GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
+ GNUNET_CRYPTO_short_hash (s_name, strlen (s_name) + 1, &s_zone_value);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using PKEY `%s' \n", GNUNET_short_h2s (&s_zone_value));
+
+ struct GNUNET_NAMESTORE_RecordData rd;
+ rd.expiration = GNUNET_TIME_absolute_get();
+ rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY;
+ rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
+ rd.data = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ memcpy ((char *) rd.data, &s_zone_value, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+
+ start_arm (cfgfile);
+ GNUNET_assert (arm != NULL);
+
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ GNUNET_break (NULL != nsh);
+
+ expire = GNUNET_TIME_absolute_get ();
+ s_signature = GNUNET_NAMESTORE_create_signature(privkey, rd.expiration, s_name, &rd, 1);
+ GNUNET_NAMESTORE_record_put(nsh, &pubkey, s_name, expire, 1, &rd, s_signature, put_cont, NULL);
+
+ GNUNET_free ((void *) rd.data);
+}
+
+static int
+check ()
+{
+ static char *const argv[] = { "test-namestore-api",
+ "-c",
+ "test_namestore_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ res = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
+ "nohelp", options, &run, &res);
+ return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ ret = check ();
+ return ret;
+}
+
+/* end of test_namestore_api.c */
diff --git a/src/namestore/test_namestore_record_serialization.c b/src/namestore/test_namestore_record_serialization.c
index 5ea345b..5e95253 100644
--- a/src/namestore/test_namestore_record_serialization.c
+++ b/src/namestore/test_namestore_record_serialization.c
@@ -36,15 +36,12 @@ static void
run (void *cls, char *const *args, const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- char * dest = NULL;
size_t len;
int c;
- int elem = 0;
int rd_count = 3;
size_t data_len;
struct GNUNET_NAMESTORE_RecordData src[rd_count];
- struct GNUNET_NAMESTORE_RecordData *dst = NULL;
memset(src, '\0', rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
@@ -61,25 +58,27 @@ run (void *cls, char *const *args, const char *cfgfile,
}
res = 0;
- len = GNUNET_NAMESTORE_records_serialize (&dest, rd_count, src);
+ len = GNUNET_NAMESTORE_records_get_size(rd_count, src);
+ char rd_ser[len];
+ GNUNET_assert (len == GNUNET_NAMESTORE_records_serialize(rd_count, src, len, rd_ser));
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len);
- GNUNET_assert (dest != NULL);
+ GNUNET_assert (rd_ser != NULL);
- elem = GNUNET_NAMESTORE_records_deserialize(&dst, dest, len);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized elements: %u\n",elem);
+ struct GNUNET_NAMESTORE_RecordData dst[rd_count];
+ GNUNET_assert (GNUNET_OK == GNUNET_NAMESTORE_records_deserialize (len, rd_ser, rd_count, dst));
- GNUNET_assert (elem == rd_count);
GNUNET_assert (dst != NULL);
- for (c = 0; c < elem; c++)
+ for (c = 0; c < rd_count; c++)
{
if (src[c].data_size != dst[c].data_size)
{
GNUNET_break (0);
res = 1;
}
- if (GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value != GNUNET_TIME_relative_get_zero().rel_value)
+ if (0 != GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value)
{
GNUNET_break (0);
res = 1;
@@ -115,12 +114,12 @@ run (void *cls, char *const *args, const char *cfgfile,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c);
- /* clean up */
- GNUNET_free((char *) dst[c].data);
- GNUNET_free((char *) src[c].data);
}
- GNUNET_free (dest);
- GNUNET_free (dst);
+
+ for (c = 0; c < rd_count; c++)
+ {
+ GNUNET_free ((void *)src[c].data);
+ }
}
static int
diff --git a/src/namestore/test_plugin_namestore.c b/src/namestore/test_plugin_namestore.c
index 0b0008f..3e93d73 100644
--- a/src/namestore/test_plugin_namestore.c
+++ b/src/namestore/test_plugin_namestore.c
@@ -176,7 +176,7 @@ run (void *cls, char *const *args, const char *cfgfile,
{
struct GNUNET_NAMESTORE_PluginFunctions *nsp;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
- GNUNET_HashCode zone;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
ok = 0;
nsp = load_plugin (cfg);
@@ -187,13 +187,16 @@ run (void *cls, char *const *args, const char *cfgfile,
"Failed to initialize namestore. Database likely not setup, skipping test.\n");
return;
}
+
put_record (nsp, 1);
+
get_record (nsp, 1);
memset (&zone_key, 1, sizeof (zone_key));
- GNUNET_CRYPTO_hash (&zone_key, sizeof (zone_key), &zone);
+ GNUNET_CRYPTO_short_hash (&zone_key, sizeof (zone_key), &zone);
nsp->delete_zone (nsp->cls, &zone);
unload_plugin (nsp);
+
}
@@ -235,8 +238,6 @@ main (int argc, char *argv[])
GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_namestore_%s.conf",
plugin_name);
- if (pos != plugin_name)
- pos[0] = '.';
GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv,
"test-plugin-namestore", "nohelp", options, &run, NULL);
if (ok != 0)
diff --git a/src/namestore/hostkey b/src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey
index eac1d1e..eac1d1e 100644
--- a/src/namestore/hostkey
+++ b/src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey
Binary files differ
diff --git a/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey b/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey
new file mode 100644
index 0000000..871fc90
--- /dev/null
+++ b/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey
Binary files differ