summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-07-07 06:27:10 +0000
committerChristian Grothoff <christian@grothoff.org>2010-07-07 06:27:10 +0000
commitac2de52a5de68f6f4f13b7aa01a481869fffc6aa (patch)
tree856c9f0b2f55f8cae99f3c7b3bf22beaecbf58da
parentc1a3c11f8665432d9db6d549c28c0329668e66af (diff)
hacks from trip
-rw-r--r--TODO77
-rw-r--r--contrib/defaults.conf2
-rw-r--r--doc/man/gnunet-peerinfo.112
-rwxr-xr-xmkinstalldirs5
-rw-r--r--src/core/core.h58
-rw-r--r--src/core/core_api.c32
-rw-r--r--src/core/gnunet-service-core.c84
-rw-r--r--src/core/test_core_api.c2
-rw-r--r--src/core/test_core_api_reliability.c2
-rw-r--r--src/core/test_core_api_start_only.c2
-rw-r--r--src/dht/gnunet-service-dht.c1
-rw-r--r--src/dv/gnunet-service-dv.c6
-rw-r--r--src/dv/test_transport_api_dv.c20
-rw-r--r--src/fs/gnunet-service-fs.c175
-rw-r--r--src/hostlist/gnunet-daemon-hostlist.c2
-rw-r--r--src/hostlist/hostlist-server.c8
-rw-r--r--src/hostlist/test_gnunet_daemon_hostlist_learning.c14
-rw-r--r--src/include/gnunet_core_service.h22
-rw-r--r--src/include/gnunet_peerinfo_service.h13
-rw-r--r--src/include/gnunet_protocols.h70
-rw-r--r--src/include/gnunet_statistics_service.h22
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c49
-rwxr-xr-xsrc/peerinfo-tool/test_gnunet_peerinfo.py.in12
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c181
-rw-r--r--src/peerinfo/peerinfo.h37
-rw-r--r--src/peerinfo/peerinfo_api.c40
-rw-r--r--src/peerinfo/peerinfo_api_notify.c2
-rw-r--r--src/peerinfo/test_peerinfo_api.c5
-rw-r--r--src/statistics/gnunet-service-statistics.c332
-rw-r--r--src/statistics/statistics.h39
-rw-r--r--src/statistics/statistics_api.c365
-rw-r--r--src/statistics/test_statistics_api.c37
-rw-r--r--src/statistics/test_statistics_api_data.conf3
-rw-r--r--src/testing/test_testing_topology.c18
-rw-r--r--src/testing/testing.c6
-rw-r--r--src/topology/gnunet-daemon-topology.c7
-rw-r--r--src/transport/gnunet-service-transport.c11
-rw-r--r--src/util/server_nc.c26
38 files changed, 1269 insertions, 530 deletions
diff --git a/TODO b/TODO
index 9b7ad277a..fbd4d4575 100644
--- a/TODO
+++ b/TODO
@@ -1,67 +1,42 @@
-0.9.0pre1:
-* TRANSPORT:
- - HTTP backend [MW]
-* CORE:
- - derived key generation [Nils]
+0.9.0pre2:
* UTIL:
- only connect() sockets that are ready (select()) [Nils]
[On W32, we need to select after calling socket before doing connect etc.]
-* BUGS:
- Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616.
- (transport notified us that we connected to ourselves!!!)
-
-0.9.0pre2:
+* TRANSPORT:
+ - HTTP backend [MW]
+ - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616.
+ (transport notified us that we connected to ourselves!!!)
* CORE:
- transport-level disconnect (i.e. TCP) does not cause core-level
disconnect in a timely fashion (waits for connection timeout);
need to figure a way to make it near-instant in those cases
- (i.e. rapid reduction in timeout on transport-level disconnect)
- - encrypted P2P transmission (loopback) tops at 2 MB/s on my quad-core;
- why is it so slow? Fix! (see core_api_reliability test)
- - implement API to get notifications about bandwidth assignments to individual peers
- - implement API to get notifications about updates to liveness of individual peers (before disconnect)
-* STATISTICS:
- - implement notification-based statistics API
-* PEERINFO [CG]
- - better API for trust management (or move into FS!?)
-* TOPOLOGY:
- - needs more testing (especially F2F topology) & transport blacklisting
-* TBENCH: [MW]
- - good to have for transport/DV evaluation!
-* DV: [Nate]
- - implement performance tests (needs tbench)
+ (i.e. rapid reduction in timeout on transport-level disconnect) [CG]
+ - derived key generation [Nils]
* DHT: [Nate]
- implement DHT service
- implement testcases
- implement performance tests
-* MONKEY: [Safey]
- - better crash management (attach debugging support, capture and analyze
- debug output, detect random vs. deterministic crashes)
-* ARM: [CG]
- - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?)
- - discover dependencies between services
* FS: [CG]
- - trust & peerinfo integration
- - load considerations (migration, routing)
+ - publishing a directory sets the embedded filename to "empty"
+ (likely an issue with cutting off everything before '/' in the filename,
+ which in the case of a directory would leave nothing)
+ - trust: do not charge when "idle" / load considerations (migration, routing)
- bound our priorities based on priorities used by other peers
- - artificial delays
- - active reply route caching design & implementation of service; gap extension!
- datastore reservation (publishing)
- - location URIs (publish, search, download)
- unindex on index failure
+ - listing of learned namespaces
+ - collection API & tests
+ + gnunet-pseudonym (collection support)
+ - artificial delays
+ - active reply route caching design & implementation of service; gap extension!
- utilize in-line files in meta data always (including in search results or
when download is triggered manually and for probes); currently the data is
only used when users do a general 'recursive' download
+ - location URIs (publish, search, download)
- non-anonymous FS service (needs DHT)
+ DHT integration for search
+ CS-DHT-functions (DHT-put of LOC)
+ P2P-functions (DHT-get)
- - listing of learned namespaces
- - collection API & tests
- + gnunet-pseudonym (collection support)
- - publishing a directory sets the embedded filename to "empty"
- (likely an issue with cutting off everything before '/' in the filename,
- which in the case of a directory would leave nothing)
- implement FS performance tests
+ insert
+ download
@@ -101,6 +76,13 @@
- implement download by URI dialog; figure out where to display those downloads!
- figure out where in the GUI we should show active uploads/unindex operations and allow aborts
- handle 'lost parent' case for recursive downloads (need to move children!)
+* MONKEY: [Safey]
+ - better crash management (attach debugging support, capture and analyze
+ debug output, detect random vs. deterministic crashes)
+* TBENCH: [MW]
+ - good to have for transport/DV evaluation!
+* DV: [Nate]
+ - implement performance tests (needs tbench)
0.9.0pre3:
@@ -113,6 +95,8 @@
- test basic peer re-configure
- consider changing API for peer-group termination to
call continuation when done
+* TOPOLOGY:
+ - needs more testing (especially F2F topology) & transport blacklisting
* NAT/UPNP: [MW]
- finalize API design
- code clean up
@@ -127,6 +111,10 @@
- use different 'priority' for probe downloads vs. normal downloads
* ARM: [CG/Safey]
- better tracking of which config changes actually need to cause process restarts by ARM.
+ - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?)
+ - discover dependencies between services
+* STATISTICS:
+ - test notification-based statistics API
* SETUP:
- design & implement new setup tool
@@ -175,6 +163,8 @@
to track actual 'use')
- make sue we also trigger notifications whenever HELLOs expire
* VPN
+* UTIL:
+ - allow limiting UNIX socket access by UID/GID
@@ -193,6 +183,9 @@ Optimizations:
(theoretically reduces overhead; bounds messgae queue size)
* FS:
- use different queue prioritization for probe-downloads vs. normal downloads (!?)
+* CORE:
+ - encrypted P2P transmission (loopback) tops at 2 MB/s on my quad-core;
+ why is it so slow? Fix! (see core_api_reliability test)
Minor features:
* TCP:
diff --git a/contrib/defaults.conf b/contrib/defaults.conf
index b539295b0..def529812 100644
--- a/contrib/defaults.conf
+++ b/contrib/defaults.conf
@@ -107,7 +107,6 @@ UNIXPATH = /tmp/gnunet-service-peerinfo.sock
# REJECT_FROM6 =
# PREFIX =
HOSTS = $SERVICEHOME/data/hosts/
-TRUST = $SERVICEHOME/data/credit/
[transport]
@@ -201,6 +200,7 @@ FILENAME = $SERVICEHOME/datastore/sqlite.db
[fs]
AUTOSTART = YES
INDEXDB = $SERVICEHOME/idxinfo.lst
+TRUST = $SERVICEHOME/data/credit/
IDENTITY_DIR = $SERVICEHOME/identities/
STATE_DIR = $SERVICEHOME/persistence/
PORT = 2094
diff --git a/doc/man/gnunet-peerinfo.1 b/doc/man/gnunet-peerinfo.1
index 99a560075..e2691b11a 100644
--- a/doc/man/gnunet-peerinfo.1
+++ b/doc/man/gnunet-peerinfo.1
@@ -10,7 +10,7 @@ gnunet\-peerinfo \- Display information about other peers.
.SH DESCRIPTION
.PP
-\fBgnunet\-peerinfo\fP display the known addresses and trust of known peers. The tool can also be used to change the amount of trust we have in another peer. For this, the options should be first the amount of trust changed (prefix it with "\-\- " if the amount is negative) followed by the peer identity.
+\fBgnunet\-peerinfo\fP display the known addresses and trust of known peers.
.SH OPTIONS
.B
@@ -35,16 +35,6 @@ Print the version number
.IP "\-L LOGLEVEL, \-\-loglelvel=LOGLEVEL"
Set the loglevel
-.SH EXAMPLE
-.TP
-gnunet\-peerinfo 4 S9LBDF6V770H8CELVKBFJMOTS25LB272JB81MRJHSRJI9B1FBVOSGJVSEIRIS5J4SRDU4HT3TBPLM4MNEND7FFUHMGCK4NBR8R2UTSG
-Increase the trust in a peer by 4
-.TP
-gnunet\-peerinfo \-\- \-2 S9LBDF6V770H8CELVKBFJMOTS25LB272JB81MRJHSRJI9B1FBVOSGJVSEIRIS5J4SRDU4HT3TBPLM4MNEND7FFUHMGCK4NBR8R2UTSG
-Decrease the trust in a peer by 2
-
-
-
.SH BUGS
Report bugs by using mantis <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org>
diff --git a/mkinstalldirs b/mkinstalldirs
index 4191a45db..ef7e16fda 100755
--- a/mkinstalldirs
+++ b/mkinstalldirs
@@ -1,7 +1,7 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2006-05-11.19
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
@@ -157,6 +157,5 @@ exit $errstatus
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
+# time-stamp-end: "$"
# End:
diff --git a/src/core/core.h b/src/core/core.h
index 88e6b748c..021aa4184 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -23,6 +23,7 @@
* @brief common internal definitions for core service
* @author Christian Grothoff
*/
+#include "gnunet_bandwidth_lib.h"
#include "gnunet_crypto_lib.h"
#include "gnunet_time_lib.h"
@@ -45,10 +46,11 @@
#define GNUNET_CORE_OPTION_NOTHING 0
#define GNUNET_CORE_OPTION_SEND_CONNECT 1
#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2
-#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 4
-#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 8
-#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 16
-#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 32
+#define GNUNET_CORE_OPTION_SEND_STATUS_CHANGE 4
+#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8
+#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16
+#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32
+#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64
/**
@@ -100,13 +102,12 @@ struct InitReplyMessage
/**
* Message sent by the service to clients to notify them
- * about a peer connecting or disconnecting.
+ * about a peer connecting.
*/
struct ConnectNotifyMessage
{
/**
* Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
- * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT.
*/
struct GNUNET_MessageHeader header;
@@ -128,6 +129,49 @@ struct ConnectNotifyMessage
};
+/**
+ * Message sent by the service to clients to notify them
+ * about a peer changing status.
+ */
+struct PeerStatusNotifyMessage
+{
+ /**
+ * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PEER_STATUS
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Distance to the peer.
+ */
+ uint32_t distance GNUNET_PACKED;
+
+ /**
+ * Currently observed latency.
+ */
+ struct GNUNET_TIME_RelativeNBO latency;
+
+ /**
+ * When the peer would time out (unless we see activity)
+ */
+ struct GNUNET_TIME_AbsoluteNBO timeout;
+
+ /**
+ * Available bandwidth from the peer.
+ */
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
+
+ /**
+ * Available bandwidth to the peer.
+ */
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
+
+ /**
+ * Identity of the peer.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+};
+
/**
* Message sent by the service to clients to notify them
diff --git a/src/core/core_api.c b/src/core/core_api.c
index d13166c14..5f21d8478 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -67,6 +67,11 @@ struct GNUNET_CORE_Handle
GNUNET_CORE_DisconnectEventHandler disconnects;
/**
+ * Function to call whenever we're notified about a peer changing status.
+ */
+ GNUNET_CORE_PeerStatusEventHandler status_events;
+
+ /**
* Function to call whenever we receive an inbound message.
*/
GNUNET_CORE_MessageCallback inbound_notify;
@@ -381,6 +386,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
const struct DisconnectNotifyMessage *dnm;
const struct NotifyTrafficMessage *ntm;
const struct GNUNET_MessageHeader *em;
+ const struct PeerStatusNotifyMessage *psnm;
uint16_t msize;
uint16_t et;
const struct GNUNET_CORE_MessageHandler *mh;
@@ -433,6 +439,26 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
h->disconnects (h->cls,
&dnm->peer);
break;
+ case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
+ if (NULL == h->status_events)
+ {
+ GNUNET_break (0);
+ break;
+ }
+ if (msize != sizeof (struct PeerStatusNotifyMessage))
+ {
+ GNUNET_break (0);
+ break;
+ }
+ psnm = (const struct PeerStatusNotifyMessage *) msg;
+ h->status_events (h->cls,
+ &psnm->peer,
+ GNUNET_TIME_relative_ntoh (psnm->latency),
+ ntohl (psnm->distance),
+ psnm->bandwidth_in,
+ psnm->bandwidth_out,
+ GNUNET_TIME_absolute_ntoh (psnm->timeout));
+ break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
if (msize <
sizeof (struct NotifyTrafficMessage) +
@@ -658,6 +684,8 @@ transmit_start (void *cls, size_t size, void *buf)
opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
if (h->disconnects != NULL)
opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
+ if (h->status_events != NULL)
+ opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
if (h->inbound_notify != NULL)
{
if (h->inbound_hdr_only)
@@ -717,6 +745,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
GNUNET_CORE_StartupCallback init,
GNUNET_CORE_ConnectEventHandler connects,
GNUNET_CORE_DisconnectEventHandler disconnects,
+ GNUNET_CORE_PeerStatusEventHandler status_events,
GNUNET_CORE_MessageCallback inbound_notify,
int inbound_hdr_only,
GNUNET_CORE_MessageCallback outbound_notify,
@@ -732,6 +761,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
h->init = init;
h->connects = connects;
h->disconnects = disconnects;
+ h->status_events = status_events;
h->inbound_notify = inbound_notify;
h->outbound_notify = outbound_notify;
h->inbound_hdr_only = inbound_hdr_only;
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 4e5177ca3..8cd598e83 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -830,6 +830,43 @@ send_to_all_clients (const struct GNUNET_MessageHeader *msg,
/**
+ * Function called by transport telling us that a peer
+ * changed status.
+ *
+ * @param peer the peer that changed status
+ */
+static void
+handle_peer_status_change (struct Neighbour *n)
+{
+ struct PeerStatusNotifyMessage psnm;
+
+ if (! n->is_connected)
+ return;
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer `%4s' changed status\n",
+ GNUNET_i2s (peer));
+#endif
+ psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
+ psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
+ psnm.distance = htonl (n->last_distance);
+ psnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
+ psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity,
+ GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
+ psnm.bandwidth_in = n->bw_in;
+ psnm.bandwidth_out = n->bw_out;
+ psnm.peer = n->peer;
+ send_to_all_clients (&psnm.header,
+ GNUNET_YES,
+ GNUNET_CORE_OPTION_SEND_STATUS_CHANGE);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# peer status changes"),
+ 1,
+ GNUNET_NO);
+}
+
+
+/**
* Handle CORE_INIT request.
*/
static void
@@ -997,16 +1034,21 @@ handle_client_request_info (void *cls,
if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__)
{
n->bw_out_internal_limit = rcm->limit_outbound;
- n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
- n->bw_out_external_limit);
- GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
- n->bw_out);
- GNUNET_TRANSPORT_set_quota (transport,
- &n->peer,
- n->bw_in,
- n->bw_out,
- GNUNET_TIME_UNIT_FOREVER_REL,
- NULL, NULL);
+ if (n->bw_out.value__ != GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
+ n->bw_out_external_limit).value__)
+ {
+ n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
+ n->bw_out_external_limit);
+ GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
+ n->bw_out);
+ GNUNET_TRANSPORT_set_quota (transport,
+ &n->peer,
+ n->bw_in,
+ n->bw_out,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL, NULL);
+ handle_peer_status_change (n);
+ }
}
if (want_reserv < 0)
{
@@ -2359,13 +2401,11 @@ handle_client_request_connect (void *cls,
* @param cls the 'struct Neighbour' to retry sending the key for
* @param peer the peer for which this is the HELLO
* @param hello HELLO message of that peer
- * @param trust amount of trust we currently have in that peer
*/
static void
process_hello_retry_send_key (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct Neighbour *n = cls;
@@ -2516,7 +2556,6 @@ send_key (struct Neighbour *n)
GNUNET_assert (n->pitr == NULL);
n->pitr = GNUNET_PEERINFO_iterate (peerinfo,
&n->peer,
- 0,
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20),
&process_hello_retry_send_key, n);
return;
@@ -2666,13 +2705,11 @@ handle_set_key (struct Neighbour *n,
* @param cls pointer to the set key message
* @param peer the peer for which this is the HELLO
* @param hello HELLO message of that peer
- * @param trust amount of trust we currently have in that peer
*/
static void
process_hello_retry_handle_set_key (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct Neighbour *n = cls;
struct SetKeyMessage *sm = n->skm;
@@ -2922,6 +2959,7 @@ handle_pong (struct Neighbour *n,
GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
&send_keep_alive,
n);
+ handle_peer_status_change (n);
break;
default:
GNUNET_break (0);
@@ -2974,7 +3012,6 @@ handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
n->skm = m_cpy;
n->pitr = GNUNET_PEERINFO_iterate (peerinfo,
&n->peer,
- 0,
GNUNET_TIME_UNIT_MINUTES,
&process_hello_retry_handle_set_key, n);
GNUNET_STATISTICS_update (stats,
@@ -3364,7 +3401,8 @@ handle_encrypted_message (struct Neighbour *n,
GNUNET_STATISTICS_set (stats,
gettext_noop ("# bytes of payload decrypted"),
size - sizeof (struct EncryptedMessage),
- GNUNET_NO);
+ GNUNET_NO);
+ handle_peer_status_change (n);
if (GNUNET_OK != GNUNET_SERVER_mst_receive (mst,
n,
&buf[sizeof (struct EncryptedMessage)],
@@ -3396,6 +3434,7 @@ handle_transport_receive (void *cls,
int up;
uint16_t type;
uint16_t size;
+ int changed;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3411,6 +3450,7 @@ handle_transport_receive (void *cls,
n = find_neighbour (peer);
if (n == NULL)
n = create_neighbour (peer);
+ changed = (latency.value != n->last_latency.value) || (distance != n->last_distance);
n->last_latency = latency;
n->last_distance = distance;
up = (n->status == PEER_STATE_KEY_CONFIRMED);
@@ -3496,6 +3536,7 @@ handle_transport_receive (void *cls,
{
now = GNUNET_TIME_absolute_get ();
n->last_activity = now;
+ changed = GNUNET_YES;
if (!up)
{
GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), 1, GNUNET_NO);
@@ -3509,6 +3550,8 @@ handle_transport_receive (void *cls,
&send_keep_alive,
n);
}
+ if (changed)
+ handle_peer_status_change (n);
}
@@ -3591,6 +3634,7 @@ neighbour_quota_update (void *cls,
n->bw_out,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL, NULL);
+ handle_peer_status_change (n);
}
schedule_quota_update (n);
}
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c
index c488a5153..ad82d0a1d 100644
--- a/src/core/test_core_api.c
+++ b/src/core/test_core_api.c
@@ -228,6 +228,7 @@ init_notify (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES,
&outbound_notify, GNUNET_YES, handlers);
@@ -321,6 +322,7 @@ run (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
}
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c
index 6d3ae04dc..c2375620a 100644
--- a/src/core/test_core_api_reliability.c
+++ b/src/core/test_core_api_reliability.c
@@ -375,6 +375,7 @@ init_notify (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES,
&outbound_notify, GNUNET_YES, handlers);
@@ -468,6 +469,7 @@ run (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
}
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c
index 4195bdc58..4155bf5d4 100644
--- a/src/core/test_core_api_start_only.c
+++ b/src/core/test_core_api_start_only.c
@@ -133,6 +133,7 @@ init_notify (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES,
&outbound_notify, GNUNET_YES, handlers);
@@ -182,6 +183,7 @@ run (void *cls,
&init_notify,
&connect_notify,
&disconnect_notify,
+ NULL,
&inbound_notify,
GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
}
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index a310cc944..32c01e384 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -834,6 +834,7 @@ run (void *cls,
&core_init, /* Call core_init once connected */
&handle_core_connect, /* Don't care about connects */
NULL, /* Don't care about disconnects */
+ NULL, /* Don't care about peer status changes */
NULL, /* Don't want notified about all incoming messages */
GNUNET_NO, /* For header only inbound notification */
NULL, /* Don't want notified about all outbound messages */
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index b16f12938..9fb008237 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -2755,12 +2755,11 @@ static int add_all_direct_neighbors (void *cls,
* @param cls closure
* @param peer id of the peer, NULL for last call
* @param hello hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer
*/
static void
process_peerinfo (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello, uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct PeerIteratorContext *peerinfo_iterator = cls;
struct DirectNeighbor *neighbor = peerinfo_iterator->neighbor;
@@ -2779,7 +2778,6 @@ process_peerinfo (void *cls,
#endif
peerinfo_iterator->ic = GNUNET_PEERINFO_iterate(peerinfo_handle,
&peerinfo_iterator->neighbor->identity,
- 0,
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
&process_peerinfo,
peerinfo_iterator);
@@ -2856,7 +2854,6 @@ void handle_core_connect (void *cls,
peerinfo_iterator->neighbor = neighbor;
peerinfo_iterator->ic = GNUNET_PEERINFO_iterate (peerinfo_handle,
peer,
- 0,
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
&process_peerinfo,
peerinfo_iterator);
@@ -2988,6 +2985,7 @@ run (void *cls,
&core_init,
&handle_core_connect,
&handle_core_disconnect,
+ NULL,
NULL,
GNUNET_NO,
NULL,
diff --git a/src/dv/test_transport_api_dv.c b/src/dv/test_transport_api_dv.c
index 8157d00e7..3e66388fe 100644
--- a/src/dv/test_transport_api_dv.c
+++ b/src/dv/test_transport_api_dv.c
@@ -534,14 +534,14 @@ init_notify_peer1 (void *cls,
* Connect to the receiving peer
*/
pos->peer2handle = GNUNET_CORE_connect (sched,
- pos->peer2->cfg,
- TIMEOUT,
- pos,
- &init_notify_peer2,
- NULL,
- NULL,
- NULL,
- GNUNET_YES, NULL, GNUNET_YES, handlers);
+ pos->peer2->cfg,
+ TIMEOUT,
+ pos,
+ &init_notify_peer2,
+ NULL,
+ NULL,
+ NULL, NULL,
+ GNUNET_YES, NULL, GNUNET_YES, handlers);
}
@@ -578,7 +578,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
TIMEOUT,
pos,
&init_notify_peer1,
- NULL,
+ NULL, NULL,
NULL,
NULL,
GNUNET_NO, NULL, GNUNET_NO, no_handlers);
@@ -893,7 +893,7 @@ peers_started_callback (void *cls,
GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
new_peer = GNUNET_malloc(sizeof(struct PeerContext));
- new_peer->peer_handle = GNUNET_CORE_connect(sched, cfg, GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers);
+ new_peer->peer_handle = GNUNET_CORE_connect(sched, cfg, GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers);
new_peer->daemon = d;
new_peer->next = all_peers;
all_peers = new_peer;
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index e2d90f786..ea79d0711 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -55,6 +55,12 @@
#define MAX_QUEUE_PER_PEER 16
/**
+ * How often do we flush trust values to disk?
+ */
+#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
+
+
+/**
* Inverse of the probability that we will submit the same query
* to the same peer again. If the same peer already got the query
* repeatedly recently, the probability is multiplied by the inverse
@@ -211,9 +217,14 @@ struct ConnectedPeer
uint64_t inc_preference;
/**
- * Trust delta to still commit to the system.
+ * Trust rating for this peer
*/
- uint32_t trust_delta;
+ uint32_t trust;
+
+ /**
+ * Trust rating for this peer on disk.
+ */
+ uint32_t disk_trust;
/**
* The peer's identity.
@@ -680,6 +691,11 @@ static struct MigrationReadyBlock *mig_tail;
static struct GNUNET_DATASTORE_QueueEntry *mig_qe;
/**
+ * Where do we store trust information?
+ */
+static char *trustDirectory;
+
+/**
* ID of task that collects blocks for migration.
*/
static GNUNET_SCHEDULER_TaskIdentifier mig_task;
@@ -702,6 +718,24 @@ static int active_migration;
/**
+ * Get the filename under which we would store the GNUNET_HELLO_Message
+ * for the given host and protocol.
+ * @return filename of the form DIRECTORY/HOSTID
+ */
+static char *
+get_trust_filename (const struct GNUNET_PeerIdentity *id)
+{
+ struct GNUNET_CRYPTO_HashAsciiEncoded fil;
+ char *fn;
+
+ GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
+ GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil);
+ return fn;
+}
+
+
+
+/**
* Transmit messages by copying it to the target buffer
* "buf". "buf" will be NULL and "size" zero if the socket was closed
* for writing in the meantime. In that case, do nothing
@@ -1148,9 +1182,18 @@ peer_connect_handler (void *cls,
{
struct ConnectedPeer *cp;
struct MigrationReadyBlock *pos;
+ char *fn;
+ uint32_t trust;
cp = GNUNET_malloc (sizeof (struct ConnectedPeer));
cp->pid = GNUNET_PEER_intern (peer);
+
+ fn = get_trust_filename (peer);
+ if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
+ (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust))))
+ cp->disk_trust = cp->trust = ntohl (trust);
+ GNUNET_free (fn);
+
GNUNET_break (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (connected_peers,
&peer->hashPubKey,
@@ -1166,6 +1209,105 @@ peer_connect_handler (void *cls,
}
+/**
+ * Increase the host credit by a value.
+ *
+ * @param host which peer to change the trust value on
+ * @param value is the int value by which the
+ * host credit is to be increased or decreased
+ * @returns the actual change in trust (positive or negative)
+ */
+static int
+change_host_trust (struct ConnectedPeer *host, int value)
+{
+ unsigned int old_trust;
+
+ if (value == 0)
+ return 0;
+ GNUNET_assert (host != NULL);
+ old_trust = host->trust;
+ if (value > 0)
+ {
+ if (host->trust + value < host->trust)
+ {
+ value = UINT32_MAX - host->trust;
+ host->trust = UINT32_MAX;
+ }
+ else
+ host->trust += value;
+ }
+ else
+ {
+ if (host->trust < -value)
+ {
+ value = -host->trust;
+ host->trust = 0;
+ }
+ else
+ host->trust += value;
+ }
+ return value;
+}
+
+
+/**
+ * Write host-trust information to a file - flush the buffer entry!
+ */
+static int
+flush_trust (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct ConnectedPeer *host = value;
+ char *fn;
+ uint32_t trust;
+ struct GNUNET_PeerIdentity pid;
+
+ if (host->trust == host->disk_trust)
+ return GNUNET_OK; /* unchanged */
+ GNUNET_PEER_resolve (host->pid,
+ &pid);
+ fn = get_trust_filename (&pid);
+ if (host->trust == 0)
+ {
+ if ((0 != UNLINK (fn)) && (errno != ENOENT))
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
+ GNUNET_ERROR_TYPE_BULK, "unlink", fn);
+ }
+ else
+ {
+ trust = htonl (host->trust);
+ if (sizeof(uint32_t) == GNUNET_DISK_fn_write (fn, &trust,
+ sizeof(uint32_t),
+ GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
+ | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ))
+ host->disk_trust = host->trust;
+ }
+ GNUNET_free (fn);
+ return GNUNET_OK;
+}
+
+/**
+ * Call this method periodically to scan data/hosts for new hosts.
+ */
+static void
+cron_flush_trust (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+
+ if (NULL == connected_peers)
+ return;
+ GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
+ &flush_trust,
+ NULL);
+ if (NULL == tc)
+ return;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+ GNUNET_SCHEDULER_add_delayed (tc->sched,
+ TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
+}
+
/**
* Free (each) request made by the peer.
@@ -1253,7 +1395,7 @@ peer_disconnect_handler (void *cls,
&consider_migration,
pos);
}
- if (cp->trust_delta > 0)
+ if (cp->trust > 0)
{
/* FIXME: push trust back to peerinfo!
(need better peerinfo API!) */
@@ -1400,6 +1542,7 @@ shutdown_task (void *cls,
while (client_list != NULL)
handle_client_disconnect (NULL,
client_list->client);
+ cron_flush_trust (NULL, NULL);
GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
&clean_peer,
NULL);
@@ -1430,6 +1573,8 @@ shutdown_task (void *cls,
dsh = NULL;
sched = NULL;
cfg = NULL;
+ GNUNET_free_non_null (trustDirectory);
+ trustDirectory = NULL;
}
@@ -2674,7 +2819,7 @@ handle_p2p_put (void *cls,
if (prq.sender != NULL)
{
prq.sender->inc_preference += CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority;
- prq.sender->trust_delta += prq.priority;
+ prq.sender->trust += prq.priority;
}
if (GNUNET_YES == active_migration)
{
@@ -2954,13 +3099,9 @@ static uint32_t
bound_priority (uint32_t prio_in,
struct ConnectedPeer *cp)
{
- if (cp->trust_delta > prio_in)
- {
- cp->trust_delta -= prio_in;
- return prio_in;
- }
- // FIXME: get out trust in the target peer from peerinfo!
- return 0;
+ /* FIXME: check if load is low and we
+ hence should not charge... */
+ return change_host_trust (cp, prio_in);
}
@@ -3510,6 +3651,7 @@ main_init (struct GNUNET_SCHEDULER_Handle *s,
NULL,
&peer_connect_handler,
&peer_disconnect_handler,
+ NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
p2p_handlers);
@@ -3543,6 +3685,17 @@ main_init (struct GNUNET_SCHEDULER_Handle *s,
GNUNET_SERVER_disconnect_notify (server,
&handle_client_disconnect,
NULL);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "fs",
+ "TRUST",
+ &trustDirectory));
+ GNUNET_DISK_directory_create (trustDirectory);
+ GNUNET_SCHEDULER_add_with_priority (sched,
+ GNUNET_SCHEDULER_PRIORITY_HIGH,
+ &cron_flush_trust, NULL);
+
+
GNUNET_SERVER_add_handlers (server, handlers);
GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_TIME_UNIT_FOREVER_REL,
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c
index ffeff0882..52c996aed 100644
--- a/src/hostlist/gnunet-daemon-hostlist.c
+++ b/src/hostlist/gnunet-daemon-hostlist.c
@@ -274,7 +274,7 @@ run (void *cls,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
- &connect_handler, &disconnect_handler,
+ &connect_handler, &disconnect_handler, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
learning? learn_handlers : no_learn_handlers);
diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c
index 58daf0401..87fae74e3 100644
--- a/src/hostlist/hostlist-server.c
+++ b/src/hostlist/hostlist-server.c
@@ -183,8 +183,7 @@ check_has_addr (void *cls,
static void
host_processor (void *cls,
const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_HELLO_Message *hello,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct HostSet *results = cls;
size_t old;
@@ -447,13 +446,11 @@ disconnect_handler (void *cls,
* @param cls closure (not used)
* @param peer potential peer to connect to
* @param hello HELLO for this peer (or NULL)
- * @param trust how much we trust the peer (not used)
*/
static void
process_notify (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct HostSet *results;
#if DEBUG_HOSTLIST_SERVER
@@ -464,7 +461,6 @@ process_notify (void *cls,
GNUNET_assert (peerinfo != NULL);
pitr = GNUNET_PEERINFO_iterate (peerinfo,
NULL,
- 0,
GNUNET_TIME_UNIT_MINUTES,
&host_processor,
results);
diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
index 96390373f..d1a04ffe8 100644
--- a/src/hostlist/test_gnunet_daemon_hostlist_learning.c
+++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
@@ -383,13 +383,13 @@ setup_learn_peer (struct PeerContext *p, const char *cfgname)
if ( NULL != filename) GNUNET_free ( filename );
p->core = GNUNET_CORE_connect (sched, p->cfg,
- GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
- NULL,
- NULL, NULL,
- NULL, GNUNET_NO,
- NULL, GNUNET_NO,
- learn_handlers );
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ NULL,
+ NULL,
+ NULL, NULL, NULL,
+ NULL, GNUNET_NO,
+ NULL, GNUNET_NO,
+ learn_handlers );
GNUNET_assert ( NULL != p->core );
p->stats = GNUNET_STATISTICS_create (sched, "hostlist", p->cfg);
GNUNET_assert ( NULL != p->stats );
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
index 069bf5202..2434e3770 100644
--- a/src/include/gnunet_core_service.h
+++ b/src/include/gnunet_core_service.h
@@ -64,6 +64,26 @@ typedef void (*GNUNET_CORE_ConnectEventHandler) (void *cls,
struct GNUNET_TIME_Relative latency,
uint32_t distance);
+/**
+ * Method called whenever a given peer has a status change.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ * @param latency reported latency of the connection with 'other'
+ * @param distance reported distance (DV) to 'other'
+ * @param bandwidth_in available amount of inbound bandwidth
+ * @param bandwidth_out available amount of outbound bandwidth
+ * @param timeout absolute time when this peer will time out
+ * unless we see some further activity from it
+ */
+typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls,
+ const struct
+ GNUNET_PeerIdentity * peer,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_TIME_Absolute timeout);
/**
@@ -166,6 +186,7 @@ typedef void
* connected to the core service; note that timeout is only meaningful if init is not NULL
* @param connects function to call on peer connect, can be NULL
* @param disconnects function to call on peer disconnect / timeout, can be NULL
+ * @param status_events function to call on peer status changes, can be NULL
* @param inbound_notify function to call for all inbound messages, can be NULL
* note that the core is allowed to drop notifications about inbound
* messages if the client does not process them fast enough (for this
@@ -201,6 +222,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
GNUNET_CORE_StartupCallback init,
GNUNET_CORE_ConnectEventHandler connects,
GNUNET_CORE_DisconnectEventHandler disconnects,
+ GNUNET_CORE_PeerStatusEventHandler status_events,
GNUNET_CORE_MessageCallback inbound_notify,
int inbound_hdr_only,
GNUNET_CORE_MessageCallback outbound_notify,
diff --git a/src/include/gnunet_peerinfo_service.h b/src/include/gnunet_peerinfo_service.h
index db5cc37ba..d88c6fb41 100644
--- a/src/include/gnunet_peerinfo_service.h
+++ b/src/include/gnunet_peerinfo_service.h
@@ -20,8 +20,7 @@
/**
* @file include/gnunet_peerinfo_service.h
* @brief Code to maintain the list of currently known hosts
- * (in memory structure of data/hosts) and their trust ratings
- * (in memory structure of data/trust)
+ * (in memory structure of data/hosts).
* @author Christian Grothoff
*/
@@ -98,13 +97,11 @@ GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
* @param cls closure
* @param peer id of the peer, NULL for last call
* @param hello hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer
*/
typedef void
(*GNUNET_PEERINFO_Processor) (void *cls,
const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_HELLO_Message * hello,
- uint32_t trust);
+ const struct GNUNET_HELLO_Message * hello);
/**
@@ -123,12 +120,11 @@ struct GNUNET_PEERINFO_IteratorContext;
* being done; however, the trust argument will be set to zero if we
* are done, 1 if we timed out and 2 for fatal error.
*
- * Instead of calling this function with 'peer == NULL' and 'trust ==
- * 0', it is often better to use 'GNUNET_PEERINFO_notify'.
+ * Instead of calling this function with 'peer == NULL'
+ * it is often better to use 'GNUNET_PEERINFO_notify'.
*
* @param h handle to the peerinfo service
* @param peer restrict iteration to this peer only (can be NULL)
- * @param trust_delta how much to change the trust in all matching peers
* @param timeout how long to wait until timing out
* @param callback the method to call for each peer
* @param callback_cls closure for callback
@@ -138,7 +134,6 @@ struct GNUNET_PEERINFO_IteratorContext;
struct GNUNET_PEERINFO_IteratorContext *
GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
const struct GNUNET_PeerIdentity *peer,
- int trust_delta,
struct GNUNET_TIME_Relative timeout,
GNUNET_PEERINFO_Processor callback,
void *callback_cls);
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index bfa1314c9..8a1df7ff9 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -52,26 +52,6 @@ extern "C"
#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE 3
-/**
- * Set a statistical value.
- */
-#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 4
-
-/**
- * Get a statistical value(s).
- */
-#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 5
-
-/**
- * Response to a STATISTICS_GET message (with value).
- */
-#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 6
-
-/**
- * Response to a STATISTICS_GET message (end of value stream).
- */
-#define GNUNET_MESSAGE_TYPE_STATISTICS_END 7
-
/**
* Request to ARM to start a service.
@@ -345,35 +325,40 @@ extern "C"
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 68
/**
+ * Notify clients about peer status change.
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE 69
+
+/**
* Notify clients about incoming P2P messages.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 69
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 70
/**
* Notify clients about outgoing P2P transmissions.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 70
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 71
/**
* Request from client to "configure" P2P connection.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 71
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 72
/**
* Response from server about (possibly updated) P2P
* connection configuration.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 72
+#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 73
/**
* Request from client with message to transmit.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_SEND 73
+#define GNUNET_MESSAGE_TYPE_CORE_SEND 74
/**
* Request from client asking to connect to a peer.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 74
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 75
/**
@@ -584,6 +569,39 @@ extern "C"
*/
#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT 160
+
+/**
+ * Set a statistical value.
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 168
+
+/**
+ * Get a statistical value(s).
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 169
+
+/**
+ * Response to a STATISTICS_GET message (with value).
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 170
+
+/**
+ * Response to a STATISTICS_GET message (end of value stream).
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_END 171
+
+/**
+ * Watch changes to a statistical value. Message format is the same
+ * as for GET, except that the subsystem and entry name must be given.
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH 172
+
+/**
+ * Changes to a watched value.
+ */
+#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE 173
+
+
/**
* Type used to match 'all' message types.
*/
diff --git a/src/include/gnunet_statistics_service.h b/src/include/gnunet_statistics_service.h
index 5c166d43d..71c834f2a 100644
--- a/src/include/gnunet_statistics_service.h
+++ b/src/include/gnunet_statistics_service.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -94,6 +94,26 @@ void GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
/**
+ * Watch statistics from the peer (be notified whenever they change).
+ * Note that the only way to cancel a "watch" request is to destroy
+ * the statistics handle given as the first argument to this call.
+ *
+ * @param handle identification of the statistics service
+ * @param subsystem limit to the specified subsystem, never NULL
+ * @param name name of the statistic value, never NULL
+ * @param proc function to call on each value
+ * @param proc_cls closure for proc
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
+ const char *subsystem,
+ const char *name,
+ GNUNET_STATISTICS_Iterator proc,
+ void *proc_cls);
+
+
+/**
* Continuation called by the "get_all" and "get" functions.
*
* @param cls closure
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index 88bca1e7d..28f2284ce 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -49,7 +49,6 @@ struct PrintContext
char **address_list;
unsigned int num_addresses;
uint32_t off;
- uint32_t trust;
};
@@ -60,9 +59,8 @@ dump_pc (struct PrintContext *pc)
unsigned int i;
GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc);
- printf (_("Peer `%s' with trust %8u\n"),
- (const char *) &enc,
- pc->trust);
+ printf (_("Peer `%s'\n"),
+ (const char *) &enc);
for (i=0;i<pc->num_addresses;i++)
{
printf ("\t%s\n",
@@ -156,13 +154,13 @@ print_address (void *cls,
/**
* Print information about the peer.
- * Currently prints the GNUNET_PeerIdentity, trust and the IP.
+ * Currently prints the GNUNET_PeerIdentity and the IP.
* Could of course do more (e.g. resolve via DNS).
*/
static void
print_peer_info (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello, uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct GNUNET_CRYPTO_HashAsciiEncoded enc;
struct PrintContext *pc;
@@ -170,22 +168,8 @@ print_peer_info (void *cls,
if (peer == NULL)
{
GNUNET_PEERINFO_disconnect (peerinfo);
- switch (trust)
- {
- case 0:
- break;
- case 1:
- fprintf (stderr,
- _("Timeout trying to interact with PEERINFO service\n"));
- break;
- case 2:
- fprintf (stderr,
- _("Error in communication with PEERINFO service\n"));
- break;
- default:
- GNUNET_break (0);
- break;
- }
+ fprintf (stderr,
+ _("Error in communication with PEERINFO service\n"));
return;
}
if (be_quiet)
@@ -196,7 +180,6 @@ print_peer_info (void *cls,
}
pc = GNUNET_malloc (sizeof (struct PrintContext));
pc->peer = *peer;
- pc->trust = trust;
GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc);
if (0 == pc->off)
{
@@ -228,27 +211,10 @@ run (void *cls,
struct GNUNET_PeerIdentity pid;
struct GNUNET_CRYPTO_HashAsciiEncoded enc;
char *fn;
- int delta;
sched = s;
cfg = c;
- delta = 0;
- if ( (args[0] != NULL) &&
- (args[1] != NULL) &&
- (1 == sscanf(args[0], "%d", &delta)) &&
- (GNUNET_OK ==
- GNUNET_CRYPTO_hash_from_string (args[1],
- &pid.hashPubKey)) )
- {
- peerinfo = GNUNET_PEERINFO_connect (sched, cfg);
- GNUNET_PEERINFO_iterate (peerinfo,
- &pid,
- delta,
- GNUNET_TIME_UNIT_SECONDS,
- &print_peer_info, NULL);
- return;
- }
- else if (args[0] != NULL)
+ if (args[0] != NULL)
{
fprintf (stderr,
_("Invalid command line argument `%s'\n"),
@@ -266,7 +232,6 @@ run (void *cls,
}
(void) GNUNET_PEERINFO_iterate (peerinfo,
NULL,
- 0,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 2),
&print_peer_info, NULL);
diff --git a/src/peerinfo-tool/test_gnunet_peerinfo.py.in b/src/peerinfo-tool/test_gnunet_peerinfo.py.in
index ba542f28a..01f76aa1e 100755
--- a/src/peerinfo-tool/test_gnunet_peerinfo.py.in
+++ b/src/peerinfo-tool/test_gnunet_peerinfo.py.in
@@ -46,12 +46,12 @@ try:
os.system ('gnunet-arm -q -i transport -c test_gnunet_peerinfo_data.conf')
os.system ('sleep 1')
pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf')
- pinfo.expect (re.compile ("Peer `.*\' with trust *0\r"));
+ pinfo.expect (re.compile ("Peer `.*\'\r"));
pinfo.expect (re.compile (" *localhost:24357\r"));
pinfo.expect (pexpect.EOF);
pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf -n')
- pinfo.expect (re.compile ("Peer `.*\' with trust *0\r"));
+ pinfo.expect (re.compile ("Peer `.*\'\r"));
pinfo.expect (re.compile (" *127..*:24357\r"));
pinfo.expect (pexpect.EOF);
@@ -59,14 +59,6 @@ try:
pid = pinfo.read (-1)
pid = pid.strip ()
- pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf 4 ' + pid)
- pinfo.expect (re.compile ("Peer `" + pid + "\' with trust *4\r"));
- pinfo.expect (pexpect.EOF);
-
- pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf -- -4 ' + pid)
- pinfo.expect (re.compile ("Peer `" + pid + "\' with trust *0\r"));
- pinfo.expect (pexpect.EOF);
-
finally:
os.system ('gnunet-arm -c test_gnunet_peerinfo_data.conf -eq')
os.system ('rm -rf /tmp/gnunet-test-peerinfo/')
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c
index 692f71e9b..ee8749955 100644
--- a/src/peerinfo/gnunet-service-peerinfo.c
+++ b/src/peerinfo/gnunet-service-peerinfo.c
@@ -23,7 +23,7 @@
* @brief maintains list of known peers
*
* Code to maintain the list of currently known hosts (in memory
- * structure of data/hosts/ and data/credit/).
+ * structure of data/hosts/).
*
* @author Christian Grothoff
*
@@ -46,11 +46,6 @@
#define DATA_HOST_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
/**
- * How often do we flush trust values to disk?
- */
-#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
-
-/**
* How often do we discard old entries in data/hosts/?
*/
#define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
@@ -76,16 +71,6 @@ struct HostEntry
*/
struct GNUNET_HELLO_Message *hello;
- /**
- * Trust rating for this peer
- */
- uint32_t trust;
-
- /**
- * Trust rating for this peer on disk.
- */
- uint32_t disk_trust;
-
};
@@ -105,11 +90,6 @@ static struct GNUNET_SERVER_NotificationContext *notify_list;
static char *networkIdDirectory;
/**
- * Where do we store trust information?
- */
-static char *trustDirectory;
-
-/**
* Handle for reporting statistics.
*/
static struct GNUNET_STATISTICS_Handle *stats;
@@ -129,7 +109,6 @@ make_info_message (const struct HostEntry *he)
im = GNUNET_malloc (sizeof (struct InfoMessage) + hs);
im->header.size = htons (hs + sizeof (struct InfoMessage));
im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
- im->trust = htonl (he->trust);
im->peer = he->identity;
if (he->hello != NULL)
memcpy (&im[1], he->hello, hs);
@@ -184,25 +163,7 @@ get_host_filename (const struct GNUNET_PeerIdentity *id)
/**
- * Get the filename under which we would store the GNUNET_HELLO_Message
- * for the given host and protocol.
- * @return filename of the form DIRECTORY/HOSTID
- */
-static char *
-get_trust_filename (const struct GNUNET_PeerIdentity *id)
-{
- struct GNUNET_CRYPTO_HashAsciiEncoded fil;
- char *fn;
-
- GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
- GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil);
- return fn;
-}
-
-
-/**
- * Find the host entry for the given peer. Call
- * only when synchronized!
+ * Find the host entry for the given peer. FIXME: replace by hash map!
* @return NULL if not found
*/
static struct HostEntry *
@@ -247,13 +208,12 @@ static void
add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
{
struct HostEntry *entry;
- char *fn;
- uint32_t trust;
char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
const struct GNUNET_HELLO_Message *hello;
struct GNUNET_HELLO_Message *hello_clean;
int size;
struct GNUNET_TIME_Absolute now;
+ char *fn;
entry = lookup_host_entry (identity);
if (entry != NULL)
@@ -264,11 +224,6 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
GNUNET_NO);
entry = GNUNET_malloc (sizeof (struct HostEntry));
entry->identity = *identity;
- fn = get_trust_filename (identity);
- if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
- (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust))))
- entry->disk_trust = entry->trust = ntohl (trust);
- GNUNET_free (fn);
fn = get_host_filename (identity);
if (GNUNET_DISK_file_test (fn) == GNUNET_YES)
@@ -302,56 +257,6 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
/**
- * Increase the host credit by a value.
- *
- * @param hostId is the identity of the host
- * @param value is the int value by which the
- * host credit is to be increased or decreased
- * @returns the actual change in trust (positive or negative)
- */
-static int
-change_host_trust (const struct GNUNET_PeerIdentity *hostId, int value)
-{
- struct HostEntry *host;
- unsigned int old_trust;
-
- if (value == 0)
- return 0;
- host = lookup_host_entry (hostId);
- if (host == NULL)
- {
- add_host_to_known_hosts (hostId);
- host = lookup_host_entry (hostId);
- }
- GNUNET_assert (host != NULL);
- old_trust = host->trust;
- if (value > 0)
- {
- if (host->trust + value < host->trust)
- {
- value = UINT32_MAX - host->trust;
- host->trust = UINT32_MAX;
- }
- else
- host->trust += value;
- }
- else
- {
- if (host->trust < -value)
- {
- value = -host->trust;
- host->trust = 0;
- }
- else
- host->trust += value;
- }
- if (host->trust != old_trust)
- notify_all (host);
- return value;
-}
-
-
-/**
* Remove a file that should not be there. LOG
* success or failure.
*/
@@ -480,16 +385,14 @@ bind_address (const struct GNUNET_PeerIdentity *peer,
/**
* Do transmit info either for only the host matching the given
- * argument or for all known hosts and change their trust values by
- * the given delta.
+ * argument or for all known hosts.
*
* @param only NULL to hit all hosts, otherwise specifies a particular target
- * @param trust_change how much should the trust be changed
* @param client who is making the request (and will thus receive our confirmation)
*/
static void
send_to_each_host (const struct GNUNET_PeerIdentity *only,
- int trust_change, struct GNUNET_SERVER_Client *client)
+ struct GNUNET_SERVER_Client *client)
{
struct HostEntry *pos;
struct InfoMessage *im;
@@ -508,7 +411,6 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
memcmp (only, &pos->identity,
sizeof (struct GNUNET_PeerIdentity))))
{
- change_host_trust (&pos->identity, trust_change);
hs = 0;
im = (struct InfoMessage *) buf;
if (pos->hello != NULL)
@@ -522,7 +424,7 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
}
im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
im->header.size = htons (sizeof (struct InfoMessage) + hs);
- im->trust = htonl (pos->trust);
+ im->reserved = htonl (0);
im->peer = pos->identity;
GNUNET_SERVER_transmit_context_append_message (tc,
&im->header);
@@ -542,58 +444,6 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
/**
- * Write host-trust information to a file - flush the buffer entry!
- * Assumes synchronized access.
- */
-static void
-flush_trust (struct HostEntry *host)
-{
- char *fn;
- uint32_t trust;
-
- if (host->trust == host->disk_trust)
- return; /* unchanged */
- fn = get_trust_filename (&host->identity);
- if (host->trust == 0)
- {
- if ((0 != UNLINK (fn)) && (errno != ENOENT))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
- GNUNET_ERROR_TYPE_BULK, "unlink", fn);
- }
- else
- {
- trust = htonl (host->trust);
- if (sizeof(uint32_t) == GNUNET_DISK_fn_write (fn, &trust,
- sizeof(uint32_t),
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
- | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ))
- host->disk_trust = host->trust;
- }
- GNUNET_free (fn);
-}
-
-/**
- * Call this method periodically to scan data/hosts for new hosts.
- */
-static void
-cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct HostEntry *pos;
-
- pos = hosts;
- while (pos != NULL)
- {
- flush_trust (pos);
- pos = pos->next;
- }
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
- GNUNET_SCHEDULER_add_delayed (tc->sched,
- TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
-}
-
-
-/**
* @brief delete expired HELLO entries in data/hosts/
*/
static int
@@ -711,7 +561,7 @@ handle_get (void *cls,
"GET",
GNUNET_i2s (&lpm->peer));
#endif
- send_to_each_host (&lpm->peer, ntohl (lpm->trust_change), client);
+ send_to_each_host (&lpm->peer, client);
}
@@ -727,15 +577,12 @@ handle_get_all (void *cls,
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- const struct ListAllPeersMessage *lpm;
-
- lpm = (const struct ListAllPeersMessage *) message;
#if DEBUG_PEERINFO
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"`%s' message received\n",
"GET_ALL");
#endif
- send_to_each_host (NULL, ntohl (lpm->trust_change), client);
+ send_to_each_host (NULL, client);
}
@@ -814,7 +661,7 @@ run (void *cls,
{&handle_get, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET,
sizeof (struct ListPeerMessage)},
{&handle_get_all, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL,
- sizeof (struct ListAllPeersMessage)},
+ sizeof (struct GNUNET_MessageHeader)},
{&handle_notify, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY,
sizeof (struct GNUNET_MessageHeader)},
{NULL, NULL, 0, 0}
@@ -826,20 +673,11 @@ run (void *cls,
"peerinfo",
"HOSTS",
&networkIdDirectory));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "peerinfo",
- "TRUST",
- &trustDirectory));
GNUNET_DISK_directory_create (networkIdDirectory);
- GNUNET_DISK_directory_create (trustDirectory);
GNUNET_SCHEDULER_add_with_priority (sched,
GNUNET_SCHEDULER_PRIORITY_IDLE,
&cron_scan_directory_data_hosts, NULL);
GNUNET_SCHEDULER_add_with_priority (sched,
- GNUNET_SCHEDULER_PRIORITY_HIGH,
- &cron_flush_trust, NULL);
- GNUNET_SCHEDULER_add_with_priority (sched,
GNUNET_SCHEDULER_PRIORITY_IDLE,
&cron_clean_data_hosts, NULL);
GNUNET_SCHEDULER_add_delayed (sched,
@@ -868,7 +706,6 @@ main (int argc, char *const *argv)
GNUNET_SERVICE_OPTION_NONE,
&run, NULL)) ? 0 : 1;
GNUNET_free_non_null (networkIdDirectory);
- GNUNET_free_non_null (trustDirectory);
return ret;
}
diff --git a/src/peerinfo/peerinfo.h b/src/peerinfo/peerinfo.h
index d8d645b13..87860097a 100644
--- a/src/peerinfo/peerinfo.h
+++ b/src/peerinfo/peerinfo.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -31,8 +31,7 @@
/**
* Message requesting a listing of all known peers,
- * possibly modified by the specified trust value
- * and restricted to the specified peer identity.
+ * possibly restricted to the specified peer identity.
*/
struct ListPeerMessage
{
@@ -43,10 +42,9 @@ struct ListPeerMessage
struct GNUNET_MessageHeader header;
/**
- * How much to change the trust in each returned peer,
- * in network byte order.
+ * Always zero.
*/
- int32_t trust_change GNUNET_PACKED;
+ uint32_t reserved GNUNET_PACKED;
/**
* Restrict to peers with this identity (optional
@@ -58,28 +56,6 @@ struct ListPeerMessage
/**
- * Message requesting a listing of all known peers,
- * possibly modified by the specified trust value
- * and restricted to the specified peer identity.
- */
-struct ListAllPeersMessage
-{
-
- /**
- * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_GET
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * How much to change the trust in each returned peer,
- * in network byte order.
- */
- int32_t trust_change GNUNET_PACKED;
-
-};
-
-
-/**
* Message used to inform the client about
* a particular peer; this message is optionally followed
* by a HELLO message for the respective peer (if available).
@@ -95,10 +71,9 @@ struct InfoMessage
struct GNUNET_MessageHeader header;
/**
- * Amount of trust we now have in the peer,
- * in network byte order.
+ * Always zero.
*/
- uint32_t trust GNUNET_PACKED;
+ uint32_t reserved GNUNET_PACKED;
/**
* About which peer are we talking here?
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c
index a1eeeb220..1f382f096 100644
--- a/src/peerinfo/peerinfo_api.c
+++ b/src/peerinfo/peerinfo_api.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2004, 2005, 2007, 2009 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -397,7 +397,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_SCHEDULER_cancel (ic->h->sched,
ic->timeout_task);
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, 1);
+ ic->callback (ic->callback_cls, NULL, NULL);
GNUNET_free (ic);
return;
}
@@ -413,7 +413,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_SCHEDULER_cancel (ic->h->sched,
ic->timeout_task);
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, 0);
+ ic->callback (ic->callback_cls, NULL, NULL);
GNUNET_free (ic);
return;
}
@@ -428,7 +428,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_SCHEDULER_cancel (ic->h->sched,
ic->timeout_task);
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, 2);
+ ic->callback (ic->callback_cls, NULL, NULL);
GNUNET_free (ic);
return;
}
@@ -446,7 +446,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_SCHEDULER_cancel (ic->h->sched,
ic->timeout_task);
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, 2);
+ ic->callback (ic->callback_cls, NULL, NULL);
GNUNET_free (ic);
return;
}
@@ -461,7 +461,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
#endif
ic->h->in_receive = GNUNET_YES;
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, &im->peer, hello, ntohl (im->trust));
+ ic->callback (ic->callback_cls, &im->peer, hello);
GNUNET_CLIENT_receive (ic->h->client,
&peerinfo_handler,
ic,
@@ -497,7 +497,7 @@ iterator_start_receive (void *cls,
reconnect (ic->h);
trigger_transmit (ic->h);
if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, 1);
+ ic->callback (ic->callback_cls, NULL, NULL);
GNUNET_free (ic);
return;
}
@@ -536,7 +536,7 @@ signal_timeout (void *cls,
GNUNET_CONTAINER_DLL_remove (ic->h->tq_head,
ic->h->tq_tail,
ic->tqe);
- ic->callback (ic->callback_cls, NULL, NULL, 1);
+ ic->callback (ic->callback_cls, NULL, NULL);
ic->callback = NULL;
if (ic->in_receive)
return;
@@ -551,16 +551,11 @@ signal_timeout (void *cls,
* host and then finally once with a NULL pointer. After that final
* invocation, the iterator context must no longer be used.
*
- * Note that the last call can be triggered by timeout or by simply
- * being done; however, the trust argument will be set to zero if we
- * are done, 1 if we timed out and 2 for fatal error.
- *
- * Instead of calling this function with 'peer == NULL' and 'trust ==
- * 0', it is often better to use 'GNUNET_PEERINFO_notify'.
+ * Instead of calling this function with 'peer == NULL' it is often
+ * better to use 'GNUNET_PEERINFO_notify'.
*
* @param h handle to the peerinfo service
* @param peer restrict iteration to this peer only (can be NULL)
- * @param trust_delta how much to change the trust in all matching peers
* @param timeout how long to wait until timing out
* @param callback the method to call for each peer
* @param callback_cls closure for callback
@@ -570,12 +565,11 @@ signal_timeout (void *cls,
struct GNUNET_PEERINFO_IteratorContext *
GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
const struct GNUNET_PeerIdentity *peer,
- int trust_delta,
struct GNUNET_TIME_Relative timeout,
GNUNET_PEERINFO_Processor callback,
void *callback_cls)
{
- struct ListAllPeersMessage *lapm;
+ struct GNUNET_MessageHeader *lapm;
struct ListPeerMessage *lpm;
struct GNUNET_PEERINFO_IteratorContext *ic;
struct TransmissionQueueEntry *tqe;
@@ -587,12 +581,11 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
"Requesting list of peers from PEERINFO service\n");
#endif
tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) +
- sizeof (struct ListAllPeersMessage));
- tqe->size = sizeof (struct ListAllPeersMessage);
- lapm = (struct ListAllPeersMessage *) &tqe[1];
- lapm->header.size = htons (sizeof (struct ListAllPeersMessage));
- lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
- lapm->trust_change = htonl (trust_delta);
+ sizeof (struct GNUNET_MessageHeader));
+ tqe->size = sizeof (struct GNUNET_MessageHeader);
+ lapm = (struct GNUNET_MessageHeader *) &tqe[1];
+ lapm->size = htons (sizeof (struct GNUNET_MessageHeader));
+ lapm->type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
}
else
{
@@ -607,7 +600,6 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
lpm = (struct ListPeerMessage *) &tqe[1];
lpm->header.size = htons (sizeof (struct ListPeerMessage));
lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
- lpm->trust_change = htonl (trust_delta);
memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
}
ic = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext));
diff --git a/src/peerinfo/peerinfo_api_notify.c b/src/peerinfo/peerinfo_api_notify.c
index 04e8baea0..c7a9c6145 100644
--- a/src/peerinfo/peerinfo_api_notify.c
+++ b/src/peerinfo/peerinfo_api_notify.c
@@ -142,7 +142,7 @@ process_notification (void *cls,
"Received information about peer `%s' from peerinfo database\n",
GNUNET_i2s (&im->peer));
#endif
- nc->callback (nc->callback_cls, &im->peer, hello, ntohl (im->trust));
+ nc->callback (nc->callback_cls, &im->peer, hello);
receive_notifications (nc);
}
diff --git a/src/peerinfo/test_peerinfo_api.c b/src/peerinfo/test_peerinfo_api.c
index dd931f4bc..47304d549 100644
--- a/src/peerinfo/test_peerinfo_api.c
+++ b/src/peerinfo/test_peerinfo_api.c
@@ -102,7 +102,7 @@ add_peer ()
static void
process (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello, uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
int *ok = cls;
unsigned int agc;
@@ -118,7 +118,6 @@ process (void *cls,
add_peer ();
ic = GNUNET_PEERINFO_iterate (h,
NULL,
- 0,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 15),
&process, cls);
@@ -126,7 +125,6 @@ process (void *cls,
}
GNUNET_assert (peer == NULL);
GNUNET_assert (2 == *ok);
- GNUNET_assert (trust == 0);
GNUNET_PEERINFO_disconnect (h);
h = NULL;
*ok = 0;
@@ -156,7 +154,6 @@ run (void *cls,
add_peer ();
ic = GNUNET_PEERINFO_iterate (h,
NULL,
- 0,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 15),
&process, cls);
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index 3ff751efe..251302a66 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -27,6 +27,7 @@
* - use BIO for IO operations
*/
#include "platform.h"
+#include "gnunet_container_lib.h"
#include "gnunet_disk_lib.h"
#include "gnunet_getopt_lib.h"
#include "gnunet_protocols.h"
@@ -37,6 +38,41 @@
#include "statistics.h"
/**
+ * Watch entry.
+ */
+struct WatchEntry
+{
+
+ struct WatchEntry *next;
+
+ struct WatchEntry *prev;
+
+ struct GNUNET_SERVER_Client *client;
+
+ uint64_t last_value;
+
+ uint32_t wid;
+
+};
+
+
+/**
+ * Client entry.
+ */
+struct ClientEntry
+{
+
+ struct ClientEntry *next;
+
+ struct ClientEntry *prev;
+
+ struct GNUNET_SERVER_Client *client;
+
+ uint32_t max_wid;
+
+};
+
+/**
* Entry in the statistics list.
*/
struct StatsEntry
@@ -66,6 +102,18 @@ struct StatsEntry
struct GNUNET_STATISTICS_SetMessage *msg;
/**
+ * Watch context for changes to this
+ * value, or NULL for none.
+ */
+ struct WatchEntry *we_head;
+
+ /**
+ * Watch context for changes to this
+ * value, or NULL for none.
+ */
+ struct WatchEntry *we_tail;
+
+ /**
* Our value.
*/
uint64_t value;
@@ -92,6 +140,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
*/
static struct StatsEntry *start;
+static struct ClientEntry *client_head;
+
+static struct ClientEntry *client_tail;
+
+/**
+ * Our notification context.
+ */
+static struct GNUNET_SERVER_NotificationContext *nc;
+
+/**
+ * Counter used to generate unique values.
+ */
+static uint32_t uidgen;
+
+
/**
* Load persistent values from disk. Disk format is
* exactly the same format that we also use for
@@ -209,7 +272,7 @@ save ()
* Transmit the given stats value.
*/
static void
-transmit (struct GNUNET_SERVER_TransmitContext *tc,
+transmit (struct GNUNET_SERVER_Client *client,
const struct StatsEntry *e)
{
struct GNUNET_STATISTICS_ReplyMessage *m;
@@ -232,10 +295,11 @@ transmit (struct GNUNET_SERVER_TransmitContext *tc,
2, e->service, e->name));
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transmitting value for `%s:%s': %llu\n",
- e->service, e->name, e->value);
+ "Transmitting value for `%s:%s' (%d): %llu\n",
+ e->service, e->name,
+ e->persistent, e->value);
#endif
- GNUNET_SERVER_transmit_context_append_message (tc, &m->header);
+ GNUNET_SERVER_notification_context_unicast (nc, client, &m->header, GNUNET_NO);
GNUNET_free (m);
}
@@ -252,6 +316,32 @@ matches (const struct StatsEntry *e, const char *service, const char *name)
}
+static struct ClientEntry *
+make_client_entry (struct GNUNET_SERVER_Client *client)
+{
+ struct ClientEntry *ce;
+
+ if (client == NULL)
+ return NULL;
+ ce = client_head;
+ while (ce != NULL)
+ {
+ if (ce->client == client)
+ return ce;
+ ce = ce->next;
+ }
+ ce = GNUNET_malloc (sizeof (struct ClientEntry));
+ ce->client = client;
+ GNUNET_SERVER_client_keep (client);
+ GNUNET_CONTAINER_DLL_insert (client_head,
+ client_tail,
+ ce);
+ GNUNET_SERVER_notification_context_add (nc,
+ client);
+ return ce;
+}
+
+
/**
* Handle GET-message.
*
@@ -266,12 +356,13 @@ handle_get (void *cls,
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
+ struct GNUNET_MessageHeader end;
char *service;
char *name;
struct StatsEntry *pos;
- struct GNUNET_SERVER_TransmitContext *tc;
size_t size;
+ make_client_entry (client);
size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
size, 2, &service, &name))
@@ -285,20 +376,51 @@ handle_get (void *cls,
"Received request for statistics on `%s:%s'\n",
strlen (service) ? service : "*", strlen (name) ? name : "*");
#endif
- tc = GNUNET_SERVER_transmit_context_create (client);
pos = start;
while (pos != NULL)
{
if (matches (pos, service, name))
- transmit (tc, pos);
+ transmit (client, pos);
pos = pos->next;
}
- GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
- GNUNET_MESSAGE_TYPE_STATISTICS_END);
- GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
+ end.size = htons (sizeof (struct GNUNET_MessageHeader));
+ end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END);
+ GNUNET_SERVER_notification_context_unicast (nc,
+ client,
+ &end,
+ GNUNET_NO);
+ GNUNET_SERVER_receive_done (client,
+ GNUNET_OK);
}
+static void
+notify_change (struct StatsEntry *se)
+{
+ struct GNUNET_STATISTICS_WatchValueMessage wvm;
+ struct WatchEntry *pos;
+
+ pos = se->we_head;
+ while (pos != NULL)
+ {
+ if (pos->last_value != se->value)
+ {
+ wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE);
+ wvm.header.size = htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage));
+ wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0);
+ wvm.wid = htonl (pos->wid);
+ wvm.reserved = htonl (0);
+ wvm.value = GNUNET_htonll (se->value);
+ GNUNET_SERVER_notification_context_unicast (nc,
+ pos->client,
+ &wvm.header,
+ GNUNET_NO);
+ pos->last_value = se->value;
+ }
+ pos = pos->next;
+ }
+}
+
/**
* Handle SET-message.
*
@@ -311,11 +433,6 @@ handle_set (void *cls,
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- /**
- * Counter used to generate unique values.
- */
- static uint32_t uidgen;
-
char *service;
char *name;
uint16_t msize;
@@ -326,7 +443,9 @@ handle_set (void *cls,
uint32_t flags;
uint64_t value;
int64_t delta;
+ int changed;
+ make_client_entry (client);
msize = ntohs (message->size);
if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage))
{
@@ -344,13 +463,15 @@ handle_set (void *cls,
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
+ flags = ntohl (msg->flags);
+ value = GNUNET_ntohll (msg->value);
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received request to update statistic on `%s:%s'\n",
- service, name);
+ "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
+ service, name,
+ (unsigned int) flags,
+ (unsigned long long) value);
#endif
- flags = ntohl (msg->flags);
- value = GNUNET_ntohll (msg->value);
pos = start;
prev = NULL;
while (pos != NULL)
@@ -359,17 +480,20 @@ handle_set (void *cls,
{
if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
{
+ changed = (pos->value != value);
pos->value = value;
}
else
{
delta = (int64_t) value;
if ((delta < 0) && (pos->value < -delta))
- {
- pos->value = 0;
+ {
+ changed = (pos->value != 0);
+ pos->value = 0;
}
else
{
+ changed = (delta != 0);
GNUNET_break ((delta <= 0) ||
(pos->value + delta > pos->value));
pos->value += delta;
@@ -391,6 +515,8 @@ handle_set (void *cls,
"Statistic `%s:%s' updated to value %llu.\n",
service, name, pos->value);
#endif
+ if (changed)
+ notify_change (pos);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
@@ -420,6 +546,86 @@ handle_set (void *cls,
/**
+ * Handle WATCH-message.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_watch (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ char *service;
+ char *name;
+ uint16_t msize;
+ uint16_t size;
+ struct StatsEntry *pos;
+ struct ClientEntry *ce;
+ struct WatchEntry *we;
+
+ ce = make_client_entry (client);
+ msize = ntohs (message->size);
+ if (msize < sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ size = msize - sizeof (struct GNUNET_MessageHeader);
+ if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
+ size, 2, &service, &name))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received request to watch statistic on `%s:%s'\n",
+ service, name);
+#endif
+ pos = start;
+ while (pos != NULL)
+ {
+ if (matches (pos, service, name))
+ break;
+ pos = pos->next;
+ }
+ if (pos == NULL)
+ {
+ pos = GNUNET_malloc (sizeof (struct StatsEntry) +
+ sizeof (struct GNUNET_STATISTICS_SetMessage) +
+ size);
+ pos->next = start;
+ pos->uid = uidgen++;
+ pos->msg = (void *) &pos[1];
+ pos->msg->header.size = htons (sizeof (struct GNUNET_STATISTICS_SetMessage) +
+ size);
+ pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
+ memcpy (pos->msg, message, ntohs (message->size));
+ pos->service = (const char *) &pos->msg[1];
+ memcpy (&pos->msg[1], service, strlen (service)+1);
+ pos->name = &pos->service[strlen (pos->service) + 1];
+ memcpy ((void*) pos->name, name, strlen (name)+1);
+ start = pos;
+ }
+ we = GNUNET_malloc (sizeof (struct WatchEntry));
+ we->client = client;
+ GNUNET_SERVER_client_keep (client);
+ we->wid = ce->max_wid++;
+ GNUNET_CONTAINER_DLL_insert (pos->we_head,
+ pos->we_tail,
+ we);
+ if (pos->value != 0)
+ notify_change (pos);
+ GNUNET_SERVER_receive_done (client,
+ GNUNET_OK);
+}
+
+
+/**
* Task run during shutdown.
*
* @param cls unused
@@ -429,7 +635,84 @@ static void
shutdown_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ struct ClientEntry *ce;
+ struct WatchEntry *we;
+ struct StatsEntry *se;
+
save ();
+ GNUNET_SERVER_notification_context_destroy (nc);
+ nc = NULL;
+ while (NULL != (ce = client_head))
+ {
+ GNUNET_SERVER_client_drop (ce->client);
+ GNUNET_CONTAINER_DLL_remove (client_head,
+ client_tail,
+ ce);
+ GNUNET_free (ce);
+ }
+ while (NULL != (se = start))
+ {
+ start = se->next;
+ while (NULL != (we = se->we_head))
+ {
+ GNUNET_SERVER_client_drop (we->client);
+ GNUNET_CONTAINER_DLL_remove (se->we_head,
+ se->we_tail,
+ we);
+ GNUNET_free (we);
+ }
+ GNUNET_free (se);
+ }
+}
+
+
+/**
+ * A client disconnected. Remove all of its data structure entries.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ */
+static void
+handle_client_disconnect (void *cls,
+ struct GNUNET_SERVER_Client
+ * client)
+{
+ struct ClientEntry *ce;
+ struct WatchEntry *we;
+ struct WatchEntry *wen;
+ struct StatsEntry *se;
+
+ ce = client_head;
+ while (NULL != ce)
+ {
+ if (ce->client == client)
+ {
+ GNUNET_SERVER_client_drop (ce->client);
+ GNUNET_CONTAINER_DLL_remove (client_head,
+ client_tail,
+ ce);
+ GNUNET_free (ce);
+ break;
+ }
+ ce = ce->next;
+ }
+ se = start;
+ while (NULL != se)
+ {
+ wen = se->we_head;
+ while (NULL != (we = wen))
+ {
+ wen = we->next;
+ if (we->client != client)
+ continue;
+ GNUNET_SERVER_client_drop (we->client);
+ GNUNET_CONTAINER_DLL_remove (se->we_head,
+ se->we_tail,
+ we);
+ GNUNET_free (we);
+ }
+ se = se->next;
+ }
}
@@ -450,10 +733,15 @@ run (void *cls,
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
{&handle_set, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_SET, 0},
{&handle_get, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_GET, 0},
+ {&handle_watch, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, 0},
{NULL, NULL, 0, 0}
};
cfg = c;
GNUNET_SERVER_add_handlers (server, handlers);
+ nc = GNUNET_SERVER_notification_context_create (server, 16);
+ GNUNET_SERVER_disconnect_notify (server,
+ &handle_client_disconnect,
+ NULL);
load (server);
GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_TIME_UNIT_FOREVER_REL,
diff --git a/src/statistics/statistics.h b/src/statistics/statistics.h
index c4a79765a..070a0aba5 100644
--- a/src/statistics/statistics.h
+++ b/src/statistics/statistics.h
@@ -91,4 +91,43 @@ struct GNUNET_STATISTICS_SetMessage
};
+
+/**
+ * Message transmitted if a watched value changes.
+ */
+struct GNUNET_STATISTICS_WatchValueMessage
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * 0 for absolute value, 1 for relative value; 2 to make persistent
+ * (see GNUNET_STATISTICS_SETFLAG_*).
+ */
+ uint32_t flags GNUNET_PACKED;
+
+ /**
+ * Unique watch identification number (watch
+ * requests are enumerated in the order they
+ * are received, the first request having
+ * a wid of zero).
+ */
+ uint32_t wid GNUNET_PACKED;
+
+ /**
+ * Reserved (always 0).
+ */
+ uint32_t reserved GNUNET_PACKED;
+
+ /**
+ * Value. Note that if this is a relative value, it will
+ * be signed even though the type given here is unsigned.
+ */
+ uint64_t value GNUNET_PACKED;
+
+};
+
+
#endif
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
index 9de9f78fd..a5dde0e55 100644
--- a/src/statistics/statistics_api.c
+++ b/src/statistics/statistics_api.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -25,6 +25,7 @@
*/
#include "platform.h"
#include "gnunet_client_lib.h"
+#include "gnunet_constants.h"
#include "gnunet_container_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_server_lib.h"
@@ -47,7 +48,37 @@ enum ActionType
{
ACTION_GET,
ACTION_SET,
- ACTION_UPDATE
+ ACTION_UPDATE,
+ ACTION_WATCH
+};
+
+
+/**
+ * Entry kept for each value we are watching.
+ */
+struct GNUNET_STATISTICS_WatchEntry
+{
+
+ /**
+ * What subsystem is this action about? (never NULL)
+ */
+ char *subsystem;
+
+ /**
+ * What value is this action about? (never NULL)
+ */
+ char *name;
+
+ /**
+ * Function to call
+ */
+ GNUNET_STATISTICS_Iterator proc;
+
+ /**
+ * Closure for proc
+ */
+ void *proc_cls;
+
};
@@ -118,7 +149,7 @@ struct GNUNET_STATISTICS_GetHandle
int aborted;
/**
- * Is this a GET, SET or UPDATE?
+ * Is this a GET, SET, UPDATE or WATCH?
*/
enum ActionType type;
@@ -179,14 +210,103 @@ struct GNUNET_STATISTICS_Handle
struct GNUNET_STATISTICS_GetHandle *current;
/**
+ * Array of watch entries.
+ */
+ struct GNUNET_STATISTICS_WatchEntry **watches;
+
+ /**
+ * Task doing exponential back-off trying to reconnect.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier backoff_task;
+
+ /**
+ * Time for next connect retry.
+ */
+ struct GNUNET_TIME_Relative backoff;
+
+ /**
+ * Size of the 'watches' array.
+ */
+ unsigned int watches_size;
+
+ /**
* Should this handle auto-destruct once all actions have
* been processed?
*/
int do_destroy;
+ /**
+ * Are we currently receiving from the service?
+ */
+ int receiving;
+
};
+
+/**
+ * Schedule the next action to be performed.
+ */
+static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
+
+/**
+ * Try to (re)connect to the statistics service.
+ *
+ * @return GNUNET_YES on success, GNUNET_NO on failure.
+ */
+static int
+try_connect (struct GNUNET_STATISTICS_Handle *ret);
+
+
+static void
+insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai)
+{
+ GNUNET_CONTAINER_DLL_insert_after (h->action_head,
+ h->action_tail,
+ h->action_tail,
+ ai);
+ if (h->action_head == ai)
+ schedule_action (h);
+}
+
+
+static void
+schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
+ struct GNUNET_STATISTICS_WatchEntry *watch)
+{
+
+ struct GNUNET_STATISTICS_GetHandle *ai;
+ size_t slen;
+ size_t nlen;
+ size_t nsize;
+
+ GNUNET_assert (h != NULL);
+ if (GNUNET_YES != try_connect (h))
+ {
+ schedule_action (h);
+ return;
+ }
+ slen = strlen (watch->subsystem) + 1;
+ nlen = strlen (watch->name) + 1;
+ nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen;
+ if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
+ ai->sh = h;
+ ai->subsystem = GNUNET_strdup (watch->subsystem);
+ ai->name = GNUNET_strdup (watch->name);
+ ai->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
+ ai->msize = nsize;
+ ai->type = ACTION_WATCH;
+ ai->proc = watch->proc;
+ ai->cls = watch->proc_cls;
+ insert_ai (h, ai);
+}
+
+
/**
* Try to (re)connect to the statistics service.
*
@@ -195,11 +315,16 @@ struct GNUNET_STATISTICS_Handle
static int
try_connect (struct GNUNET_STATISTICS_Handle *ret)
{
+ unsigned int i;
if (ret->client != NULL)
return GNUNET_YES;
ret->client = GNUNET_CLIENT_connect (ret->sched, "statistics", ret->cfg);
if (ret->client != NULL)
- return GNUNET_YES;
+ {
+ for (i=0;i<ret->watches_size;i++)
+ schedule_watch_request (ret, ret->watches[i]);
+ return GNUNET_YES;
+ }
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
_("Failed to connect to statistics service!\n"));
@@ -221,12 +346,6 @@ free_action_item (struct GNUNET_STATISTICS_GetHandle *ai)
/**
- * Schedule the next action to be performed.
- */
-static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
-
-
-/**
* GET processing is complete, tell client about it.
*/
static void
@@ -259,7 +378,13 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
uint16_t size;
if (h->current->aborted)
- return GNUNET_OK; /* don't bother */
+ {
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Iteration was aborted, ignoring VALUE\n");
+#endif
+ return GNUNET_OK; /* don't bother */
+ }
size = ntohs (msg->size);
if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage))
{
@@ -293,6 +418,42 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
#endif
h->current->aborted = GNUNET_YES;
}
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "VALUE processed successfully\n");
+#endif
+ return GNUNET_OK;
+}
+
+
+static int
+process_watch_value (struct GNUNET_STATISTICS_Handle *h,
+ const struct GNUNET_MessageHeader *msg)
+{
+ const struct GNUNET_STATISTICS_WatchValueMessage *wvm;
+ struct GNUNET_STATISTICS_WatchEntry *w;
+ uint32_t wid;
+
+ if (sizeof(struct GNUNET_STATISTICS_WatchValueMessage) !=
+ ntohs (msg->size))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *)msg;
+ wid = ntohl (wvm->wid);
+ if (wid >= h->watches_size)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ w = h->watches[wid];
+ (void) w->proc (w->proc_cls,
+ w->subsystem,
+ w->name,
+ GNUNET_ntohll (wvm->value),
+ 0 !=
+ (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
return GNUNET_OK;
}
@@ -329,21 +490,53 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received end of statistics marker\n");
#endif
+ h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
finish (h, GNUNET_OK);
+ if (h->watches_size > 0)
+ {
+ GNUNET_CLIENT_receive (h->client,
+ &receive_stats,
+ h,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ }
+ else
+ {
+ h->receiving = GNUNET_NO;
+ }
return;
case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
if (GNUNET_OK == process_message (h, msg))
{
/* finally, look for more! */
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Processing VALUE done, now reading more\n");
+#endif
GNUNET_CLIENT_receive (h->client,
&receive_stats,
h,
GNUNET_TIME_absolute_get_remaining
(h->current->timeout));
+ h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
return;
}
GNUNET_break (0);
break;
+ case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
+ if (GNUNET_OK ==
+ process_watch_value (h,
+ msg))
+ {
+ h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
+ GNUNET_assert (h->watches_size > 0);
+ GNUNET_CLIENT_receive (h->client,
+ &receive_stats,
+ h,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ return;
+ }
+ GNUNET_break (0);
+ break;
default:
GNUNET_break (0);
break;
@@ -392,15 +585,69 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
2,
handle->current->subsystem,
handle->current->name));
- GNUNET_CLIENT_receive (handle->client,
- &receive_stats,
- handle,
- GNUNET_TIME_absolute_get_remaining (handle->
- current->timeout));
+ if (! handle->receiving)
+ {
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transmission of GET done, now reading response\n");
+#endif
+ handle->receiving = GNUNET_YES;
+ GNUNET_CLIENT_receive (handle->client,
+ &receive_stats,
+ handle,
+ GNUNET_TIME_absolute_get_remaining (handle->
+ current->timeout));
+ }
return msize;
}
+/**
+ * Transmit a WATCH request (and if successful, start to receive
+ * the response).
+ */
+static size_t
+transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
+{
+ struct GNUNET_MessageHeader *hdr;
+ size_t slen1;
+ size_t slen2;
+ uint16_t msize;
+
+ if (buf == NULL)
+ {
+ /* timeout / error */
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transmission of request for statistics failed!\n");
+#endif
+ finish (handle, GNUNET_SYSERR);
+ return 0;
+ }
+ slen1 = strlen (handle->current->subsystem) + 1;
+ slen2 = strlen (handle->current->name) + 1;
+ msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
+ GNUNET_assert (msize <= size);
+ hdr = (struct GNUNET_MessageHeader *) buf;
+ hdr->size = htons (msize);
+ hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH);
+ GNUNET_assert (slen1 + slen2 ==
+ GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
+ slen1 + slen2,
+ 2,
+ handle->current->subsystem,
+ handle->current->name));
+ if (! handle->receiving)
+ {
+ handle->receiving = GNUNET_YES;
+ GNUNET_CLIENT_receive (handle->client,
+ &receive_stats,
+ handle,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ }
+ return msize;
+}
+
/**
* Transmit a SET/UPDATE request.
@@ -464,6 +711,9 @@ transmit_action (void *cls, size_t size, void *buf)
case ACTION_UPDATE:
ret = transmit_set (handle, size, buf);
break;
+ case ACTION_WATCH:
+ ret = transmit_watch (handle, size, buf);
+ break;
default:
ret = 0;
GNUNET_break (0);
@@ -495,6 +745,7 @@ GNUNET_STATISTICS_create (struct GNUNET_SCHEDULER_Handle *sched,
ret->sched = sched;
ret->cfg = cfg;
ret->subsystem = GNUNET_strdup (subsystem);
+ ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
try_connect (ret);
return ret;
}
@@ -516,7 +767,11 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
struct GNUNET_STATISTICS_GetHandle *next;
struct GNUNET_STATISTICS_GetHandle *prev;
struct GNUNET_TIME_Relative timeout;
+ int i;
+ if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task)
+ GNUNET_SCHEDULER_cancel (h->sched,
+ h->backoff_task);
if (sync_first)
{
if (h->current != NULL)
@@ -591,11 +846,30 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
GNUNET_CLIENT_disconnect (h->client, GNUNET_YES);
h->client = NULL;
}
+ for (i=0;i<h->watches_size;i++)
+ {
+ GNUNET_free (h->watches[i]->subsystem);
+ GNUNET_free (h->watches[i]->name);
+ GNUNET_free (h->watches[i]);
+ }
+ GNUNET_array_grow (h->watches,
+ h->watches_size,
+ 0);
GNUNET_free (h->subsystem);
GNUNET_free (h);
}
+static void
+finish_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_STATISTICS_Handle *h = cls;
+
+ h->backoff_task = GNUNET_SCHEDULER_NO_TASK;
+ finish (h, GNUNET_SYSERR);
+}
+
/**
* Schedule the next action to be performed.
@@ -609,7 +883,13 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
return; /* action already pending */
if (GNUNET_YES != try_connect (h))
{
- finish (h, GNUNET_SYSERR);
+ h->backoff_task = GNUNET_SCHEDULER_add_delayed (h->sched,
+ h->backoff,
+ &finish_task,
+ h);
+ h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2);
+ h->backoff = GNUNET_TIME_relative_min (h->backoff,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT);
return;
}
@@ -643,19 +923,6 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
}
}
-
-static void
-insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai)
-{
- GNUNET_CONTAINER_DLL_insert_after (h->action_head,
- h->action_tail,
- h->action_tail,
- ai);
- if (h->action_head == ai)
- schedule_action (h);
-}
-
-
/**
* Get statistic from the peer.
*
@@ -742,6 +1009,40 @@ GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
}
+/**
+ * Watch statistics from the peer (be notified whenever they change).
+ * Note that the only way to cancel a "watch" request is to destroy
+ * the statistics handle given as the first argument to this call.
+ *
+ * @param handle identification of the statistics service
+ * @param subsystem limit to the specified subsystem, never NULL
+ * @param name name of the statistic value, never NULL
+ * @param proc function to call on each value
+ * @param proc_cls closure for proc
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
+ const char *subsystem,
+ const char *name,
+ GNUNET_STATISTICS_Iterator proc,
+ void *proc_cls)
+{
+ struct GNUNET_STATISTICS_WatchEntry *w;
+
+ w = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_WatchEntry));
+ w->subsystem = GNUNET_strdup (subsystem);
+ w->name = GNUNET_strdup (name);
+ w->proc = proc;
+ w->proc_cls = proc_cls;
+ GNUNET_array_append (handle->watches,
+ handle->watches_size,
+ w);
+ schedule_watch_request (handle, w);
+ return GNUNET_OK;
+}
+
+
static void
add_setter_action (struct GNUNET_STATISTICS_Handle *h,
const char *name,
@@ -809,7 +1110,8 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
ai->type = type;
}
}
- ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
+ ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
+ ai->make_persistent = make_persistent;
return;
}
ai = ai->next;
@@ -824,7 +1126,6 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
ai->value = value;
ai->type = type;
insert_ai (h, ai);
- schedule_action (h);
}
diff --git a/src/statistics/test_statistics_api.c b/src/statistics/test_statistics_api.c
index 378e17d0c..5c55a11a6 100644
--- a/src/statistics/test_statistics_api.c
+++ b/src/statistics/test_statistics_api.c
@@ -29,7 +29,7 @@
#include "gnunet_scheduler_lib.h"
#include "gnunet_statistics_service.h"
-#define VERBOSE GNUNET_NO
+#define DEBUG_STATISTICS GNUNET_NO
#define START_SERVICE GNUNET_YES
@@ -38,6 +38,11 @@ check_1 (void *cls,
const char *subsystem,
const char *name, uint64_t value, int is_persistent)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received value %llu for `%s:%s\n",
+ (unsigned long long) value,
+ subsystem,
+ name);
GNUNET_assert (0 == strcmp (name, "test-1"));
GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
GNUNET_assert (value == 1);
@@ -50,6 +55,11 @@ check_2 (void *cls,
const char *subsystem,
const char *name, uint64_t value, int is_persistent)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received value %llu for `%s:%s\n",
+ (unsigned long long) value,
+ subsystem,
+ name);
GNUNET_assert (0 == strcmp (name, "test-2"));
GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
GNUNET_assert (value == 2);
@@ -62,6 +72,11 @@ check_3 (void *cls,
const char *subsystem,
const char *name, uint64_t value, int is_persistent)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received value %llu for `%s:%s\n",
+ (unsigned long long) value,
+ subsystem,
+ name);
GNUNET_assert (0 == strcmp (name, "test-3"));
GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
GNUNET_assert (value == 3);
@@ -85,6 +100,8 @@ static void
next (void *cls, int success)
{
GNUNET_assert (success == GNUNET_OK);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Issuing GET request\n");
GNUNET_break (NULL !=
GNUNET_STATISTICS_get (h, NULL, "test-2",
GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, cls));
@@ -102,6 +119,8 @@ run (void *cls,
GNUNET_STATISTICS_set (h, "test-2", 2, GNUNET_NO);
GNUNET_STATISTICS_set (h, "test-3", 2, GNUNET_NO);
GNUNET_STATISTICS_update (h, "test-3", 1, GNUNET_YES);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Issuing GET request\n");
GNUNET_break (NULL !=
GNUNET_STATISTICS_get (h, NULL, "test-1",
GNUNET_TIME_UNIT_SECONDS, &next, &check_1, cls));
@@ -127,6 +146,11 @@ check ()
char *const argv[] = { "test-statistics-api",
"-c",
"test_statistics_api_data.conf",
+#if DEBUG_STATISTICS
+ "-L", "DEBUG",
+#else
+ "-L", "WARNING",
+#endif
NULL
};
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -141,7 +165,7 @@ check ()
#endif
"-c", "test_statistics_api_data.conf", NULL);
#endif
- GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp",
+ GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
options, &run, &ok);
#if START_SERVICE
if (0 != PLIBC_KILL (pid, SIGTERM))
@@ -163,7 +187,7 @@ check ()
#endif
"-c", "test_statistics_api_data.conf", NULL);
#endif
- GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp",
+ GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
options, &run_more, &ok);
#if START_SERVICE
if (0 != PLIBC_KILL (pid, SIGTERM))
@@ -181,6 +205,13 @@ main (int argc, char *argv[])
{
int ret;
+ GNUNET_log_setup ("test_statistics_api",
+#if DEBUG_STATISTICS
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
ret = check ();
return ret;
diff --git a/src/statistics/test_statistics_api_data.conf b/src/statistics/test_statistics_api_data.conf
index 41cfd9596..ba8d4d68e 100644
--- a/src/statistics/test_statistics_api_data.conf
+++ b/src/statistics/test_statistics_api_data.conf
@@ -4,9 +4,12 @@ DEFAULTCONFIG = test_statistics_api_data.conf
[statistics]
PORT = 22353
+UNIXPATH = /tmp/test-statistics-service-statistics.unix
+DEBUG = YES
[arm]
PORT = 22354
DEFAULTSERVICES =
+UNIXPATH = /tmp/test-statistics-service-arm.unix
# DEBUG = YES
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c
index 6450d67d3..4701d2c84 100644
--- a/src/testing/test_testing_topology.c
+++ b/src/testing/test_testing_topology.c
@@ -443,14 +443,14 @@ init_notify_peer1 (void *cls,
* Connect to the receiving peer
*/
pos->peer2handle = GNUNET_CORE_connect (sched,
- pos->peer2->cfg,
- TIMEOUT,
- pos,
- &init_notify_peer2,
- NULL,
- NULL,
- NULL,
- GNUNET_YES, NULL, GNUNET_YES, handlers);
+ pos->peer2->cfg,
+ TIMEOUT,
+ pos,
+ &init_notify_peer2,
+ NULL,
+ NULL,
+ NULL, NULL,
+ GNUNET_YES, NULL, GNUNET_YES, handlers);
}
@@ -485,7 +485,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
TIMEOUT,
pos,
&init_notify_peer1,
- NULL,
+ NULL, NULL,
NULL,
NULL,
GNUNET_NO, NULL, GNUNET_NO, no_handlers);
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 3ccb445e4..d12892fcc 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -513,7 +513,7 @@ start_fsm (void *cls,
ARM_START_WAIT,
d,
&testing_init,
- NULL, NULL,
+ NULL, NULL, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO, no_handlers);
break;
@@ -1380,7 +1380,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
timeout,
ctx,
NULL,
- &connect_notify, NULL,
+ &connect_notify, NULL, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO, no_handlers);
if (ctx->d1core == NULL)
@@ -1442,7 +1442,7 @@ reattempt_daemons_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext
GNUNET_TIME_absolute_get_remaining(ctx->timeout),
ctx,
NULL,
- &connect_notify, NULL,
+ &connect_notify, NULL, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO, no_handlers);
if (ctx->d1core == NULL)
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index e2ae4a107..d39c89d36 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -934,13 +934,11 @@ consider_for_advertising (const struct GNUNET_HELLO_Message *hello)
* @param cls closure (not used)
* @param peer potential peer to connect to
* @param hello HELLO for this peer (or NULL)
- * @param trust how much we trust the peer (not used)
*/
static void
process_peer (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *hello,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *hello)
{
struct Peer *pos;
@@ -1404,7 +1402,8 @@ run (void *cls,
NULL,
&core_init,
&connect_notify,
- &disconnect_notify,
+ &disconnect_notify,
+ NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
handlers);
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 93f064fd0..12db541ac 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -2612,13 +2612,11 @@ add_to_foreign_address_list (void *cls,
* @param cls closure ('struct NeighbourList*')
* @param peer id of the peer, NULL for last call
* @param h hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer (not used)
*/
static void
add_hello_for_peer (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *h,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *h)
{
struct NeighbourList *n = cls;
@@ -2706,7 +2704,7 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
if (do_hello)
{
n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer,
- 0, GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_TIME_UNIT_FOREVER_REL,
&add_hello_for_peer, n);
transmit_to_peer (NULL, NULL, 0,
HELLO_ADDRESS_EXPIRATION,
@@ -3870,13 +3868,11 @@ run_validation (void *cls,
* @param cls closure
* @param peer id of the peer, NULL for last call
* @param h hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer (not used)
*/
static void
check_hello_validated (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HELLO_Message *h,
- uint32_t trust)
+ const struct GNUNET_HELLO_Message *h)
{
struct CheckHelloValidatedContext *chvc = cls;
struct GNUNET_HELLO_Message *plain_hello;
@@ -4088,7 +4084,6 @@ process_hello (struct TransportPlugin *plugin,
(continuation will then schedule actual validation) */
chvc->piter = GNUNET_PEERINFO_iterate (peerinfo,
&target,
- 0,
HELLO_VERIFICATION_TIMEOUT,
&check_hello_validated, chvc);
return GNUNET_OK;
diff --git a/src/util/server_nc.c b/src/util/server_nc.c
index 1cf3df8bd..3bab691e9 100644
--- a/src/util/server_nc.c
+++ b/src/util/server_nc.c
@@ -164,6 +164,11 @@ handle_client_disconnect (void *cls,
}
if (pos == NULL)
return;
+#if DEBUG_SERVER_NC
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client disconnected, cleaning up %u messages in NC queue\n",
+ pos->num_pending);
+#endif
if (prev == NULL)
nc->clients = pos->next;
else
@@ -285,6 +290,10 @@ transmit_message (void *cls,
if (buf == NULL)
{
/* 'cl' should be freed via disconnect notification shortly */
+#if DEBUG_SERVER_NC
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to transmit message from NC queue to client\n");
+#endif
return 0;
}
ret = 0;
@@ -310,11 +319,18 @@ transmit_message (void *cls,
cl->num_pending--;
}
if (cl->pending_head != NULL)
- cl->th = GNUNET_SERVER_notify_transmit_ready (cl->client,
- ntohs (cl->pending_head->msg->size),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &transmit_message,
- cl);
+ {
+#if DEBUG_SERVER_NC
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Have %u messages left in NC queue, will try transmission again\n",
+ cl->num_pending);
+#endif
+ cl->th = GNUNET_SERVER_notify_transmit_ready (cl->client,
+ ntohs (cl->pending_head->msg->size),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &transmit_message,
+ cl);
+ }
return ret;
}