aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/fs/Makefile.am1
-rw-r--r--src/fs/gnunet-service-fs.c108
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/gnunet_peer_lib.h91
-rw-r--r--src/peer/Makefile.am29
-rw-r--r--src/peer/peer.c212
8 files changed, 441 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 28094e057d..20bff6c6af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -753,6 +753,7 @@ src/hello/Makefile
src/include/Makefile
src/include/gnunet_directories.h
src/hostlist/Makefile
+src/peer/Makefile
src/peerinfo/Makefile
src/resolver/Makefile
src/statistics/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 7e92437c6a..a394944d2c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,7 @@ SUBDIRS = \
arm \
fragmentation \
hello \
+ peer \
peerinfo \
resolver \
statistics \
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index e2f2e62678..a91459e643 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -88,6 +88,7 @@ gnunet_service_fs_LDADD = \
$(top_builddir)/src/fs/libgnunetfs.la \
$(top_builddir)/src/datastore/libgnunetdatastore.la \
$(top_builddir)/src/core/libgnunetcore.la \
+ $(top_builddir)/src/peer/libgnunetpeer.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_LIBINTL)
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index 1f248c0592..5237cee042 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -42,6 +42,7 @@
#include "platform.h"
#include "gnunet_core_service.h"
#include "gnunet_datastore_service.h"
+#include "gnunet_peer_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_util_lib.h"
@@ -341,12 +342,112 @@ struct ProcessGetContext
/**
- * Information we keep for each pending
- * request.
+ * Information we keep for each pending request. We should try to
+ * keep this struct as small as possible since its memory consumption
+ * is key to how many requests we can have pending at once.
*/
struct PendingRequest
{
- // FIXME
+
+ /**
+ * ID of a client making a request, NULL if this entry is for a
+ * peer.
+ */
+ struct GNUNET_SERVER_Client *client;
+
+ /**
+ * If this is a namespace query, pointer to the hash of the public
+ * key of the namespace; otherwise NULL.
+ */
+ GNUNET_HashCode *namespace;
+
+ /**
+ * Bloomfilter we use to filter out replies that we don't care about
+ * (anymore). NULL as long as we are interested in all replies.
+ */
+ struct GNUNET_CONTAINER_BloomFilter *bf;
+
+ /**
+ * Hash code of all replies that we have seen so far (only valid
+ * if client is not NULL since we only track replies like this for
+ * our own clients).
+ */
+ GNUNET_HashCode *replies_seen;
+
+ /**
+ * When did we first see this request (form this peer), or, if our
+ * client is initiating, when did we last initiate a search?
+ */
+ struct GNUNET_TIME_Absolute start_time;
+
+ /**
+ * The query that this request is for.
+ */
+ GNUNET_HashCode query;
+
+ /**
+ * (Interned) Peer identifier (only valid if "client" is NULL)
+ * that identifies a peer that gave us this request.
+ */
+ GNUNET_PEER_Id source_pid;
+
+ /**
+ * (Interned) Peer identifier that identifies a preferred target
+ * for requests.
+ */
+ GNUNET_PEER_Id target_pid;
+
+ /**
+ * (Interned) Peer identifiers of peers that have already
+ * received our query for this content.
+ */
+ GNUNET_PEER_Id *used_pids;
+
+ /**
+ * How many entries in "used_pids" are actually valid?
+ */
+ unsigned int used_pids_off;
+
+ /**
+ * How long is the "used_pids" array?
+ */
+ unsigned int used_pids_size;
+
+ /**
+ * How many entries in "replies_seen" are actually valid?
+ */
+ unsigned int replies_seen_off;
+
+ /**
+ * How long is the "replies_seen" array?
+ */
+ unsigned int replies_seen_size;
+
+ /**
+ * Priority with which this request was made. If one of our clients
+ * made the request, then this is the current priority that we are
+ * using when initiating the request. This value is used when
+ * we decide to reward other peers with trust for providing a reply.
+ */
+ uint32_t priority;
+
+ /**
+ * Priority points left for us to spend when forwarding this request
+ * to other peers.
+ */
+ uint32_t remaining_priority;
+
+ /**
+ * TTL with which we saw this request (or, if we initiated, TTL that
+ * we used for the request).
+ */
+ int32_t ttl;
+
+ /**
+ * Type of the content that this request is for.
+ */
+ uint32_t type;
+
};
@@ -1080,6 +1181,7 @@ handle_on_demand_block (const GNUNET_HashCode * key,
off = GNUNET_ntohll (odb->offset);
fn = (const char*) GNUNET_CONTAINER_multihashmap_get (ifm,
&odb->file_id);
+ fh = NULL;
if ( (NULL == fn) ||
(NULL == (fh = GNUNET_DISK_file_open (fn,
GNUNET_DISK_OPEN_READ))) ||
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 008d6a180e..39fb2f0f5d 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -30,6 +30,7 @@ gnunetinclude_HEADERS = \
gnunet_getopt_lib.h \
gnunet_hello_lib.h \
gnunet_network_lib.h \
+ gnunet_peer_lib.h \
gnunet_peerinfo_service.h \
gnunet_program_lib.h \
gnunet_protocols.h \
diff --git a/src/include/gnunet_peer_lib.h b/src/include/gnunet_peer_lib.h
new file mode 100644
index 0000000000..036eea1dc6
--- /dev/null
+++ b/src/include/gnunet_peer_lib.h
@@ -0,0 +1,91 @@
+/*
+ This file is part of GNUnet.
+ (C) 2006, 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file include/gnunet_peer_lib.h
+ * @brief helper library for interning of peer identifiers
+ * @author Christian Grothoff
+ */
+
+#ifndef GNUNET_PEER_LIB_H
+#define GNUNET_PEER_LIB_H
+
+#include "gnunet_util_lib.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+/**
+ * A GNUNET_PEER_Id is simply a shorter
+ * version of a "struct GNUNET_PeerIdentifier"
+ * that can be used inside of a GNUnet peer
+ * to save memory when the same identifier
+ * needs to be used over and over again.
+ */
+typedef unsigned int GNUNET_PEER_Id;
+
+
+/**
+ * Intern an peer identity. If the identity is already known, its
+ * reference counter will be increased by one.
+ *
+ * @param pid identity to intern
+ * @return the interned identity.
+ */
+GNUNET_PEER_Id GNUNET_PEER_intern (const struct GNUNET_PeerIdentity * pid);
+
+
+/**
+ * Change the reference counter of an interned PID.
+ *
+ * @param id identity to change the RC of
+ * @param delta how much to change the RC
+ */
+void GNUNET_PEER_change_rc (GNUNET_PEER_Id id, int delta);
+
+
+/**
+ * Decrement multiple RCs of peer identities by one.
+ *
+ * @param ids array of PIDs to decrement the RCs of
+ * @param count size of the ids array
+ */
+void GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id * ids,
+ unsigned int count);
+
+
+/**
+ * Convert an interned PID to a normal peer identity.
+ *
+ * @param id interned PID to convert
+ * @param pid where to write the normal peer identity
+ */
+void GNUNET_PEER_resolve (GNUNET_PEER_Id id,
+ struct GNUNET_PeerIdentity * pid);
+
+
+/* ifndef GNUNET_PEER_LIB_H */
+#endif
+/* end of gnunet_peer_lib.h */
diff --git a/src/peer/Makefile.am b/src/peer/Makefile.am
new file mode 100644
index 0000000000..bd268cf39d
--- /dev/null
+++ b/src/peer/Makefile.am
@@ -0,0 +1,29 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+if MINGW
+ WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
+endif
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+ XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = libgnunetpeer.la
+
+libgnunetpeer_la_SOURCES = \
+ peer.c
+libgnunetpeer_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
+
+#check_PROGRAMS = \
+# test_peer
+#
+#TESTS = $(check_PROGRAMS)
+#
+#test_peer_SOURCES = \
+# test_peer.c
+#test_peer_LDADD = \
+# $(top_builddir)/src/peer/libgnunetpeer.la \
+# $(top_builddir)/src/util/libgnunetutil.la
+
diff --git a/src/peer/peer.c b/src/peer/peer.c
new file mode 100644
index 0000000000..02c95f4db9
--- /dev/null
+++ b/src/peer/peer.c
@@ -0,0 +1,212 @@
+/*
+ This file is part of GNUnet
+ (C) 2006, 2008, 2009 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file peer/peer.c
+ * @brief peer-ID table that assigns integer IDs to peer-IDs to save memory
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_peer_lib.h"
+
+
+struct PeerEntry
+{
+ /**
+ * the identifier itself
+ */
+ struct GNUNET_PeerIdentity id;
+
+ /**
+ * Short version of the identifier;
+ * if the RC==0, then index of next
+ * free slot in table, otherwise
+ * equal to this slot in the table.
+ */
+ GNUNET_PEER_Id pid;
+
+ /**
+ * Reference counter, 0 if this slot
+ * is not used.
+ */
+ unsigned int rc;
+};
+
+
+/**
+ * Table with our interned peer IDs.
+ */
+static struct PeerEntry *table;
+
+/**
+ * Hashmap of PeerIdentities to "struct PeerEntry"
+ * (for fast lookup). NULL until the library
+ * is actually being used.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *map;
+
+/**
+ * Size of the "table".
+ */
+static unsigned int size;
+
+/**
+ * Index of the beginning of the free list in the table; set to "size"
+ * if no slots are free in the table.
+ */
+static unsigned int free_list_start;
+
+
+/**
+ * Intern an peer identity. If the identity is already known, its
+ * reference counter will be increased by one.
+ *
+ * @param pid identity to intern
+ * @return the interned identity.
+ */
+GNUNET_PEER_Id
+GNUNET_PEER_intern (const struct GNUNET_PeerIdentity * pid)
+{
+ GNUNET_PEER_Id ret;
+ struct PeerEntry *e;
+ unsigned int i;
+
+ if (pid == NULL)
+ return 0;
+ if (NULL == map)
+ map = GNUNET_CONTAINER_multihashmap_create (32);
+ e = GNUNET_CONTAINER_multihashmap_get (map,
+ &pid->hashPubKey);
+ if (e != NULL)
+ {
+ GNUNET_assert (e->rc > 0);
+ e->rc++;
+ return e->pid;
+ }
+ ret = free_list_start;
+ if (ret == size)
+ {
+ GNUNET_array_grow (table, size, size + 16);
+ for (i=ret;i<size;i++)
+ table[i].pid = i + 1;
+ }
+ if (ret == 0)
+ {
+ table[0].pid = 0;
+ table[0].rc = 1;
+ ret = 1;
+ }
+ GNUNET_assert (ret < size);
+ GNUNET_assert (table[ret].rc == 0);
+ free_list_start = table[ret].pid;
+ table[ret].id = *pid;
+ table[ret].rc = 1;
+ table[ret].pid = ret;
+ GNUNET_CONTAINER_multihashmap_put (map,
+ &pid->hashPubKey,
+ &table[ret],
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ return ret;
+}
+
+
+/**
+ * Decrement multiple RCs of peer identities by one.
+ *
+ * @param ids array of PIDs to decrement the RCs of
+ * @param count size of the ids array
+ */
+void
+GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id * ids,
+ unsigned int count)
+{
+ int i;
+ GNUNET_PEER_Id id;
+
+ if (count == 0)
+ return;
+ for (i = count - 1; i >= 0; i--)
+ {
+ id = ids[i];
+ GNUNET_assert (id < size);
+ GNUNET_assert (table[id].rc > 0);
+ table[id].rc--;
+ if (table[id].rc == 0)
+ {
+ GNUNET_CONTAINER_multihashmap_remove (map,
+ &table[id].id.hashPubKey,
+ &table[id]);
+ table[id].pid = free_list_start;
+ free_list_start = id;
+ }
+ }
+}
+
+
+/**
+ * Change the reference counter of an interned PID.
+ *
+ * @param id identity to change the RC of
+ * @param delta how much to change the RC
+ */
+void
+GNUNET_PEER_change_rc (GNUNET_PEER_Id id, int delta)
+{
+ if (id == 0)
+ return;
+ GNUNET_assert (id < size);
+ GNUNET_assert (table[id].rc > 0);
+ GNUNET_assert ((delta >= 0) || (table[id].rc >= -delta));
+ table[id].rc += delta;
+ if (table[id].rc == 0)
+ {
+ GNUNET_CONTAINER_multihashmap_remove (map,
+ &table[id].id.hashPubKey,
+ &table[id]);
+ table[id].pid = free_list_start;
+ free_list_start = id;
+ }
+}
+
+
+/**
+ * Convert an interned PID to a normal peer identity.
+ *
+ * @param id interned PID to convert
+ * @param pid where to write the normal peer identity
+ */
+void
+GNUNET_PEER_resolve (GNUNET_PEER_Id id,
+ struct GNUNET_PeerIdentity * pid)
+{
+ if (id == 0)
+ {
+ memset (pid, 0, sizeof (struct GNUNET_PeerIdentity));
+ GNUNET_break (0);
+ return;
+ }
+ GNUNET_assert (id < size);
+ GNUNET_assert (table[id].rc > 0);
+ *pid = table[id].id;
+}
+
+
+/* end of peer.c */