From 91dfeebc1a2e840f88904aab7f43ce214c3eb03a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 7 Oct 2013 18:08:05 +0000 Subject: [PATCH] -moving friends file parsing logic into its own library --- src/include/Makefile.am | 5 +- src/include/gnunet_friends_lib.h | 95 +++++++++++++++ src/topology/Makefile.am | 19 ++- src/topology/friends.c | 165 ++++++++++++++++++++++++++ src/topology/gnunet-daemon-topology.c | 124 ++++++------------- 5 files changed, 314 insertions(+), 94 deletions(-) create mode 100644 src/include/gnunet_friends_lib.h create mode 100644 src/topology/friends.c diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 634ce6f23..8a848135b 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS = . gnunetincludedir = $(includedir)/gnunet nodist_gnunetinclude_HEADERS = \ - gnunet_directories.h + gnunet_directories.h if MINGW WINPROC = winproc.h @@ -44,6 +44,7 @@ gnunetinclude_HEADERS = \ gnunet_dns_service.h \ gnunet_dv_service.h \ gnunet_fragmentation_lib.h \ + gnunet_friends_lib.h \ gnunet_fs_service.h \ gnunet_getopt_lib.h \ gnunet_gns_service.h \ @@ -87,4 +88,4 @@ gnunetinclude_HEADERS = \ gnunet_transport_plugin.h \ gnunet_tun_lib.h \ gnunet_util_lib.h \ - gnunet_vpn_service.h + gnunet_vpn_service.h diff --git a/src/include/gnunet_friends_lib.h b/src/include/gnunet_friends_lib.h new file mode 100644 index 000000000..dda1d3245 --- /dev/null +++ b/src/include/gnunet_friends_lib.h @@ -0,0 +1,95 @@ +/* + This file is part of GNUnet. + (C) 2013 Christian Grothoff + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file include/gnunet_friends_lib.h + * @brief library to read and write the FRIENDS file + * @author Christian Grothoff + */ +#ifndef GNUNET_FRIENDS_LIB_H +#define GNUNET_FRIENDS_LIB_H + +#include "gnunet_util_lib.h" + + +/** + * Signature of a function called on each friend found. + * + * @param cls closure + * @param friend peer identity of the friend + */ +typedef void (*GNUNET_FRIENDS_Callback)(void *cls, + const struct GNUNET_PeerIdentity *friend); + + +/** + * Parse the FRIENDS file. + * + * @param cfg our configuration + * @param cb function to call on each friend found + * @param cb_cls closure for @a cb + * @return #GNUNET_OK on success, #GNUNET_SYSERR on parsing errors + */ +int +GNUNET_FRIENDS_parse (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_FRIENDS_Callback cb, + void *cb_cls); + + +/** + * Handle for writing a friends file. + */ +struct GNUNET_FRIENDS_Writer; + + +/** + * Start writing a fresh FRIENDS file. Will make a backup of the + * old one. + * + * @param cfg configuration to use. + * @return NULL on error + */ +struct GNUNET_FRIENDS_Writer * +GNUNET_FRIENDS_write_start (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Finish writing out the friends file. + * + * @param w write handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_FRIENDS_write_stop (struct GNUNET_FRIENDS_Writer *w); + + +/** + * Add a friend to the friends file. + * + * @param w write handle + * @param friend friend to add + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_FRIENDS_write (struct GNUNET_FRIENDS_Writer *w, + const struct GNUNET_PeerIdentity *friend); + + +#endif diff --git a/src/topology/Makefile.am b/src/topology/Makefile.am index 1094325ff..8c78d5c2c 100644 --- a/src/topology/Makefile.am +++ b/src/topology/Makefile.am @@ -12,12 +12,25 @@ dist_pkgcfg_DATA = \ topology.conf +lib_LTLIBRARIES = libgnunetfriends.la + +libgnunetfriends_la_SOURCES = \ + friends.c +libgnunetfriends_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la + $(GN_LIBINTL) $(XLIB) +libgnunetfriends_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) $(WINFLAGS) \ + -version-info 0:0:0 + + libexec_PROGRAMS = \ gnunet-daemon-topology gnunet_daemon_topology_SOURCES = \ - gnunet-daemon-topology.c + gnunet-daemon-topology.c gnunet_daemon_topology_LDADD = \ + libgnunetfriends.la \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ @@ -40,7 +53,7 @@ test_gnunet_daemon_topology_SOURCES = \ test_gnunet_daemon_topology.c test_gnunet_daemon_topology_LDADD = \ $(top_builddir)/src/testbed/libgnunettestbed.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la EXTRA_DIST = \ - test_gnunet_daemon_topology_data.conf + test_gnunet_daemon_topology_data.conf diff --git a/src/topology/friends.c b/src/topology/friends.c new file mode 100644 index 000000000..c0915fa15 --- /dev/null +++ b/src/topology/friends.c @@ -0,0 +1,165 @@ +/* + This file is part of GNUnet. + (C) 2013 Christian Grothoff + + 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 topology/friends.c + * @brief library to read and write the FRIENDS file + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_friends_lib.h" + + +/** + * Parse the FRIENDS file. + * + * @param cfg our configuration + * @param cb function to call on each friend found + * @param cb_cls closure for @a cb + * @return #GNUNET_OK on success, #GNUNET_SYSERR on parsing errors + */ +int +GNUNET_FRIENDS_parse (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_FRIENDS_Callback cb, + void *cb_cls) +{ + char *fn; + char *data; + size_t pos; + size_t start; + struct GNUNET_PeerIdentity pid; + uint64_t fsize; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, "TOPOLOGY", "FRIENDS", &fn)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "topology", "FRIENDS"); + return GNUNET_SYSERR; + } + if ( (GNUNET_OK != GNUNET_DISK_file_test (fn)) && + (GNUNET_OK != GNUNET_DISK_fn_write (fn, NULL, 0, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE)) ) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); + if ( (GNUNET_OK != + GNUNET_DISK_file_size (fn, + &fsize, + GNUNET_NO, GNUNET_YES)) || + (0 == fsize) ) + { + GNUNET_free (fn); + return GNUNET_OK; + } + data = GNUNET_malloc_large (fsize); + if (NULL == data) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc"); + GNUNET_free (fn); + return GNUNET_SYSERR; + } + if (fsize != GNUNET_DISK_fn_read (fn, data, fsize)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "read", "fn"); + GNUNET_free (fn); + GNUNET_free (data); + return GNUNET_SYSERR; + } + start = 0; + pos = 0; + while (pos < fsize) + { + while ((pos < fsize) && isspace ((unsigned char) data[pos])) + pos++; + if (GNUNET_OK != + GNUNET_CRYPTO_ecc_public_sign_key_from_string (&data[start], + pos - start, + &pid.public_key)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Syntax error in topology specification at offset %llu, skipping bytes `%.*s'.\n"), + (unsigned long long) pos, + (int) (pos - start), + &data[start]); + pos++; + start = pos; + continue; + } + pos++; + start = pos; + cb (cb_cls, &pid); + } + GNUNET_free (data); + GNUNET_free (fn); + return GNUNET_OK; +} + + +/** + * Handle for writing a friends file. + */ +struct GNUNET_FRIENDS_Writer +{ +}; + + +/** + * Start writing a fresh FRIENDS file. Will make a backup of the + * old one. + * + * @param cfg configuration to use. + * @return NULL on error + */ +struct GNUNET_FRIENDS_Writer * +GNUNET_FRIENDS_write_start (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + return NULL; +} + + +/** + * Finish writing out the friends file. + * + * @param w write handle + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_FRIENDS_write_stop (struct GNUNET_FRIENDS_Writer *w) +{ + return GNUNET_SYSERR; +} + + +/** + * Add a friend to the friends file. + * + * @param w write handle + * @param friend friend to add + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_FRIENDS_write (struct GNUNET_FRIENDS_Writer *w, + const struct GNUNET_PeerIdentity *friend) +{ + return GNUNET_SYSERR; +} + + +/* end of friends.c */ diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index 761986d68..051dccf50 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c @@ -25,6 +25,7 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_friends_lib.h" #include "gnunet_constants.h" #include "gnunet_core_service.h" #include "gnunet_protocols.h" @@ -1002,118 +1003,63 @@ core_init (void *cls, /** - * Read the friends file. + * Process friend found in FRIENDS file. + * + * @param cls pointer to an `unsigned int` to be incremented per friend found + * @param pid identity of the friend */ static void -read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) +handle_friend (void *cls, + const struct GNUNET_PeerIdentity *pid) { - char *fn; - char *data; - size_t pos; - size_t start; - struct GNUNET_PeerIdentity pid; - uint64_t fsize; - unsigned int entries_found; + unsigned int *entries_found = cls; struct Peer *fl; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, "TOPOLOGY", "FRIENDS", &fn)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "topology", "FRIENDS"); - return; - } - if ( (GNUNET_OK != GNUNET_DISK_file_test (fn)) && - (GNUNET_OK != GNUNET_DISK_fn_write (fn, NULL, 0, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE)) ) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); - if (GNUNET_OK != GNUNET_DISK_file_size (fn, - &fsize, GNUNET_NO, GNUNET_YES)) - { - if ((friends_only) || (minimum_friend_count > 0)) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not read friends list `%s'\n"), fn); - GNUNET_free (fn); - return; - } - if (0 == fsize) + if (0 == memcmp (pid, &my_identity, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Friends file `%s' is empty.\n"), - fn); - GNUNET_free (fn); - return; - } - data = GNUNET_malloc_large (fsize); - if (NULL == data) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to read friends list from `%s': out of memory\n"), - fn); - GNUNET_free (fn); - return; - } - if (fsize != GNUNET_DISK_fn_read (fn, data, fsize)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to read friends list from `%s'\n"), fn); - GNUNET_free (fn); - GNUNET_free (data); + _("Found myself `%s' in friend list (useless, ignored)\n"), + GNUNET_i2s (&pid)); return; } + (*entries_found)++; + fl = make_peer (pid, NULL, GNUNET_YES); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Found friend `%s' in configuration\n"), + GNUNET_i2s (&fl->pid)); +} + + +/** + * Read the friends file. + */ +static void +read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + unsigned int entries_found; + entries_found = 0; - start = 0; - pos = 0; - while (pos < fsize) + if (GNUNET_OK != + GNUNET_FRIENDS_parse (cfg, + &handle_friend, + &entries_found)) { - while ((pos < fsize) && isspace ((unsigned char) data[pos])) - pos++; - if (GNUNET_OK != - GNUNET_CRYPTO_ecc_public_sign_key_from_string (&data[start], - pos - start, - &pid.public_key)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in topology specification at offset %llu, skipping bytes `%.*s'.\n"), - (unsigned long long) pos, - (int) (pos - start), - &data[start]); - pos++; - start = pos; - continue; - } - pos++; - start = pos; - if (0 == memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity))) - { + if ((friends_only) || (minimum_friend_count > 0)) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Found myself `%s' in friend list (useless, ignored)\n"), - GNUNET_i2s (&pid)); - continue; - } - entries_found++; - fl = make_peer (&pid, NULL, GNUNET_YES); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Found friend `%s' in configuration\n"), - GNUNET_i2s (&fl->pid)); + _("Encountered errors parsing friends list!\n")); } - GNUNET_free (data); - GNUNET_free (fn); GNUNET_STATISTICS_update (stats, gettext_noop ("# friends in configuration"), entries_found, GNUNET_NO); if ((minimum_friend_count > entries_found) && (friends_only == GNUNET_NO)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n")); + _("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n")); } if ((minimum_friend_count > target_connection_count) && (friends_only == GNUNET_NO)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("More friendly connections required than target total number of connections.\n")); + _("More friendly connections required than target total number of connections.\n")); } } -- 2.25.1