aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
10.9.0pre1: 10.9.0pre2:
2* TRANSPORT:
3 - HTTP backend [MW]
4* CORE:
5 - derived key generation [Nils]
6* UTIL: 2* UTIL:
7 - only connect() sockets that are ready (select()) [Nils] 3 - only connect() sockets that are ready (select()) [Nils]
8 [On W32, we need to select after calling socket before doing connect etc.] 4 [On W32, we need to select after calling socket before doing connect etc.]
9* BUGS: 5* TRANSPORT:
10 Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. 6 - HTTP backend [MW]
11 (transport notified us that we connected to ourselves!!!) 7 - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616.
12 8 (transport notified us that we connected to ourselves!!!)
130.9.0pre2:
14* CORE: 9* CORE:
15 - transport-level disconnect (i.e. TCP) does not cause core-level 10 - transport-level disconnect (i.e. TCP) does not cause core-level
16 disconnect in a timely fashion (waits for connection timeout); 11 disconnect in a timely fashion (waits for connection timeout);
17 need to figure a way to make it near-instant in those cases 12 need to figure a way to make it near-instant in those cases
18 (i.e. rapid reduction in timeout on transport-level disconnect) 13 (i.e. rapid reduction in timeout on transport-level disconnect) [CG]
19 - encrypted P2P transmission (loopback) tops at 2 MB/s on my quad-core; 14 - derived key generation [Nils]
20 why is it so slow? Fix! (see core_api_reliability test)
21 - implement API to get notifications about bandwidth assignments to individual peers
22 - implement API to get notifications about updates to liveness of individual peers (before disconnect)
23* STATISTICS:
24 - implement notification-based statistics API
25* PEERINFO [CG]
26 - better API for trust management (or move into FS!?)
27* TOPOLOGY:
28 - needs more testing (especially F2F topology) & transport blacklisting
29* TBENCH: [MW]
30 - good to have for transport/DV evaluation!
31* DV: [Nate]
32 - implement performance tests (needs tbench)
33* DHT: [Nate] 15* DHT: [Nate]
34 - implement DHT service 16 - implement DHT service
35 - implement testcases 17 - implement testcases
36 - implement performance tests 18 - implement performance tests
37* MONKEY: [Safey]
38 - better crash management (attach debugging support, capture and analyze
39 debug output, detect random vs. deterministic crashes)
40* ARM: [CG]
41 - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?)
42 - discover dependencies between services
43* FS: [CG] 19* FS: [CG]
44 - trust & peerinfo integration 20 - publishing a directory sets the embedded filename to "empty"
45 - load considerations (migration, routing) 21 (likely an issue with cutting off everything before '/' in the filename,
22 which in the case of a directory would leave nothing)
23 - trust: do not charge when "idle" / load considerations (migration, routing)
46 - bound our priorities based on priorities used by other peers 24 - bound our priorities based on priorities used by other peers
47 - artificial delays
48 - active reply route caching design & implementation of service; gap extension!
49 - datastore reservation (publishing) 25 - datastore reservation (publishing)
50 - location URIs (publish, search, download)
51 - unindex on index failure 26 - unindex on index failure
27 - listing of learned namespaces
28 - collection API & tests
29 + gnunet-pseudonym (collection support)
30 - artificial delays
31 - active reply route caching design & implementation of service; gap extension!
52 - utilize in-line files in meta data always (including in search results or 32 - utilize in-line files in meta data always (including in search results or
53 when download is triggered manually and for probes); currently the data is 33 when download is triggered manually and for probes); currently the data is
54 only used when users do a general 'recursive' download 34 only used when users do a general 'recursive' download
35 - location URIs (publish, search, download)
55 - non-anonymous FS service (needs DHT) 36 - non-anonymous FS service (needs DHT)
56 + DHT integration for search 37 + DHT integration for search
57 + CS-DHT-functions (DHT-put of LOC) 38 + CS-DHT-functions (DHT-put of LOC)
58 + P2P-functions (DHT-get) 39 + P2P-functions (DHT-get)
59 - listing of learned namespaces
60 - collection API & tests
61 + gnunet-pseudonym (collection support)
62 - publishing a directory sets the embedded filename to "empty"
63 (likely an issue with cutting off everything before '/' in the filename,
64 which in the case of a directory would leave nothing)
65 - implement FS performance tests 40 - implement FS performance tests
66 + insert 41 + insert
67 + download 42 + download
@@ -101,6 +76,13 @@
101 - implement download by URI dialog; figure out where to display those downloads! 76 - implement download by URI dialog; figure out where to display those downloads!
102 - figure out where in the GUI we should show active uploads/unindex operations and allow aborts 77 - figure out where in the GUI we should show active uploads/unindex operations and allow aborts
103 - handle 'lost parent' case for recursive downloads (need to move children!) 78 - handle 'lost parent' case for recursive downloads (need to move children!)
79* MONKEY: [Safey]
80 - better crash management (attach debugging support, capture and analyze
81 debug output, detect random vs. deterministic crashes)
82* TBENCH: [MW]
83 - good to have for transport/DV evaluation!
84* DV: [Nate]
85 - implement performance tests (needs tbench)
104 86
105 87
1060.9.0pre3: 880.9.0pre3:
@@ -113,6 +95,8 @@
113 - test basic peer re-configure 95 - test basic peer re-configure
114 - consider changing API for peer-group termination to 96 - consider changing API for peer-group termination to
115 call continuation when done 97 call continuation when done
98* TOPOLOGY:
99 - needs more testing (especially F2F topology) & transport blacklisting
116* NAT/UPNP: [MW] 100* NAT/UPNP: [MW]
117 - finalize API design 101 - finalize API design
118 - code clean up 102 - code clean up
@@ -127,6 +111,10 @@
127 - use different 'priority' for probe downloads vs. normal downloads 111 - use different 'priority' for probe downloads vs. normal downloads
128* ARM: [CG/Safey] 112* ARM: [CG/Safey]
129 - better tracking of which config changes actually need to cause process restarts by ARM. 113 - better tracking of which config changes actually need to cause process restarts by ARM.
114 - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?)
115 - discover dependencies between services
116* STATISTICS:
117 - test notification-based statistics API
130* SETUP: 118* SETUP:
131 - design & implement new setup tool 119 - design & implement new setup tool
132 120
@@ -175,6 +163,8 @@
175 to track actual 'use') 163 to track actual 'use')
176 - make sue we also trigger notifications whenever HELLOs expire 164 - make sue we also trigger notifications whenever HELLOs expire
177* VPN 165* VPN
166* UTIL:
167 - allow limiting UNIX socket access by UID/GID
178 168
179 169
180 170
@@ -193,6 +183,9 @@ Optimizations:
193 (theoretically reduces overhead; bounds messgae queue size) 183 (theoretically reduces overhead; bounds messgae queue size)
194* FS: 184* FS:
195 - use different queue prioritization for probe-downloads vs. normal downloads (!?) 185 - use different queue prioritization for probe-downloads vs. normal downloads (!?)
186* CORE:
187 - encrypted P2P transmission (loopback) tops at 2 MB/s on my quad-core;
188 why is it so slow? Fix! (see core_api_reliability test)
196 189
197Minor features: 190Minor features:
198* TCP: 191* 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
107# REJECT_FROM6 = 107# REJECT_FROM6 =
108# PREFIX = 108# PREFIX =
109HOSTS = $SERVICEHOME/data/hosts/ 109HOSTS = $SERVICEHOME/data/hosts/
110TRUST = $SERVICEHOME/data/credit/
111 110
112 111
113[transport] 112[transport]
@@ -201,6 +200,7 @@ FILENAME = $SERVICEHOME/datastore/sqlite.db
201[fs] 200[fs]
202AUTOSTART = YES 201AUTOSTART = YES
203INDEXDB = $SERVICEHOME/idxinfo.lst 202INDEXDB = $SERVICEHOME/idxinfo.lst
203TRUST = $SERVICEHOME/data/credit/
204IDENTITY_DIR = $SERVICEHOME/identities/ 204IDENTITY_DIR = $SERVICEHOME/identities/
205STATE_DIR = $SERVICEHOME/persistence/ 205STATE_DIR = $SERVICEHOME/persistence/
206PORT = 2094 206PORT = 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.
10 10
11.SH DESCRIPTION 11.SH DESCRIPTION
12.PP 12.PP
13\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. 13\fBgnunet\-peerinfo\fP display the known addresses and trust of known peers.
14 14
15.SH OPTIONS 15.SH OPTIONS
16.B 16.B
@@ -35,16 +35,6 @@ Print the version number
35.IP "\-L LOGLEVEL, \-\-loglelvel=LOGLEVEL" 35.IP "\-L LOGLEVEL, \-\-loglelvel=LOGLEVEL"
36Set the loglevel 36Set the loglevel
37 37
38.SH EXAMPLE
39.TP
40gnunet\-peerinfo 4 S9LBDF6V770H8CELVKBFJMOTS25LB272JB81MRJHSRJI9B1FBVOSGJVSEIRIS5J4SRDU4HT3TBPLM4MNEND7FFUHMGCK4NBR8R2UTSG
41Increase the trust in a peer by 4
42.TP
43gnunet\-peerinfo \-\- \-2 S9LBDF6V770H8CELVKBFJMOTS25LB272JB81MRJHSRJI9B1FBVOSGJVSEIRIS5J4SRDU4HT3TBPLM4MNEND7FFUHMGCK4NBR8R2UTSG
44Decrease the trust in a peer by 2
45
46
47
48 38
49.SH BUGS 39.SH BUGS
50Report bugs by using mantis <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org> 40Report 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 @@
1#! /bin/sh 1#! /bin/sh
2# mkinstalldirs --- make directory hierarchy 2# mkinstalldirs --- make directory hierarchy
3 3
4scriptversion=2009-04-28.21; # UTC 4scriptversion=2006-05-11.19
5 5
6# Original author: Noah Friedman <friedman@prep.ai.mit.edu> 6# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
7# Created: 1993-05-16 7# Created: 1993-05-16
@@ -157,6 +157,5 @@ exit $errstatus
157# eval: (add-hook 'write-file-hooks 'time-stamp) 157# eval: (add-hook 'write-file-hooks 'time-stamp)
158# time-stamp-start: "scriptversion=" 158# time-stamp-start: "scriptversion="
159# time-stamp-format: "%:y-%02m-%02d.%02H" 159# time-stamp-format: "%:y-%02m-%02d.%02H"
160# time-stamp-time-zone: "UTC" 160# time-stamp-end: "$"
161# time-stamp-end: "; # UTC"
162# End: 161# 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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -23,6 +23,7 @@
23 * @brief common internal definitions for core service 23 * @brief common internal definitions for core service
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "gnunet_bandwidth_lib.h"
26#include "gnunet_crypto_lib.h" 27#include "gnunet_crypto_lib.h"
27#include "gnunet_time_lib.h" 28#include "gnunet_time_lib.h"
28 29
@@ -45,10 +46,11 @@
45#define GNUNET_CORE_OPTION_NOTHING 0 46#define GNUNET_CORE_OPTION_NOTHING 0
46#define GNUNET_CORE_OPTION_SEND_CONNECT 1 47#define GNUNET_CORE_OPTION_SEND_CONNECT 1
47#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2 48#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2
48#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 4 49#define GNUNET_CORE_OPTION_SEND_STATUS_CHANGE 4
49#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 8 50#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8
50#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 16 51#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16
51#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 32 52#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32
53#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64
52 54
53 55
54/** 56/**
@@ -100,13 +102,12 @@ struct InitReplyMessage
100 102
101/** 103/**
102 * Message sent by the service to clients to notify them 104 * Message sent by the service to clients to notify them
103 * about a peer connecting or disconnecting. 105 * about a peer connecting.
104 */ 106 */
105struct ConnectNotifyMessage 107struct ConnectNotifyMessage
106{ 108{
107 /** 109 /**
108 * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT 110 * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
109 * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT.
110 */ 111 */
111 struct GNUNET_MessageHeader header; 112 struct GNUNET_MessageHeader header;
112 113
@@ -128,6 +129,49 @@ struct ConnectNotifyMessage
128}; 129};
129 130
130 131
132/**
133 * Message sent by the service to clients to notify them
134 * about a peer changing status.
135 */
136struct PeerStatusNotifyMessage
137{
138 /**
139 * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PEER_STATUS
140 */
141 struct GNUNET_MessageHeader header;
142
143 /**
144 * Distance to the peer.
145 */
146 uint32_t distance GNUNET_PACKED;
147
148 /**
149 * Currently observed latency.
150 */
151 struct GNUNET_TIME_RelativeNBO latency;
152
153 /**
154 * When the peer would time out (unless we see activity)
155 */
156 struct GNUNET_TIME_AbsoluteNBO timeout;
157
158 /**
159 * Available bandwidth from the peer.
160 */
161 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
162
163 /**
164 * Available bandwidth to the peer.
165 */
166 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
167
168 /**
169 * Identity of the peer.
170 */
171 struct GNUNET_PeerIdentity peer;
172
173};
174
131 175
132/** 176/**
133 * Message sent by the service to clients to notify them 177 * 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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -67,6 +67,11 @@ struct GNUNET_CORE_Handle
67 GNUNET_CORE_DisconnectEventHandler disconnects; 67 GNUNET_CORE_DisconnectEventHandler disconnects;
68 68
69 /** 69 /**
70 * Function to call whenever we're notified about a peer changing status.
71 */
72 GNUNET_CORE_PeerStatusEventHandler status_events;
73
74 /**
70 * Function to call whenever we receive an inbound message. 75 * Function to call whenever we receive an inbound message.
71 */ 76 */
72 GNUNET_CORE_MessageCallback inbound_notify; 77 GNUNET_CORE_MessageCallback inbound_notify;
@@ -381,6 +386,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
381 const struct DisconnectNotifyMessage *dnm; 386 const struct DisconnectNotifyMessage *dnm;
382 const struct NotifyTrafficMessage *ntm; 387 const struct NotifyTrafficMessage *ntm;
383 const struct GNUNET_MessageHeader *em; 388 const struct GNUNET_MessageHeader *em;
389 const struct PeerStatusNotifyMessage *psnm;
384 uint16_t msize; 390 uint16_t msize;
385 uint16_t et; 391 uint16_t et;
386 const struct GNUNET_CORE_MessageHandler *mh; 392 const struct GNUNET_CORE_MessageHandler *mh;
@@ -433,6 +439,26 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
433 h->disconnects (h->cls, 439 h->disconnects (h->cls,
434 &dnm->peer); 440 &dnm->peer);
435 break; 441 break;
442 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
443 if (NULL == h->status_events)
444 {
445 GNUNET_break (0);
446 break;
447 }
448 if (msize != sizeof (struct PeerStatusNotifyMessage))
449 {
450 GNUNET_break (0);
451 break;
452 }
453 psnm = (const struct PeerStatusNotifyMessage *) msg;
454 h->status_events (h->cls,
455 &psnm->peer,
456 GNUNET_TIME_relative_ntoh (psnm->latency),
457 ntohl (psnm->distance),
458 psnm->bandwidth_in,
459 psnm->bandwidth_out,
460 GNUNET_TIME_absolute_ntoh (psnm->timeout));
461 break;
436 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND: 462 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
437 if (msize < 463 if (msize <
438 sizeof (struct NotifyTrafficMessage) + 464 sizeof (struct NotifyTrafficMessage) +
@@ -658,6 +684,8 @@ transmit_start (void *cls, size_t size, void *buf)
658 opt |= GNUNET_CORE_OPTION_SEND_CONNECT; 684 opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
659 if (h->disconnects != NULL) 685 if (h->disconnects != NULL)
660 opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT; 686 opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
687 if (h->status_events != NULL)
688 opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
661 if (h->inbound_notify != NULL) 689 if (h->inbound_notify != NULL)
662 { 690 {
663 if (h->inbound_hdr_only) 691 if (h->inbound_hdr_only)
@@ -717,6 +745,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
717 GNUNET_CORE_StartupCallback init, 745 GNUNET_CORE_StartupCallback init,
718 GNUNET_CORE_ConnectEventHandler connects, 746 GNUNET_CORE_ConnectEventHandler connects,
719 GNUNET_CORE_DisconnectEventHandler disconnects, 747 GNUNET_CORE_DisconnectEventHandler disconnects,
748 GNUNET_CORE_PeerStatusEventHandler status_events,
720 GNUNET_CORE_MessageCallback inbound_notify, 749 GNUNET_CORE_MessageCallback inbound_notify,
721 int inbound_hdr_only, 750 int inbound_hdr_only,
722 GNUNET_CORE_MessageCallback outbound_notify, 751 GNUNET_CORE_MessageCallback outbound_notify,
@@ -732,6 +761,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
732 h->init = init; 761 h->init = init;
733 h->connects = connects; 762 h->connects = connects;
734 h->disconnects = disconnects; 763 h->disconnects = disconnects;
764 h->status_events = status_events;
735 h->inbound_notify = inbound_notify; 765 h->inbound_notify = inbound_notify;
736 h->outbound_notify = outbound_notify; 766 h->outbound_notify = outbound_notify;
737 h->inbound_hdr_only = inbound_hdr_only; 767 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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 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,
830 830
831 831
832/** 832/**
833 * Function called by transport telling us that a peer
834 * changed status.
835 *
836 * @param peer the peer that changed status
837 */
838static void
839handle_peer_status_change (struct Neighbour *n)
840{
841 struct PeerStatusNotifyMessage psnm;
842
843 if (! n->is_connected)
844 return;
845#if DEBUG_CORE
846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
847 "Peer `%4s' changed status\n",
848 GNUNET_i2s (peer));
849#endif
850 psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
851 psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
852 psnm.distance = htonl (n->last_distance);
853 psnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
854 psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity,
855 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
856 psnm.bandwidth_in = n->bw_in;
857 psnm.bandwidth_out = n->bw_out;
858 psnm.peer = n->peer;
859 send_to_all_clients (&psnm.header,
860 GNUNET_YES,
861 GNUNET_CORE_OPTION_SEND_STATUS_CHANGE);
862 GNUNET_STATISTICS_update (stats,
863 gettext_noop ("# peer status changes"),
864 1,
865 GNUNET_NO);
866}
867
868
869/**
833 * Handle CORE_INIT request. 870 * Handle CORE_INIT request.
834 */ 871 */
835static void 872static void
@@ -997,16 +1034,21 @@ handle_client_request_info (void *cls,
997 if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__) 1034 if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__)
998 { 1035 {
999 n->bw_out_internal_limit = rcm->limit_outbound; 1036 n->bw_out_internal_limit = rcm->limit_outbound;
1000 n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit, 1037 if (n->bw_out.value__ != GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1001 n->bw_out_external_limit); 1038 n->bw_out_external_limit).value__)
1002 GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window, 1039 {
1003 n->bw_out); 1040 n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1004 GNUNET_TRANSPORT_set_quota (transport, 1041 n->bw_out_external_limit);
1005 &n->peer, 1042 GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
1006 n->bw_in, 1043 n->bw_out);
1007 n->bw_out, 1044 GNUNET_TRANSPORT_set_quota (transport,
1008 GNUNET_TIME_UNIT_FOREVER_REL, 1045 &n->peer,
1009 NULL, NULL); 1046 n->bw_in,
1047 n->bw_out,
1048 GNUNET_TIME_UNIT_FOREVER_REL,
1049 NULL, NULL);
1050 handle_peer_status_change (n);
1051 }
1010 } 1052 }
1011 if (want_reserv < 0) 1053 if (want_reserv < 0)
1012 { 1054 {
@@ -2359,13 +2401,11 @@ handle_client_request_connect (void *cls,
2359 * @param cls the 'struct Neighbour' to retry sending the key for 2401 * @param cls the 'struct Neighbour' to retry sending the key for
2360 * @param peer the peer for which this is the HELLO 2402 * @param peer the peer for which this is the HELLO
2361 * @param hello HELLO message of that peer 2403 * @param hello HELLO message of that peer
2362 * @param trust amount of trust we currently have in that peer
2363 */ 2404 */
2364static void 2405static void
2365process_hello_retry_send_key (void *cls, 2406process_hello_retry_send_key (void *cls,
2366 const struct GNUNET_PeerIdentity *peer, 2407 const struct GNUNET_PeerIdentity *peer,
2367 const struct GNUNET_HELLO_Message *hello, 2408 const struct GNUNET_HELLO_Message *hello)
2368 uint32_t trust)
2369{ 2409{
2370 struct Neighbour *n = cls; 2410 struct Neighbour *n = cls;
2371 2411
@@ -2516,7 +2556,6 @@ send_key (struct Neighbour *n)
2516 GNUNET_assert (n->pitr == NULL); 2556 GNUNET_assert (n->pitr == NULL);
2517 n->pitr = GNUNET_PEERINFO_iterate (peerinfo, 2557 n->pitr = GNUNET_PEERINFO_iterate (peerinfo,
2518 &n->peer, 2558 &n->peer,
2519 0,
2520 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20), 2559 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20),
2521 &process_hello_retry_send_key, n); 2560 &process_hello_retry_send_key, n);
2522 return; 2561 return;
@@ -2666,13 +2705,11 @@ handle_set_key (struct Neighbour *n,
2666 * @param cls pointer to the set key message 2705 * @param cls pointer to the set key message
2667 * @param peer the peer for which this is the HELLO 2706 * @param peer the peer for which this is the HELLO
2668 * @param hello HELLO message of that peer 2707 * @param hello HELLO message of that peer
2669 * @param trust amount of trust we currently have in that peer
2670 */ 2708 */
2671static void 2709static void
2672process_hello_retry_handle_set_key (void *cls, 2710process_hello_retry_handle_set_key (void *cls,
2673 const struct GNUNET_PeerIdentity *peer, 2711 const struct GNUNET_PeerIdentity *peer,
2674 const struct GNUNET_HELLO_Message *hello, 2712 const struct GNUNET_HELLO_Message *hello)
2675 uint32_t trust)
2676{ 2713{
2677 struct Neighbour *n = cls; 2714 struct Neighbour *n = cls;
2678 struct SetKeyMessage *sm = n->skm; 2715 struct SetKeyMessage *sm = n->skm;
@@ -2922,6 +2959,7 @@ handle_pong (struct Neighbour *n,
2922 GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2), 2959 GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
2923 &send_keep_alive, 2960 &send_keep_alive,
2924 n); 2961 n);
2962 handle_peer_status_change (n);
2925 break; 2963 break;
2926 default: 2964 default:
2927 GNUNET_break (0); 2965 GNUNET_break (0);
@@ -2974,7 +3012,6 @@ handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2974 n->skm = m_cpy; 3012 n->skm = m_cpy;
2975 n->pitr = GNUNET_PEERINFO_iterate (peerinfo, 3013 n->pitr = GNUNET_PEERINFO_iterate (peerinfo,
2976 &n->peer, 3014 &n->peer,
2977 0,
2978 GNUNET_TIME_UNIT_MINUTES, 3015 GNUNET_TIME_UNIT_MINUTES,
2979 &process_hello_retry_handle_set_key, n); 3016 &process_hello_retry_handle_set_key, n);
2980 GNUNET_STATISTICS_update (stats, 3017 GNUNET_STATISTICS_update (stats,
@@ -3364,7 +3401,8 @@ handle_encrypted_message (struct Neighbour *n,
3364 GNUNET_STATISTICS_set (stats, 3401 GNUNET_STATISTICS_set (stats,
3365 gettext_noop ("# bytes of payload decrypted"), 3402 gettext_noop ("# bytes of payload decrypted"),
3366 size - sizeof (struct EncryptedMessage), 3403 size - sizeof (struct EncryptedMessage),
3367 GNUNET_NO); 3404 GNUNET_NO);
3405 handle_peer_status_change (n);
3368 if (GNUNET_OK != GNUNET_SERVER_mst_receive (mst, 3406 if (GNUNET_OK != GNUNET_SERVER_mst_receive (mst,
3369 n, 3407 n,
3370 &buf[sizeof (struct EncryptedMessage)], 3408 &buf[sizeof (struct EncryptedMessage)],
@@ -3396,6 +3434,7 @@ handle_transport_receive (void *cls,
3396 int up; 3434 int up;
3397 uint16_t type; 3435 uint16_t type;
3398 uint16_t size; 3436 uint16_t size;
3437 int changed;
3399 3438
3400#if DEBUG_CORE 3439#if DEBUG_CORE
3401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3411,6 +3450,7 @@ handle_transport_receive (void *cls,
3411 n = find_neighbour (peer); 3450 n = find_neighbour (peer);
3412 if (n == NULL) 3451 if (n == NULL)
3413 n = create_neighbour (peer); 3452 n = create_neighbour (peer);
3453 changed = (latency.value != n->last_latency.value) || (distance != n->last_distance);
3414 n->last_latency = latency; 3454 n->last_latency = latency;
3415 n->last_distance = distance; 3455 n->last_distance = distance;
3416 up = (n->status == PEER_STATE_KEY_CONFIRMED); 3456 up = (n->status == PEER_STATE_KEY_CONFIRMED);
@@ -3496,6 +3536,7 @@ handle_transport_receive (void *cls,
3496 { 3536 {
3497 now = GNUNET_TIME_absolute_get (); 3537 now = GNUNET_TIME_absolute_get ();
3498 n->last_activity = now; 3538 n->last_activity = now;
3539 changed = GNUNET_YES;
3499 if (!up) 3540 if (!up)
3500 { 3541 {
3501 GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), 1, GNUNET_NO); 3542 GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), 1, GNUNET_NO);
@@ -3509,6 +3550,8 @@ handle_transport_receive (void *cls,
3509 &send_keep_alive, 3550 &send_keep_alive,
3510 n); 3551 n);
3511 } 3552 }
3553 if (changed)
3554 handle_peer_status_change (n);
3512} 3555}
3513 3556
3514 3557
@@ -3591,6 +3634,7 @@ neighbour_quota_update (void *cls,
3591 n->bw_out, 3634 n->bw_out,
3592 GNUNET_TIME_UNIT_FOREVER_REL, 3635 GNUNET_TIME_UNIT_FOREVER_REL,
3593 NULL, NULL); 3636 NULL, NULL);
3637 handle_peer_status_change (n);
3594 } 3638 }
3595 schedule_quota_update (n); 3639 schedule_quota_update (n);
3596} 3640}
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,
228 &init_notify, 228 &init_notify,
229 &connect_notify, 229 &connect_notify,
230 &disconnect_notify, 230 &disconnect_notify,
231 NULL,
231 &inbound_notify, 232 &inbound_notify,
232 GNUNET_YES, 233 GNUNET_YES,
233 &outbound_notify, GNUNET_YES, handlers); 234 &outbound_notify, GNUNET_YES, handlers);
@@ -321,6 +322,7 @@ run (void *cls,
321 &init_notify, 322 &init_notify,
322 &connect_notify, 323 &connect_notify,
323 &disconnect_notify, 324 &disconnect_notify,
325 NULL,
324 &inbound_notify, 326 &inbound_notify,
325 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); 327 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
326} 328}
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,
375 &init_notify, 375 &init_notify,
376 &connect_notify, 376 &connect_notify,
377 &disconnect_notify, 377 &disconnect_notify,
378 NULL,
378 &inbound_notify, 379 &inbound_notify,
379 GNUNET_YES, 380 GNUNET_YES,
380 &outbound_notify, GNUNET_YES, handlers); 381 &outbound_notify, GNUNET_YES, handlers);
@@ -468,6 +469,7 @@ run (void *cls,
468 &init_notify, 469 &init_notify,
469 &connect_notify, 470 &connect_notify,
470 &disconnect_notify, 471 &disconnect_notify,
472 NULL,
471 &inbound_notify, 473 &inbound_notify,
472 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); 474 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
473} 475}
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,
133 &init_notify, 133 &init_notify,
134 &connect_notify, 134 &connect_notify,
135 &disconnect_notify, 135 &disconnect_notify,
136 NULL,
136 &inbound_notify, 137 &inbound_notify,
137 GNUNET_YES, 138 GNUNET_YES,
138 &outbound_notify, GNUNET_YES, handlers); 139 &outbound_notify, GNUNET_YES, handlers);
@@ -182,6 +183,7 @@ run (void *cls,
182 &init_notify, 183 &init_notify,
183 &connect_notify, 184 &connect_notify,
184 &disconnect_notify, 185 &disconnect_notify,
186 NULL,
185 &inbound_notify, 187 &inbound_notify,
186 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); 188 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
187} 189}
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,
834 &core_init, /* Call core_init once connected */ 834 &core_init, /* Call core_init once connected */
835 &handle_core_connect, /* Don't care about connects */ 835 &handle_core_connect, /* Don't care about connects */
836 NULL, /* Don't care about disconnects */ 836 NULL, /* Don't care about disconnects */
837 NULL, /* Don't care about peer status changes */
837 NULL, /* Don't want notified about all incoming messages */ 838 NULL, /* Don't want notified about all incoming messages */
838 GNUNET_NO, /* For header only inbound notification */ 839 GNUNET_NO, /* For header only inbound notification */
839 NULL, /* Don't want notified about all outbound messages */ 840 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,
2755 * @param cls closure 2755 * @param cls closure
2756 * @param peer id of the peer, NULL for last call 2756 * @param peer id of the peer, NULL for last call
2757 * @param hello hello message for the peer (can be NULL) 2757 * @param hello hello message for the peer (can be NULL)
2758 * @param trust amount of trust we have in the peer
2759 */ 2758 */
2760static void 2759static void
2761process_peerinfo (void *cls, 2760process_peerinfo (void *cls,
2762 const struct GNUNET_PeerIdentity *peer, 2761 const struct GNUNET_PeerIdentity *peer,
2763 const struct GNUNET_HELLO_Message *hello, uint32_t trust) 2762 const struct GNUNET_HELLO_Message *hello)
2764{ 2763{
2765 struct PeerIteratorContext *peerinfo_iterator = cls; 2764 struct PeerIteratorContext *peerinfo_iterator = cls;
2766 struct DirectNeighbor *neighbor = peerinfo_iterator->neighbor; 2765 struct DirectNeighbor *neighbor = peerinfo_iterator->neighbor;
@@ -2779,7 +2778,6 @@ process_peerinfo (void *cls,
2779#endif 2778#endif
2780 peerinfo_iterator->ic = GNUNET_PEERINFO_iterate(peerinfo_handle, 2779 peerinfo_iterator->ic = GNUNET_PEERINFO_iterate(peerinfo_handle,
2781 &peerinfo_iterator->neighbor->identity, 2780 &peerinfo_iterator->neighbor->identity,
2782 0,
2783 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3), 2781 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
2784 &process_peerinfo, 2782 &process_peerinfo,
2785 peerinfo_iterator); 2783 peerinfo_iterator);
@@ -2856,7 +2854,6 @@ void handle_core_connect (void *cls,
2856 peerinfo_iterator->neighbor = neighbor; 2854 peerinfo_iterator->neighbor = neighbor;
2857 peerinfo_iterator->ic = GNUNET_PEERINFO_iterate (peerinfo_handle, 2855 peerinfo_iterator->ic = GNUNET_PEERINFO_iterate (peerinfo_handle,
2858 peer, 2856 peer,
2859 0,
2860 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3), 2857 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
2861 &process_peerinfo, 2858 &process_peerinfo,
2862 peerinfo_iterator); 2859 peerinfo_iterator);
@@ -2988,6 +2985,7 @@ run (void *cls,
2988 &core_init, 2985 &core_init,
2989 &handle_core_connect, 2986 &handle_core_connect,
2990 &handle_core_disconnect, 2987 &handle_core_disconnect,
2988 NULL,
2991 NULL, 2989 NULL,
2992 GNUNET_NO, 2990 GNUNET_NO,
2993 NULL, 2991 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,
534 * Connect to the receiving peer 534 * Connect to the receiving peer
535 */ 535 */
536 pos->peer2handle = GNUNET_CORE_connect (sched, 536 pos->peer2handle = GNUNET_CORE_connect (sched,
537 pos->peer2->cfg, 537 pos->peer2->cfg,
538 TIMEOUT, 538 TIMEOUT,
539 pos, 539 pos,
540 &init_notify_peer2, 540 &init_notify_peer2,
541 NULL, 541 NULL,
542 NULL, 542 NULL,
543 NULL, 543 NULL, NULL,
544 GNUNET_YES, NULL, GNUNET_YES, handlers); 544 GNUNET_YES, NULL, GNUNET_YES, handlers);
545 545
546} 546}
547 547
@@ -578,7 +578,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
578 TIMEOUT, 578 TIMEOUT,
579 pos, 579 pos,
580 &init_notify_peer1, 580 &init_notify_peer1,
581 NULL, 581 NULL, NULL,
582 NULL, 582 NULL,
583 NULL, 583 NULL,
584 GNUNET_NO, NULL, GNUNET_NO, no_handlers); 584 GNUNET_NO, NULL, GNUNET_NO, no_handlers);
@@ -893,7 +893,7 @@ peers_started_callback (void *cls,
893 GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 893 GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
894 894
895 new_peer = GNUNET_malloc(sizeof(struct PeerContext)); 895 new_peer = GNUNET_malloc(sizeof(struct PeerContext));
896 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); 896 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);
897 new_peer->daemon = d; 897 new_peer->daemon = d;
898 new_peer->next = all_peers; 898 new_peer->next = all_peers;
899 all_peers = new_peer; 899 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 @@
55#define MAX_QUEUE_PER_PEER 16 55#define MAX_QUEUE_PER_PEER 16
56 56
57/** 57/**
58 * How often do we flush trust values to disk?
59 */
60#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
61
62
63/**
58 * Inverse of the probability that we will submit the same query 64 * Inverse of the probability that we will submit the same query
59 * to the same peer again. If the same peer already got the query 65 * to the same peer again. If the same peer already got the query
60 * repeatedly recently, the probability is multiplied by the inverse 66 * repeatedly recently, the probability is multiplied by the inverse
@@ -211,9 +217,14 @@ struct ConnectedPeer
211 uint64_t inc_preference; 217 uint64_t inc_preference;
212 218
213 /** 219 /**
214 * Trust delta to still commit to the system. 220 * Trust rating for this peer
215 */ 221 */
216 uint32_t trust_delta; 222 uint32_t trust;
223
224 /**
225 * Trust rating for this peer on disk.
226 */
227 uint32_t disk_trust;
217 228
218 /** 229 /**
219 * The peer's identity. 230 * The peer's identity.
@@ -680,6 +691,11 @@ static struct MigrationReadyBlock *mig_tail;
680static struct GNUNET_DATASTORE_QueueEntry *mig_qe; 691static struct GNUNET_DATASTORE_QueueEntry *mig_qe;
681 692
682/** 693/**
694 * Where do we store trust information?
695 */
696static char *trustDirectory;
697
698/**
683 * ID of task that collects blocks for migration. 699 * ID of task that collects blocks for migration.
684 */ 700 */
685static GNUNET_SCHEDULER_TaskIdentifier mig_task; 701static GNUNET_SCHEDULER_TaskIdentifier mig_task;
@@ -702,6 +718,24 @@ static int active_migration;
702 718
703 719
704/** 720/**
721 * Get the filename under which we would store the GNUNET_HELLO_Message
722 * for the given host and protocol.
723 * @return filename of the form DIRECTORY/HOSTID
724 */
725static char *
726get_trust_filename (const struct GNUNET_PeerIdentity *id)
727{
728 struct GNUNET_CRYPTO_HashAsciiEncoded fil;
729 char *fn;
730
731 GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
732 GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil);
733 return fn;
734}
735
736
737
738/**
705 * Transmit messages by copying it to the target buffer 739 * Transmit messages by copying it to the target buffer
706 * "buf". "buf" will be NULL and "size" zero if the socket was closed 740 * "buf". "buf" will be NULL and "size" zero if the socket was closed
707 * for writing in the meantime. In that case, do nothing 741 * for writing in the meantime. In that case, do nothing
@@ -1148,9 +1182,18 @@ peer_connect_handler (void *cls,
1148{ 1182{
1149 struct ConnectedPeer *cp; 1183 struct ConnectedPeer *cp;
1150 struct MigrationReadyBlock *pos; 1184 struct MigrationReadyBlock *pos;
1185 char *fn;
1186 uint32_t trust;
1151 1187
1152 cp = GNUNET_malloc (sizeof (struct ConnectedPeer)); 1188 cp = GNUNET_malloc (sizeof (struct ConnectedPeer));
1153 cp->pid = GNUNET_PEER_intern (peer); 1189 cp->pid = GNUNET_PEER_intern (peer);
1190
1191 fn = get_trust_filename (peer);
1192 if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
1193 (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust))))
1194 cp->disk_trust = cp->trust = ntohl (trust);
1195 GNUNET_free (fn);
1196
1154 GNUNET_break (GNUNET_OK == 1197 GNUNET_break (GNUNET_OK ==
1155 GNUNET_CONTAINER_multihashmap_put (connected_peers, 1198 GNUNET_CONTAINER_multihashmap_put (connected_peers,
1156 &peer->hashPubKey, 1199 &peer->hashPubKey,
@@ -1166,6 +1209,105 @@ peer_connect_handler (void *cls,
1166} 1209}
1167 1210
1168 1211
1212/**
1213 * Increase the host credit by a value.
1214 *
1215 * @param host which peer to change the trust value on
1216 * @param value is the int value by which the
1217 * host credit is to be increased or decreased
1218 * @returns the actual change in trust (positive or negative)
1219 */
1220static int
1221change_host_trust (struct ConnectedPeer *host, int value)
1222{
1223 unsigned int old_trust;
1224
1225 if (value == 0)
1226 return 0;
1227 GNUNET_assert (host != NULL);
1228 old_trust = host->trust;
1229 if (value > 0)
1230 {
1231 if (host->trust + value < host->trust)
1232 {
1233 value = UINT32_MAX - host->trust;
1234 host->trust = UINT32_MAX;
1235 }
1236 else
1237 host->trust += value;
1238 }
1239 else
1240 {
1241 if (host->trust < -value)
1242 {
1243 value = -host->trust;
1244 host->trust = 0;
1245 }
1246 else
1247 host->trust += value;
1248 }
1249 return value;
1250}
1251
1252
1253/**
1254 * Write host-trust information to a file - flush the buffer entry!
1255 */
1256static int
1257flush_trust (void *cls,
1258 const GNUNET_HashCode *key,
1259 void *value)
1260{
1261 struct ConnectedPeer *host = value;
1262 char *fn;
1263 uint32_t trust;
1264 struct GNUNET_PeerIdentity pid;
1265
1266 if (host->trust == host->disk_trust)
1267 return GNUNET_OK; /* unchanged */
1268 GNUNET_PEER_resolve (host->pid,
1269 &pid);
1270 fn = get_trust_filename (&pid);
1271 if (host->trust == 0)
1272 {
1273 if ((0 != UNLINK (fn)) && (errno != ENOENT))
1274 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
1275 GNUNET_ERROR_TYPE_BULK, "unlink", fn);
1276 }
1277 else
1278 {
1279 trust = htonl (host->trust);
1280 if (sizeof(uint32_t) == GNUNET_DISK_fn_write (fn, &trust,
1281 sizeof(uint32_t),
1282 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
1283 | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ))
1284 host->disk_trust = host->trust;
1285 }
1286 GNUNET_free (fn);
1287 return GNUNET_OK;
1288}
1289
1290/**
1291 * Call this method periodically to scan data/hosts for new hosts.
1292 */
1293static void
1294cron_flush_trust (void *cls,
1295 const struct GNUNET_SCHEDULER_TaskContext *tc)
1296{
1297
1298 if (NULL == connected_peers)
1299 return;
1300 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1301 &flush_trust,
1302 NULL);
1303 if (NULL == tc)
1304 return;
1305 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1306 return;
1307 GNUNET_SCHEDULER_add_delayed (tc->sched,
1308 TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
1309}
1310
1169 1311
1170/** 1312/**
1171 * Free (each) request made by the peer. 1313 * Free (each) request made by the peer.
@@ -1253,7 +1395,7 @@ peer_disconnect_handler (void *cls,
1253 &consider_migration, 1395 &consider_migration,
1254 pos); 1396 pos);
1255 } 1397 }
1256 if (cp->trust_delta > 0) 1398 if (cp->trust > 0)
1257 { 1399 {
1258 /* FIXME: push trust back to peerinfo! 1400 /* FIXME: push trust back to peerinfo!
1259 (need better peerinfo API!) */ 1401 (need better peerinfo API!) */
@@ -1400,6 +1542,7 @@ shutdown_task (void *cls,
1400 while (client_list != NULL) 1542 while (client_list != NULL)
1401 handle_client_disconnect (NULL, 1543 handle_client_disconnect (NULL,
1402 client_list->client); 1544 client_list->client);
1545 cron_flush_trust (NULL, NULL);
1403 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 1546 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1404 &clean_peer, 1547 &clean_peer,
1405 NULL); 1548 NULL);
@@ -1430,6 +1573,8 @@ shutdown_task (void *cls,
1430 dsh = NULL; 1573 dsh = NULL;
1431 sched = NULL; 1574 sched = NULL;
1432 cfg = NULL; 1575 cfg = NULL;
1576 GNUNET_free_non_null (trustDirectory);
1577 trustDirectory = NULL;
1433} 1578}
1434 1579
1435 1580
@@ -2674,7 +2819,7 @@ handle_p2p_put (void *cls,
2674 if (prq.sender != NULL) 2819 if (prq.sender != NULL)
2675 { 2820 {
2676 prq.sender->inc_preference += CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority; 2821 prq.sender->inc_preference += CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority;
2677 prq.sender->trust_delta += prq.priority; 2822 prq.sender->trust += prq.priority;
2678 } 2823 }
2679 if (GNUNET_YES == active_migration) 2824 if (GNUNET_YES == active_migration)
2680 { 2825 {
@@ -2954,13 +3099,9 @@ static uint32_t
2954bound_priority (uint32_t prio_in, 3099bound_priority (uint32_t prio_in,
2955 struct ConnectedPeer *cp) 3100 struct ConnectedPeer *cp)
2956{ 3101{
2957 if (cp->trust_delta > prio_in) 3102 /* FIXME: check if load is low and we
2958 { 3103 hence should not charge... */
2959 cp->trust_delta -= prio_in; 3104 return change_host_trust (cp, prio_in);
2960 return prio_in;
2961 }
2962 // FIXME: get out trust in the target peer from peerinfo!
2963 return 0;
2964} 3105}
2965 3106
2966 3107
@@ -3510,6 +3651,7 @@ main_init (struct GNUNET_SCHEDULER_Handle *s,
3510 NULL, 3651 NULL,
3511 &peer_connect_handler, 3652 &peer_connect_handler,
3512 &peer_disconnect_handler, 3653 &peer_disconnect_handler,
3654 NULL,
3513 NULL, GNUNET_NO, 3655 NULL, GNUNET_NO,
3514 NULL, GNUNET_NO, 3656 NULL, GNUNET_NO,
3515 p2p_handlers); 3657 p2p_handlers);
@@ -3543,6 +3685,17 @@ main_init (struct GNUNET_SCHEDULER_Handle *s,
3543 GNUNET_SERVER_disconnect_notify (server, 3685 GNUNET_SERVER_disconnect_notify (server,
3544 &handle_client_disconnect, 3686 &handle_client_disconnect,
3545 NULL); 3687 NULL);
3688 GNUNET_assert (GNUNET_OK ==
3689 GNUNET_CONFIGURATION_get_value_filename (cfg,
3690 "fs",
3691 "TRUST",
3692 &trustDirectory));
3693 GNUNET_DISK_directory_create (trustDirectory);
3694 GNUNET_SCHEDULER_add_with_priority (sched,
3695 GNUNET_SCHEDULER_PRIORITY_HIGH,
3696 &cron_flush_trust, NULL);
3697
3698
3546 GNUNET_SERVER_add_handlers (server, handlers); 3699 GNUNET_SERVER_add_handlers (server, handlers);
3547 GNUNET_SCHEDULER_add_delayed (sched, 3700 GNUNET_SCHEDULER_add_delayed (sched,
3548 GNUNET_TIME_UNIT_FOREVER_REL, 3701 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,
274 GNUNET_TIME_UNIT_FOREVER_REL, 274 GNUNET_TIME_UNIT_FOREVER_REL,
275 NULL, 275 NULL,
276 &core_init, 276 &core_init,
277 &connect_handler, &disconnect_handler, 277 &connect_handler, &disconnect_handler, NULL,
278 NULL, GNUNET_NO, 278 NULL, GNUNET_NO,
279 NULL, GNUNET_NO, 279 NULL, GNUNET_NO,
280 learning? learn_handlers : no_learn_handlers); 280 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,
183static void 183static void
184host_processor (void *cls, 184host_processor (void *cls,
185 const struct GNUNET_PeerIdentity * peer, 185 const struct GNUNET_PeerIdentity * peer,
186 const struct GNUNET_HELLO_Message *hello, 186 const struct GNUNET_HELLO_Message *hello)
187 uint32_t trust)
188{ 187{
189 struct HostSet *results = cls; 188 struct HostSet *results = cls;
190 size_t old; 189 size_t old;
@@ -447,13 +446,11 @@ disconnect_handler (void *cls,
447 * @param cls closure (not used) 446 * @param cls closure (not used)
448 * @param peer potential peer to connect to 447 * @param peer potential peer to connect to
449 * @param hello HELLO for this peer (or NULL) 448 * @param hello HELLO for this peer (or NULL)
450 * @param trust how much we trust the peer (not used)
451 */ 449 */
452static void 450static void
453process_notify (void *cls, 451process_notify (void *cls,
454 const struct GNUNET_PeerIdentity *peer, 452 const struct GNUNET_PeerIdentity *peer,
455 const struct GNUNET_HELLO_Message *hello, 453 const struct GNUNET_HELLO_Message *hello)
456 uint32_t trust)
457{ 454{
458 struct HostSet *results; 455 struct HostSet *results;
459#if DEBUG_HOSTLIST_SERVER 456#if DEBUG_HOSTLIST_SERVER
@@ -464,7 +461,6 @@ process_notify (void *cls,
464 GNUNET_assert (peerinfo != NULL); 461 GNUNET_assert (peerinfo != NULL);
465 pitr = GNUNET_PEERINFO_iterate (peerinfo, 462 pitr = GNUNET_PEERINFO_iterate (peerinfo,
466 NULL, 463 NULL,
467 0,
468 GNUNET_TIME_UNIT_MINUTES, 464 GNUNET_TIME_UNIT_MINUTES,
469 &host_processor, 465 &host_processor,
470 results); 466 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)
383 if ( NULL != filename) GNUNET_free ( filename ); 383 if ( NULL != filename) GNUNET_free ( filename );
384 384
385 p->core = GNUNET_CORE_connect (sched, p->cfg, 385 p->core = GNUNET_CORE_connect (sched, p->cfg,
386 GNUNET_TIME_UNIT_FOREVER_REL, 386 GNUNET_TIME_UNIT_FOREVER_REL,
387 NULL, 387 NULL,
388 NULL, 388 NULL,
389 NULL, NULL, 389 NULL, NULL, NULL,
390 NULL, GNUNET_NO, 390 NULL, GNUNET_NO,
391 NULL, GNUNET_NO, 391 NULL, GNUNET_NO,
392 learn_handlers ); 392 learn_handlers );
393 GNUNET_assert ( NULL != p->core ); 393 GNUNET_assert ( NULL != p->core );
394 p->stats = GNUNET_STATISTICS_create (sched, "hostlist", p->cfg); 394 p->stats = GNUNET_STATISTICS_create (sched, "hostlist", p->cfg);
395 GNUNET_assert ( NULL != p->stats ); 395 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,
64 struct GNUNET_TIME_Relative latency, 64 struct GNUNET_TIME_Relative latency,
65 uint32_t distance); 65 uint32_t distance);
66 66
67/**
68 * Method called whenever a given peer has a status change.
69 *
70 * @param cls closure
71 * @param peer peer identity this notification is about
72 * @param latency reported latency of the connection with 'other'
73 * @param distance reported distance (DV) to 'other'
74 * @param bandwidth_in available amount of inbound bandwidth
75 * @param bandwidth_out available amount of outbound bandwidth
76 * @param timeout absolute time when this peer will time out
77 * unless we see some further activity from it
78 */
79typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls,
80 const struct
81 GNUNET_PeerIdentity * peer,
82 struct GNUNET_TIME_Relative latency,
83 uint32_t distance,
84 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
85 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
86 struct GNUNET_TIME_Absolute timeout);
67 87
68 88
69/** 89/**
@@ -166,6 +186,7 @@ typedef void
166 * connected to the core service; note that timeout is only meaningful if init is not NULL 186 * connected to the core service; note that timeout is only meaningful if init is not NULL
167 * @param connects function to call on peer connect, can be NULL 187 * @param connects function to call on peer connect, can be NULL
168 * @param disconnects function to call on peer disconnect / timeout, can be NULL 188 * @param disconnects function to call on peer disconnect / timeout, can be NULL
189 * @param status_events function to call on peer status changes, can be NULL
169 * @param inbound_notify function to call for all inbound messages, can be NULL 190 * @param inbound_notify function to call for all inbound messages, can be NULL
170 * note that the core is allowed to drop notifications about inbound 191 * note that the core is allowed to drop notifications about inbound
171 * messages if the client does not process them fast enough (for this 192 * messages if the client does not process them fast enough (for this
@@ -201,6 +222,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
201 GNUNET_CORE_StartupCallback init, 222 GNUNET_CORE_StartupCallback init,
202 GNUNET_CORE_ConnectEventHandler connects, 223 GNUNET_CORE_ConnectEventHandler connects,
203 GNUNET_CORE_DisconnectEventHandler disconnects, 224 GNUNET_CORE_DisconnectEventHandler disconnects,
225 GNUNET_CORE_PeerStatusEventHandler status_events,
204 GNUNET_CORE_MessageCallback inbound_notify, 226 GNUNET_CORE_MessageCallback inbound_notify,
205 int inbound_hdr_only, 227 int inbound_hdr_only,
206 GNUNET_CORE_MessageCallback outbound_notify, 228 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 @@
20/** 20/**
21 * @file include/gnunet_peerinfo_service.h 21 * @file include/gnunet_peerinfo_service.h
22 * @brief Code to maintain the list of currently known hosts 22 * @brief Code to maintain the list of currently known hosts
23 * (in memory structure of data/hosts) and their trust ratings 23 * (in memory structure of data/hosts).
24 * (in memory structure of data/trust)
25 * @author Christian Grothoff 24 * @author Christian Grothoff
26 */ 25 */
27 26
@@ -98,13 +97,11 @@ GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
98 * @param cls closure 97 * @param cls closure
99 * @param peer id of the peer, NULL for last call 98 * @param peer id of the peer, NULL for last call
100 * @param hello hello message for the peer (can be NULL) 99 * @param hello hello message for the peer (can be NULL)
101 * @param trust amount of trust we have in the peer
102 */ 100 */
103typedef void 101typedef void
104 (*GNUNET_PEERINFO_Processor) (void *cls, 102 (*GNUNET_PEERINFO_Processor) (void *cls,
105 const struct GNUNET_PeerIdentity * peer, 103 const struct GNUNET_PeerIdentity * peer,
106 const struct GNUNET_HELLO_Message * hello, 104 const struct GNUNET_HELLO_Message * hello);
107 uint32_t trust);
108 105
109 106
110/** 107/**
@@ -123,12 +120,11 @@ struct GNUNET_PEERINFO_IteratorContext;
123 * being done; however, the trust argument will be set to zero if we 120 * being done; however, the trust argument will be set to zero if we
124 * are done, 1 if we timed out and 2 for fatal error. 121 * are done, 1 if we timed out and 2 for fatal error.
125 * 122 *
126 * Instead of calling this function with 'peer == NULL' and 'trust == 123 * Instead of calling this function with 'peer == NULL'
127 * 0', it is often better to use 'GNUNET_PEERINFO_notify'. 124 * it is often better to use 'GNUNET_PEERINFO_notify'.
128 * 125 *
129 * @param h handle to the peerinfo service 126 * @param h handle to the peerinfo service
130 * @param peer restrict iteration to this peer only (can be NULL) 127 * @param peer restrict iteration to this peer only (can be NULL)
131 * @param trust_delta how much to change the trust in all matching peers
132 * @param timeout how long to wait until timing out 128 * @param timeout how long to wait until timing out
133 * @param callback the method to call for each peer 129 * @param callback the method to call for each peer
134 * @param callback_cls closure for callback 130 * @param callback_cls closure for callback
@@ -138,7 +134,6 @@ struct GNUNET_PEERINFO_IteratorContext;
138struct GNUNET_PEERINFO_IteratorContext * 134struct GNUNET_PEERINFO_IteratorContext *
139GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, 135GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
140 const struct GNUNET_PeerIdentity *peer, 136 const struct GNUNET_PeerIdentity *peer,
141 int trust_delta,
142 struct GNUNET_TIME_Relative timeout, 137 struct GNUNET_TIME_Relative timeout,
143 GNUNET_PEERINFO_Processor callback, 138 GNUNET_PEERINFO_Processor callback,
144 void *callback_cls); 139 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"
52#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE 3 52#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE 3
53 53
54 54
55/**
56 * Set a statistical value.
57 */
58#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 4
59
60/**
61 * Get a statistical value(s).
62 */
63#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 5
64
65/**
66 * Response to a STATISTICS_GET message (with value).
67 */
68#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 6
69
70/**
71 * Response to a STATISTICS_GET message (end of value stream).
72 */
73#define GNUNET_MESSAGE_TYPE_STATISTICS_END 7
74
75 55
76/** 56/**
77 * Request to ARM to start a service. 57 * Request to ARM to start a service.
@@ -345,35 +325,40 @@ extern "C"
345#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 68 325#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 68
346 326
347/** 327/**
328 * Notify clients about peer status change.
329 */
330#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE 69
331
332/**
348 * Notify clients about incoming P2P messages. 333 * Notify clients about incoming P2P messages.
349 */ 334 */
350#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 69 335#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 70
351 336
352/** 337/**
353 * Notify clients about outgoing P2P transmissions. 338 * Notify clients about outgoing P2P transmissions.
354 */ 339 */
355#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 70 340#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 71
356 341
357/** 342/**
358 * Request from client to "configure" P2P connection. 343 * Request from client to "configure" P2P connection.
359 */ 344 */
360#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 71 345#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 72
361 346
362/** 347/**
363 * Response from server about (possibly updated) P2P 348 * Response from server about (possibly updated) P2P
364 * connection configuration. 349 * connection configuration.
365 */ 350 */
366#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 72 351#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 73
367 352
368/** 353/**
369 * Request from client with message to transmit. 354 * Request from client with message to transmit.
370 */ 355 */
371#define GNUNET_MESSAGE_TYPE_CORE_SEND 73 356#define GNUNET_MESSAGE_TYPE_CORE_SEND 74
372 357
373/** 358/**
374 * Request from client asking to connect to a peer. 359 * Request from client asking to connect to a peer.
375 */ 360 */
376#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 74 361#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 75
377 362
378 363
379/** 364/**
@@ -584,6 +569,39 @@ extern "C"
584 */ 569 */
585#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT 160 570#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT 160
586 571
572
573/**
574 * Set a statistical value.
575 */
576#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 168
577
578/**
579 * Get a statistical value(s).
580 */
581#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 169
582
583/**
584 * Response to a STATISTICS_GET message (with value).
585 */
586#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 170
587
588/**
589 * Response to a STATISTICS_GET message (end of value stream).
590 */
591#define GNUNET_MESSAGE_TYPE_STATISTICS_END 171
592
593/**
594 * Watch changes to a statistical value. Message format is the same
595 * as for GET, except that the subsystem and entry name must be given.
596 */
597#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH 172
598
599/**
600 * Changes to a watched value.
601 */
602#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE 173
603
604
587/** 605/**
588 * Type used to match 'all' message types. 606 * Type used to match 'all' message types.
589 */ 607 */
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 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 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,
94 94
95 95
96/** 96/**
97 * Watch statistics from the peer (be notified whenever they change).
98 * Note that the only way to cancel a "watch" request is to destroy
99 * the statistics handle given as the first argument to this call.
100 *
101 * @param handle identification of the statistics service
102 * @param subsystem limit to the specified subsystem, never NULL
103 * @param name name of the statistic value, never NULL
104 * @param proc function to call on each value
105 * @param proc_cls closure for proc
106 * @return GNUNET_OK on success, GNUNET_SYSERR on error
107 */
108int
109GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
110 const char *subsystem,
111 const char *name,
112 GNUNET_STATISTICS_Iterator proc,
113 void *proc_cls);
114
115
116/**
97 * Continuation called by the "get_all" and "get" functions. 117 * Continuation called by the "get_all" and "get" functions.
98 * 118 *
99 * @param cls closure 119 * @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
49 char **address_list; 49 char **address_list;
50 unsigned int num_addresses; 50 unsigned int num_addresses;
51 uint32_t off; 51 uint32_t off;
52 uint32_t trust;
53}; 52};
54 53
55 54
@@ -60,9 +59,8 @@ dump_pc (struct PrintContext *pc)
60 unsigned int i; 59 unsigned int i;
61 60
62 GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc); 61 GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc);
63 printf (_("Peer `%s' with trust %8u\n"), 62 printf (_("Peer `%s'\n"),
64 (const char *) &enc, 63 (const char *) &enc);
65 pc->trust);
66 for (i=0;i<pc->num_addresses;i++) 64 for (i=0;i<pc->num_addresses;i++)
67 { 65 {
68 printf ("\t%s\n", 66 printf ("\t%s\n",
@@ -156,13 +154,13 @@ print_address (void *cls,
156 154
157/** 155/**
158 * Print information about the peer. 156 * Print information about the peer.
159 * Currently prints the GNUNET_PeerIdentity, trust and the IP. 157 * Currently prints the GNUNET_PeerIdentity and the IP.
160 * Could of course do more (e.g. resolve via DNS). 158 * Could of course do more (e.g. resolve via DNS).
161 */ 159 */
162static void 160static void
163print_peer_info (void *cls, 161print_peer_info (void *cls,
164 const struct GNUNET_PeerIdentity *peer, 162 const struct GNUNET_PeerIdentity *peer,
165 const struct GNUNET_HELLO_Message *hello, uint32_t trust) 163 const struct GNUNET_HELLO_Message *hello)
166{ 164{
167 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 165 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
168 struct PrintContext *pc; 166 struct PrintContext *pc;
@@ -170,22 +168,8 @@ print_peer_info (void *cls,
170 if (peer == NULL) 168 if (peer == NULL)
171 { 169 {
172 GNUNET_PEERINFO_disconnect (peerinfo); 170 GNUNET_PEERINFO_disconnect (peerinfo);
173 switch (trust) 171 fprintf (stderr,
174 { 172 _("Error in communication with PEERINFO service\n"));
175 case 0:
176 break;
177 case 1:
178 fprintf (stderr,
179 _("Timeout trying to interact with PEERINFO service\n"));
180 break;
181 case 2:
182 fprintf (stderr,
183 _("Error in communication with PEERINFO service\n"));
184 break;
185 default:
186 GNUNET_break (0);
187 break;
188 }
189 return; 173 return;
190 } 174 }
191 if (be_quiet) 175 if (be_quiet)
@@ -196,7 +180,6 @@ print_peer_info (void *cls,
196 } 180 }
197 pc = GNUNET_malloc (sizeof (struct PrintContext)); 181 pc = GNUNET_malloc (sizeof (struct PrintContext));
198 pc->peer = *peer; 182 pc->peer = *peer;
199 pc->trust = trust;
200 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc); 183 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc);
201 if (0 == pc->off) 184 if (0 == pc->off)
202 { 185 {
@@ -228,27 +211,10 @@ run (void *cls,
228 struct GNUNET_PeerIdentity pid; 211 struct GNUNET_PeerIdentity pid;
229 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 212 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
230 char *fn; 213 char *fn;
231 int delta;
232 214
233 sched = s; 215 sched = s;
234 cfg = c; 216 cfg = c;
235 delta = 0; 217 if (args[0] != NULL)
236 if ( (args[0] != NULL) &&
237 (args[1] != NULL) &&
238 (1 == sscanf(args[0], "%d", &delta)) &&
239 (GNUNET_OK ==
240 GNUNET_CRYPTO_hash_from_string (args[1],
241 &pid.hashPubKey)) )
242 {
243 peerinfo = GNUNET_PEERINFO_connect (sched, cfg);
244 GNUNET_PEERINFO_iterate (peerinfo,
245 &pid,
246 delta,
247 GNUNET_TIME_UNIT_SECONDS,
248 &print_peer_info, NULL);
249 return;
250 }
251 else if (args[0] != NULL)
252 { 218 {
253 fprintf (stderr, 219 fprintf (stderr,
254 _("Invalid command line argument `%s'\n"), 220 _("Invalid command line argument `%s'\n"),
@@ -266,7 +232,6 @@ run (void *cls,
266 } 232 }
267 (void) GNUNET_PEERINFO_iterate (peerinfo, 233 (void) GNUNET_PEERINFO_iterate (peerinfo,
268 NULL, 234 NULL,
269 0,
270 GNUNET_TIME_relative_multiply 235 GNUNET_TIME_relative_multiply
271 (GNUNET_TIME_UNIT_SECONDS, 2), 236 (GNUNET_TIME_UNIT_SECONDS, 2),
272 &print_peer_info, NULL); 237 &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:
46 os.system ('gnunet-arm -q -i transport -c test_gnunet_peerinfo_data.conf') 46 os.system ('gnunet-arm -q -i transport -c test_gnunet_peerinfo_data.conf')
47 os.system ('sleep 1') 47 os.system ('sleep 1')
48 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf') 48 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf')
49 pinfo.expect (re.compile ("Peer `.*\' with trust *0\r")); 49 pinfo.expect (re.compile ("Peer `.*\'\r"));
50 pinfo.expect (re.compile (" *localhost:24357\r")); 50 pinfo.expect (re.compile (" *localhost:24357\r"));
51 pinfo.expect (pexpect.EOF); 51 pinfo.expect (pexpect.EOF);
52 52
53 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf -n') 53 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf -n')
54 pinfo.expect (re.compile ("Peer `.*\' with trust *0\r")); 54 pinfo.expect (re.compile ("Peer `.*\'\r"));
55 pinfo.expect (re.compile (" *127..*:24357\r")); 55 pinfo.expect (re.compile (" *127..*:24357\r"));
56 pinfo.expect (pexpect.EOF); 56 pinfo.expect (pexpect.EOF);
57 57
@@ -59,14 +59,6 @@ try:
59 pid = pinfo.read (-1) 59 pid = pinfo.read (-1)
60 pid = pid.strip () 60 pid = pid.strip ()
61 61
62 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf 4 ' + pid)
63 pinfo.expect (re.compile ("Peer `" + pid + "\' with trust *4\r"));
64 pinfo.expect (pexpect.EOF);
65
66 pinfo = pexpect.spawn ('gnunet-peerinfo -c test_gnunet_peerinfo_data.conf -- -4 ' + pid)
67 pinfo.expect (re.compile ("Peer `" + pid + "\' with trust *0\r"));
68 pinfo.expect (pexpect.EOF);
69
70finally: 62finally:
71 os.system ('gnunet-arm -c test_gnunet_peerinfo_data.conf -eq') 63 os.system ('gnunet-arm -c test_gnunet_peerinfo_data.conf -eq')
72 os.system ('rm -rf /tmp/gnunet-test-peerinfo/') 64 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 @@
23 * @brief maintains list of known peers 23 * @brief maintains list of known peers
24 * 24 *
25 * Code to maintain the list of currently known hosts (in memory 25 * Code to maintain the list of currently known hosts (in memory
26 * structure of data/hosts/ and data/credit/). 26 * structure of data/hosts/).
27 * 27 *
28 * @author Christian Grothoff 28 * @author Christian Grothoff
29 * 29 *
@@ -46,11 +46,6 @@
46#define DATA_HOST_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) 46#define DATA_HOST_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
47 47
48/** 48/**
49 * How often do we flush trust values to disk?
50 */
51#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
52
53/**
54 * How often do we discard old entries in data/hosts/? 49 * How often do we discard old entries in data/hosts/?
55 */ 50 */
56#define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60) 51#define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
@@ -76,16 +71,6 @@ struct HostEntry
76 */ 71 */
77 struct GNUNET_HELLO_Message *hello; 72 struct GNUNET_HELLO_Message *hello;
78 73
79 /**
80 * Trust rating for this peer
81 */
82 uint32_t trust;
83
84 /**
85 * Trust rating for this peer on disk.
86 */
87 uint32_t disk_trust;
88
89}; 74};
90 75
91 76
@@ -105,11 +90,6 @@ static struct GNUNET_SERVER_NotificationContext *notify_list;
105static char *networkIdDirectory; 90static char *networkIdDirectory;
106 91
107/** 92/**
108 * Where do we store trust information?
109 */
110static char *trustDirectory;
111
112/**
113 * Handle for reporting statistics. 93 * Handle for reporting statistics.
114 */ 94 */
115static struct GNUNET_STATISTICS_Handle *stats; 95static struct GNUNET_STATISTICS_Handle *stats;
@@ -129,7 +109,6 @@ make_info_message (const struct HostEntry *he)
129 im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); 109 im = GNUNET_malloc (sizeof (struct InfoMessage) + hs);
130 im->header.size = htons (hs + sizeof (struct InfoMessage)); 110 im->header.size = htons (hs + sizeof (struct InfoMessage));
131 im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); 111 im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
132 im->trust = htonl (he->trust);
133 im->peer = he->identity; 112 im->peer = he->identity;
134 if (he->hello != NULL) 113 if (he->hello != NULL)
135 memcpy (&im[1], he->hello, hs); 114 memcpy (&im[1], he->hello, hs);
@@ -184,25 +163,7 @@ get_host_filename (const struct GNUNET_PeerIdentity *id)
184 163
185 164
186/** 165/**
187 * Get the filename under which we would store the GNUNET_HELLO_Message 166 * Find the host entry for the given peer. FIXME: replace by hash map!
188 * for the given host and protocol.
189 * @return filename of the form DIRECTORY/HOSTID
190 */
191static char *
192get_trust_filename (const struct GNUNET_PeerIdentity *id)
193{
194 struct GNUNET_CRYPTO_HashAsciiEncoded fil;
195 char *fn;
196
197 GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil);
198 GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil);
199 return fn;
200}
201
202
203/**
204 * Find the host entry for the given peer. Call
205 * only when synchronized!
206 * @return NULL if not found 167 * @return NULL if not found
207 */ 168 */
208static struct HostEntry * 169static struct HostEntry *
@@ -247,13 +208,12 @@ static void
247add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) 208add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
248{ 209{
249 struct HostEntry *entry; 210 struct HostEntry *entry;
250 char *fn;
251 uint32_t trust;
252 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; 211 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
253 const struct GNUNET_HELLO_Message *hello; 212 const struct GNUNET_HELLO_Message *hello;
254 struct GNUNET_HELLO_Message *hello_clean; 213 struct GNUNET_HELLO_Message *hello_clean;
255 int size; 214 int size;
256 struct GNUNET_TIME_Absolute now; 215 struct GNUNET_TIME_Absolute now;
216 char *fn;
257 217
258 entry = lookup_host_entry (identity); 218 entry = lookup_host_entry (identity);
259 if (entry != NULL) 219 if (entry != NULL)
@@ -264,11 +224,6 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
264 GNUNET_NO); 224 GNUNET_NO);
265 entry = GNUNET_malloc (sizeof (struct HostEntry)); 225 entry = GNUNET_malloc (sizeof (struct HostEntry));
266 entry->identity = *identity; 226 entry->identity = *identity;
267 fn = get_trust_filename (identity);
268 if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
269 (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust))))
270 entry->disk_trust = entry->trust = ntohl (trust);
271 GNUNET_free (fn);
272 227
273 fn = get_host_filename (identity); 228 fn = get_host_filename (identity);
274 if (GNUNET_DISK_file_test (fn) == GNUNET_YES) 229 if (GNUNET_DISK_file_test (fn) == GNUNET_YES)
@@ -302,56 +257,6 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
302 257
303 258
304/** 259/**
305 * Increase the host credit by a value.
306 *
307 * @param hostId is the identity of the host
308 * @param value is the int value by which the
309 * host credit is to be increased or decreased
310 * @returns the actual change in trust (positive or negative)
311 */
312static int
313change_host_trust (const struct GNUNET_PeerIdentity *hostId, int value)
314{
315 struct HostEntry *host;
316 unsigned int old_trust;
317
318 if (value == 0)
319 return 0;
320 host = lookup_host_entry (hostId);
321 if (host == NULL)
322 {
323 add_host_to_known_hosts (hostId);
324 host = lookup_host_entry (hostId);
325 }
326 GNUNET_assert (host != NULL);
327 old_trust = host->trust;
328 if (value > 0)
329 {
330 if (host->trust + value < host->trust)
331 {
332 value = UINT32_MAX - host->trust;
333 host->trust = UINT32_MAX;
334 }
335 else
336 host->trust += value;
337 }
338 else
339 {
340 if (host->trust < -value)
341 {
342 value = -host->trust;
343 host->trust = 0;
344 }
345 else
346 host->trust += value;
347 }
348 if (host->trust != old_trust)
349 notify_all (host);
350 return value;
351}
352
353
354/**
355 * Remove a file that should not be there. LOG 260 * Remove a file that should not be there. LOG
356 * success or failure. 261 * success or failure.
357 */ 262 */
@@ -480,16 +385,14 @@ bind_address (const struct GNUNET_PeerIdentity *peer,
480 385
481/** 386/**
482 * Do transmit info either for only the host matching the given 387 * Do transmit info either for only the host matching the given
483 * argument or for all known hosts and change their trust values by 388 * argument or for all known hosts.
484 * the given delta.
485 * 389 *
486 * @param only NULL to hit all hosts, otherwise specifies a particular target 390 * @param only NULL to hit all hosts, otherwise specifies a particular target
487 * @param trust_change how much should the trust be changed
488 * @param client who is making the request (and will thus receive our confirmation) 391 * @param client who is making the request (and will thus receive our confirmation)
489 */ 392 */
490static void 393static void
491send_to_each_host (const struct GNUNET_PeerIdentity *only, 394send_to_each_host (const struct GNUNET_PeerIdentity *only,
492 int trust_change, struct GNUNET_SERVER_Client *client) 395 struct GNUNET_SERVER_Client *client)
493{ 396{
494 struct HostEntry *pos; 397 struct HostEntry *pos;
495 struct InfoMessage *im; 398 struct InfoMessage *im;
@@ -508,7 +411,6 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
508 memcmp (only, &pos->identity, 411 memcmp (only, &pos->identity,
509 sizeof (struct GNUNET_PeerIdentity)))) 412 sizeof (struct GNUNET_PeerIdentity))))
510 { 413 {
511 change_host_trust (&pos->identity, trust_change);
512 hs = 0; 414 hs = 0;
513 im = (struct InfoMessage *) buf; 415 im = (struct InfoMessage *) buf;
514 if (pos->hello != NULL) 416 if (pos->hello != NULL)
@@ -522,7 +424,7 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
522 } 424 }
523 im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); 425 im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
524 im->header.size = htons (sizeof (struct InfoMessage) + hs); 426 im->header.size = htons (sizeof (struct InfoMessage) + hs);
525 im->trust = htonl (pos->trust); 427 im->reserved = htonl (0);
526 im->peer = pos->identity; 428 im->peer = pos->identity;
527 GNUNET_SERVER_transmit_context_append_message (tc, 429 GNUNET_SERVER_transmit_context_append_message (tc,
528 &im->header); 430 &im->header);
@@ -542,58 +444,6 @@ send_to_each_host (const struct GNUNET_PeerIdentity *only,
542 444
543 445
544/** 446/**
545 * Write host-trust information to a file - flush the buffer entry!
546 * Assumes synchronized access.
547 */
548static void
549flush_trust (struct HostEntry *host)
550{
551 char *fn;
552 uint32_t trust;
553
554 if (host->trust == host->disk_trust)
555 return; /* unchanged */
556 fn = get_trust_filename (&host->identity);
557 if (host->trust == 0)
558 {
559 if ((0 != UNLINK (fn)) && (errno != ENOENT))
560 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
561 GNUNET_ERROR_TYPE_BULK, "unlink", fn);
562 }
563 else
564 {
565 trust = htonl (host->trust);
566 if (sizeof(uint32_t) == GNUNET_DISK_fn_write (fn, &trust,
567 sizeof(uint32_t),
568 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
569 | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ))
570 host->disk_trust = host->trust;
571 }
572 GNUNET_free (fn);
573}
574
575/**
576 * Call this method periodically to scan data/hosts for new hosts.
577 */
578static void
579cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
580{
581 struct HostEntry *pos;
582
583 pos = hosts;
584 while (pos != NULL)
585 {
586 flush_trust (pos);
587 pos = pos->next;
588 }
589 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
590 return;
591 GNUNET_SCHEDULER_add_delayed (tc->sched,
592 TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
593}
594
595
596/**
597 * @brief delete expired HELLO entries in data/hosts/ 447 * @brief delete expired HELLO entries in data/hosts/
598 */ 448 */
599static int 449static int
@@ -711,7 +561,7 @@ handle_get (void *cls,
711 "GET", 561 "GET",
712 GNUNET_i2s (&lpm->peer)); 562 GNUNET_i2s (&lpm->peer));
713#endif 563#endif
714 send_to_each_host (&lpm->peer, ntohl (lpm->trust_change), client); 564 send_to_each_host (&lpm->peer, client);
715} 565}
716 566
717 567
@@ -727,15 +577,12 @@ handle_get_all (void *cls,
727 struct GNUNET_SERVER_Client *client, 577 struct GNUNET_SERVER_Client *client,
728 const struct GNUNET_MessageHeader *message) 578 const struct GNUNET_MessageHeader *message)
729{ 579{
730 const struct ListAllPeersMessage *lpm;
731
732 lpm = (const struct ListAllPeersMessage *) message;
733#if DEBUG_PEERINFO 580#if DEBUG_PEERINFO
734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
735 "`%s' message received\n", 582 "`%s' message received\n",
736 "GET_ALL"); 583 "GET_ALL");
737#endif 584#endif
738 send_to_each_host (NULL, ntohl (lpm->trust_change), client); 585 send_to_each_host (NULL, client);
739} 586}
740 587
741 588
@@ -814,7 +661,7 @@ run (void *cls,
814 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET, 661 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET,
815 sizeof (struct ListPeerMessage)}, 662 sizeof (struct ListPeerMessage)},
816 {&handle_get_all, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, 663 {&handle_get_all, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL,
817 sizeof (struct ListAllPeersMessage)}, 664 sizeof (struct GNUNET_MessageHeader)},
818 {&handle_notify, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, 665 {&handle_notify, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY,
819 sizeof (struct GNUNET_MessageHeader)}, 666 sizeof (struct GNUNET_MessageHeader)},
820 {NULL, NULL, 0, 0} 667 {NULL, NULL, 0, 0}
@@ -826,20 +673,11 @@ run (void *cls,
826 "peerinfo", 673 "peerinfo",
827 "HOSTS", 674 "HOSTS",
828 &networkIdDirectory)); 675 &networkIdDirectory));
829 GNUNET_assert (GNUNET_OK ==
830 GNUNET_CONFIGURATION_get_value_filename (cfg,
831 "peerinfo",
832 "TRUST",
833 &trustDirectory));
834 GNUNET_DISK_directory_create (networkIdDirectory); 676 GNUNET_DISK_directory_create (networkIdDirectory);
835 GNUNET_DISK_directory_create (trustDirectory);
836 GNUNET_SCHEDULER_add_with_priority (sched, 677 GNUNET_SCHEDULER_add_with_priority (sched,
837 GNUNET_SCHEDULER_PRIORITY_IDLE, 678 GNUNET_SCHEDULER_PRIORITY_IDLE,
838 &cron_scan_directory_data_hosts, NULL); 679 &cron_scan_directory_data_hosts, NULL);
839 GNUNET_SCHEDULER_add_with_priority (sched, 680 GNUNET_SCHEDULER_add_with_priority (sched,
840 GNUNET_SCHEDULER_PRIORITY_HIGH,
841 &cron_flush_trust, NULL);
842 GNUNET_SCHEDULER_add_with_priority (sched,
843 GNUNET_SCHEDULER_PRIORITY_IDLE, 681 GNUNET_SCHEDULER_PRIORITY_IDLE,
844 &cron_clean_data_hosts, NULL); 682 &cron_clean_data_hosts, NULL);
845 GNUNET_SCHEDULER_add_delayed (sched, 683 GNUNET_SCHEDULER_add_delayed (sched,
@@ -868,7 +706,6 @@ main (int argc, char *const *argv)
868 GNUNET_SERVICE_OPTION_NONE, 706 GNUNET_SERVICE_OPTION_NONE,
869 &run, NULL)) ? 0 : 1; 707 &run, NULL)) ? 0 : 1;
870 GNUNET_free_non_null (networkIdDirectory); 708 GNUNET_free_non_null (networkIdDirectory);
871 GNUNET_free_non_null (trustDirectory);
872 return ret; 709 return ret;
873} 710}
874 711
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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -31,8 +31,7 @@
31 31
32/** 32/**
33 * Message requesting a listing of all known peers, 33 * Message requesting a listing of all known peers,
34 * possibly modified by the specified trust value 34 * possibly restricted to the specified peer identity.
35 * and restricted to the specified peer identity.
36 */ 35 */
37struct ListPeerMessage 36struct ListPeerMessage
38{ 37{
@@ -43,10 +42,9 @@ struct ListPeerMessage
43 struct GNUNET_MessageHeader header; 42 struct GNUNET_MessageHeader header;
44 43
45 /** 44 /**
46 * How much to change the trust in each returned peer, 45 * Always zero.
47 * in network byte order.
48 */ 46 */
49 int32_t trust_change GNUNET_PACKED; 47 uint32_t reserved GNUNET_PACKED;
50 48
51 /** 49 /**
52 * Restrict to peers with this identity (optional 50 * Restrict to peers with this identity (optional
@@ -58,28 +56,6 @@ struct ListPeerMessage
58 56
59 57
60/** 58/**
61 * Message requesting a listing of all known peers,
62 * possibly modified by the specified trust value
63 * and restricted to the specified peer identity.
64 */
65struct ListAllPeersMessage
66{
67
68 /**
69 * Type will be GNUNET_MESSAGE_TYPE_PEERINFO_GET
70 */
71 struct GNUNET_MessageHeader header;
72
73 /**
74 * How much to change the trust in each returned peer,
75 * in network byte order.
76 */
77 int32_t trust_change GNUNET_PACKED;
78
79};
80
81
82/**
83 * Message used to inform the client about 59 * Message used to inform the client about
84 * a particular peer; this message is optionally followed 60 * a particular peer; this message is optionally followed
85 * by a HELLO message for the respective peer (if available). 61 * by a HELLO message for the respective peer (if available).
@@ -95,10 +71,9 @@ struct InfoMessage
95 struct GNUNET_MessageHeader header; 71 struct GNUNET_MessageHeader header;
96 72
97 /** 73 /**
98 * Amount of trust we now have in the peer, 74 * Always zero.
99 * in network byte order.
100 */ 75 */
101 uint32_t trust GNUNET_PACKED; 76 uint32_t reserved GNUNET_PACKED;
102 77
103 /** 78 /**
104 * About which peer are we talking here? 79 * 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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2007, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 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)
397 GNUNET_SCHEDULER_cancel (ic->h->sched, 397 GNUNET_SCHEDULER_cancel (ic->h->sched,
398 ic->timeout_task); 398 ic->timeout_task);
399 if (ic->callback != NULL) 399 if (ic->callback != NULL)
400 ic->callback (ic->callback_cls, NULL, NULL, 1); 400 ic->callback (ic->callback_cls, NULL, NULL);
401 GNUNET_free (ic); 401 GNUNET_free (ic);
402 return; 402 return;
403 } 403 }
@@ -413,7 +413,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
413 GNUNET_SCHEDULER_cancel (ic->h->sched, 413 GNUNET_SCHEDULER_cancel (ic->h->sched,
414 ic->timeout_task); 414 ic->timeout_task);
415 if (ic->callback != NULL) 415 if (ic->callback != NULL)
416 ic->callback (ic->callback_cls, NULL, NULL, 0); 416 ic->callback (ic->callback_cls, NULL, NULL);
417 GNUNET_free (ic); 417 GNUNET_free (ic);
418 return; 418 return;
419 } 419 }
@@ -428,7 +428,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
428 GNUNET_SCHEDULER_cancel (ic->h->sched, 428 GNUNET_SCHEDULER_cancel (ic->h->sched,
429 ic->timeout_task); 429 ic->timeout_task);
430 if (ic->callback != NULL) 430 if (ic->callback != NULL)
431 ic->callback (ic->callback_cls, NULL, NULL, 2); 431 ic->callback (ic->callback_cls, NULL, NULL);
432 GNUNET_free (ic); 432 GNUNET_free (ic);
433 return; 433 return;
434 } 434 }
@@ -446,7 +446,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
446 GNUNET_SCHEDULER_cancel (ic->h->sched, 446 GNUNET_SCHEDULER_cancel (ic->h->sched,
447 ic->timeout_task); 447 ic->timeout_task);
448 if (ic->callback != NULL) 448 if (ic->callback != NULL)
449 ic->callback (ic->callback_cls, NULL, NULL, 2); 449 ic->callback (ic->callback_cls, NULL, NULL);
450 GNUNET_free (ic); 450 GNUNET_free (ic);
451 return; 451 return;
452 } 452 }
@@ -461,7 +461,7 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
461#endif 461#endif
462 ic->h->in_receive = GNUNET_YES; 462 ic->h->in_receive = GNUNET_YES;
463 if (ic->callback != NULL) 463 if (ic->callback != NULL)
464 ic->callback (ic->callback_cls, &im->peer, hello, ntohl (im->trust)); 464 ic->callback (ic->callback_cls, &im->peer, hello);
465 GNUNET_CLIENT_receive (ic->h->client, 465 GNUNET_CLIENT_receive (ic->h->client,
466 &peerinfo_handler, 466 &peerinfo_handler,
467 ic, 467 ic,
@@ -497,7 +497,7 @@ iterator_start_receive (void *cls,
497 reconnect (ic->h); 497 reconnect (ic->h);
498 trigger_transmit (ic->h); 498 trigger_transmit (ic->h);
499 if (ic->callback != NULL) 499 if (ic->callback != NULL)
500 ic->callback (ic->callback_cls, NULL, NULL, 1); 500 ic->callback (ic->callback_cls, NULL, NULL);
501 GNUNET_free (ic); 501 GNUNET_free (ic);
502 return; 502 return;
503 } 503 }
@@ -536,7 +536,7 @@ signal_timeout (void *cls,
536 GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, 536 GNUNET_CONTAINER_DLL_remove (ic->h->tq_head,
537 ic->h->tq_tail, 537 ic->h->tq_tail,
538 ic->tqe); 538 ic->tqe);
539 ic->callback (ic->callback_cls, NULL, NULL, 1); 539 ic->callback (ic->callback_cls, NULL, NULL);
540 ic->callback = NULL; 540 ic->callback = NULL;
541 if (ic->in_receive) 541 if (ic->in_receive)
542 return; 542 return;
@@ -551,16 +551,11 @@ signal_timeout (void *cls,
551 * host and then finally once with a NULL pointer. After that final 551 * host and then finally once with a NULL pointer. After that final
552 * invocation, the iterator context must no longer be used. 552 * invocation, the iterator context must no longer be used.
553 * 553 *
554 * Note that the last call can be triggered by timeout or by simply 554 * Instead of calling this function with 'peer == NULL' it is often
555 * being done; however, the trust argument will be set to zero if we 555 * better to use 'GNUNET_PEERINFO_notify'.
556 * are done, 1 if we timed out and 2 for fatal error.
557 *
558 * Instead of calling this function with 'peer == NULL' and 'trust ==
559 * 0', it is often better to use 'GNUNET_PEERINFO_notify'.
560 * 556 *
561 * @param h handle to the peerinfo service 557 * @param h handle to the peerinfo service
562 * @param peer restrict iteration to this peer only (can be NULL) 558 * @param peer restrict iteration to this peer only (can be NULL)
563 * @param trust_delta how much to change the trust in all matching peers
564 * @param timeout how long to wait until timing out 559 * @param timeout how long to wait until timing out
565 * @param callback the method to call for each peer 560 * @param callback the method to call for each peer
566 * @param callback_cls closure for callback 561 * @param callback_cls closure for callback
@@ -570,12 +565,11 @@ signal_timeout (void *cls,
570struct GNUNET_PEERINFO_IteratorContext * 565struct GNUNET_PEERINFO_IteratorContext *
571GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, 566GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
572 const struct GNUNET_PeerIdentity *peer, 567 const struct GNUNET_PeerIdentity *peer,
573 int trust_delta,
574 struct GNUNET_TIME_Relative timeout, 568 struct GNUNET_TIME_Relative timeout,
575 GNUNET_PEERINFO_Processor callback, 569 GNUNET_PEERINFO_Processor callback,
576 void *callback_cls) 570 void *callback_cls)
577{ 571{
578 struct ListAllPeersMessage *lapm; 572 struct GNUNET_MessageHeader *lapm;
579 struct ListPeerMessage *lpm; 573 struct ListPeerMessage *lpm;
580 struct GNUNET_PEERINFO_IteratorContext *ic; 574 struct GNUNET_PEERINFO_IteratorContext *ic;
581 struct TransmissionQueueEntry *tqe; 575 struct TransmissionQueueEntry *tqe;
@@ -587,12 +581,11 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
587 "Requesting list of peers from PEERINFO service\n"); 581 "Requesting list of peers from PEERINFO service\n");
588#endif 582#endif
589 tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + 583 tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) +
590 sizeof (struct ListAllPeersMessage)); 584 sizeof (struct GNUNET_MessageHeader));
591 tqe->size = sizeof (struct ListAllPeersMessage); 585 tqe->size = sizeof (struct GNUNET_MessageHeader);
592 lapm = (struct ListAllPeersMessage *) &tqe[1]; 586 lapm = (struct GNUNET_MessageHeader *) &tqe[1];
593 lapm->header.size = htons (sizeof (struct ListAllPeersMessage)); 587 lapm->size = htons (sizeof (struct GNUNET_MessageHeader));
594 lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL); 588 lapm->type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
595 lapm->trust_change = htonl (trust_delta);
596 } 589 }
597 else 590 else
598 { 591 {
@@ -607,7 +600,6 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
607 lpm = (struct ListPeerMessage *) &tqe[1]; 600 lpm = (struct ListPeerMessage *) &tqe[1];
608 lpm->header.size = htons (sizeof (struct ListPeerMessage)); 601 lpm->header.size = htons (sizeof (struct ListPeerMessage));
609 lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET); 602 lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
610 lpm->trust_change = htonl (trust_delta);
611 memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity)); 603 memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
612 } 604 }
613 ic = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext)); 605 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,
142 "Received information about peer `%s' from peerinfo database\n", 142 "Received information about peer `%s' from peerinfo database\n",
143 GNUNET_i2s (&im->peer)); 143 GNUNET_i2s (&im->peer));
144#endif 144#endif
145 nc->callback (nc->callback_cls, &im->peer, hello, ntohl (im->trust)); 145 nc->callback (nc->callback_cls, &im->peer, hello);
146 receive_notifications (nc); 146 receive_notifications (nc);
147} 147}
148 148
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 ()
102static void 102static void
103process (void *cls, 103process (void *cls,
104 const struct GNUNET_PeerIdentity *peer, 104 const struct GNUNET_PeerIdentity *peer,
105 const struct GNUNET_HELLO_Message *hello, uint32_t trust) 105 const struct GNUNET_HELLO_Message *hello)
106{ 106{
107 int *ok = cls; 107 int *ok = cls;
108 unsigned int agc; 108 unsigned int agc;
@@ -118,7 +118,6 @@ process (void *cls,
118 add_peer (); 118 add_peer ();
119 ic = GNUNET_PEERINFO_iterate (h, 119 ic = GNUNET_PEERINFO_iterate (h,
120 NULL, 120 NULL,
121 0,
122 GNUNET_TIME_relative_multiply 121 GNUNET_TIME_relative_multiply
123 (GNUNET_TIME_UNIT_SECONDS, 15), 122 (GNUNET_TIME_UNIT_SECONDS, 15),
124 &process, cls); 123 &process, cls);
@@ -126,7 +125,6 @@ process (void *cls,
126 } 125 }
127 GNUNET_assert (peer == NULL); 126 GNUNET_assert (peer == NULL);
128 GNUNET_assert (2 == *ok); 127 GNUNET_assert (2 == *ok);
129 GNUNET_assert (trust == 0);
130 GNUNET_PEERINFO_disconnect (h); 128 GNUNET_PEERINFO_disconnect (h);
131 h = NULL; 129 h = NULL;
132 *ok = 0; 130 *ok = 0;
@@ -156,7 +154,6 @@ run (void *cls,
156 add_peer (); 154 add_peer ();
157 ic = GNUNET_PEERINFO_iterate (h, 155 ic = GNUNET_PEERINFO_iterate (h,
158 NULL, 156 NULL,
159 0,
160 GNUNET_TIME_relative_multiply 157 GNUNET_TIME_relative_multiply
161 (GNUNET_TIME_UNIT_SECONDS, 15), 158 (GNUNET_TIME_UNIT_SECONDS, 15),
162 &process, cls); 159 &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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -27,6 +27,7 @@
27 * - use BIO for IO operations 27 * - use BIO for IO operations
28 */ 28 */
29#include "platform.h" 29#include "platform.h"
30#include "gnunet_container_lib.h"
30#include "gnunet_disk_lib.h" 31#include "gnunet_disk_lib.h"
31#include "gnunet_getopt_lib.h" 32#include "gnunet_getopt_lib.h"
32#include "gnunet_protocols.h" 33#include "gnunet_protocols.h"
@@ -37,6 +38,41 @@
37#include "statistics.h" 38#include "statistics.h"
38 39
39/** 40/**
41 * Watch entry.
42 */
43struct WatchEntry
44{
45
46 struct WatchEntry *next;
47
48 struct WatchEntry *prev;
49
50 struct GNUNET_SERVER_Client *client;
51
52 uint64_t last_value;
53
54 uint32_t wid;
55
56};
57
58
59/**
60 * Client entry.
61 */
62struct ClientEntry
63{
64
65 struct ClientEntry *next;
66
67 struct ClientEntry *prev;
68
69 struct GNUNET_SERVER_Client *client;
70
71 uint32_t max_wid;
72
73};
74
75/**
40 * Entry in the statistics list. 76 * Entry in the statistics list.
41 */ 77 */
42struct StatsEntry 78struct StatsEntry
@@ -66,6 +102,18 @@ struct StatsEntry
66 struct GNUNET_STATISTICS_SetMessage *msg; 102 struct GNUNET_STATISTICS_SetMessage *msg;
67 103
68 /** 104 /**
105 * Watch context for changes to this
106 * value, or NULL for none.
107 */
108 struct WatchEntry *we_head;
109
110 /**
111 * Watch context for changes to this
112 * value, or NULL for none.
113 */
114 struct WatchEntry *we_tail;
115
116 /**
69 * Our value. 117 * Our value.
70 */ 118 */
71 uint64_t value; 119 uint64_t value;
@@ -92,6 +140,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
92 */ 140 */
93static struct StatsEntry *start; 141static struct StatsEntry *start;
94 142
143static struct ClientEntry *client_head;
144
145static struct ClientEntry *client_tail;
146
147/**
148 * Our notification context.
149 */
150static struct GNUNET_SERVER_NotificationContext *nc;
151
152/**
153 * Counter used to generate unique values.
154 */
155static uint32_t uidgen;
156
157
95/** 158/**
96 * Load persistent values from disk. Disk format is 159 * Load persistent values from disk. Disk format is
97 * exactly the same format that we also use for 160 * exactly the same format that we also use for
@@ -209,7 +272,7 @@ save ()
209 * Transmit the given stats value. 272 * Transmit the given stats value.
210 */ 273 */
211static void 274static void
212transmit (struct GNUNET_SERVER_TransmitContext *tc, 275transmit (struct GNUNET_SERVER_Client *client,
213 const struct StatsEntry *e) 276 const struct StatsEntry *e)
214{ 277{
215 struct GNUNET_STATISTICS_ReplyMessage *m; 278 struct GNUNET_STATISTICS_ReplyMessage *m;
@@ -232,10 +295,11 @@ transmit (struct GNUNET_SERVER_TransmitContext *tc,
232 2, e->service, e->name)); 295 2, e->service, e->name));
233#if DEBUG_STATISTICS 296#if DEBUG_STATISTICS
234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
235 "Transmitting value for `%s:%s': %llu\n", 298 "Transmitting value for `%s:%s' (%d): %llu\n",
236 e->service, e->name, e->value); 299 e->service, e->name,
300 e->persistent, e->value);
237#endif 301#endif
238 GNUNET_SERVER_transmit_context_append_message (tc, &m->header); 302 GNUNET_SERVER_notification_context_unicast (nc, client, &m->header, GNUNET_NO);
239 GNUNET_free (m); 303 GNUNET_free (m);
240} 304}
241 305
@@ -252,6 +316,32 @@ matches (const struct StatsEntry *e, const char *service, const char *name)
252} 316}
253 317
254 318
319static struct ClientEntry *
320make_client_entry (struct GNUNET_SERVER_Client *client)
321{
322 struct ClientEntry *ce;
323
324 if (client == NULL)
325 return NULL;
326 ce = client_head;
327 while (ce != NULL)
328 {
329 if (ce->client == client)
330 return ce;
331 ce = ce->next;
332 }
333 ce = GNUNET_malloc (sizeof (struct ClientEntry));
334 ce->client = client;
335 GNUNET_SERVER_client_keep (client);
336 GNUNET_CONTAINER_DLL_insert (client_head,
337 client_tail,
338 ce);
339 GNUNET_SERVER_notification_context_add (nc,
340 client);
341 return ce;
342}
343
344
255/** 345/**
256 * Handle GET-message. 346 * Handle GET-message.
257 * 347 *
@@ -266,12 +356,13 @@ handle_get (void *cls,
266 struct GNUNET_SERVER_Client *client, 356 struct GNUNET_SERVER_Client *client,
267 const struct GNUNET_MessageHeader *message) 357 const struct GNUNET_MessageHeader *message)
268{ 358{
359 struct GNUNET_MessageHeader end;
269 char *service; 360 char *service;
270 char *name; 361 char *name;
271 struct StatsEntry *pos; 362 struct StatsEntry *pos;
272 struct GNUNET_SERVER_TransmitContext *tc;
273 size_t size; 363 size_t size;
274 364
365 make_client_entry (client);
275 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader); 366 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
276 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1], 367 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
277 size, 2, &service, &name)) 368 size, 2, &service, &name))
@@ -285,20 +376,51 @@ handle_get (void *cls,
285 "Received request for statistics on `%s:%s'\n", 376 "Received request for statistics on `%s:%s'\n",
286 strlen (service) ? service : "*", strlen (name) ? name : "*"); 377 strlen (service) ? service : "*", strlen (name) ? name : "*");
287#endif 378#endif
288 tc = GNUNET_SERVER_transmit_context_create (client);
289 pos = start; 379 pos = start;
290 while (pos != NULL) 380 while (pos != NULL)
291 { 381 {
292 if (matches (pos, service, name)) 382 if (matches (pos, service, name))
293 transmit (tc, pos); 383 transmit (client, pos);
294 pos = pos->next; 384 pos = pos->next;
295 } 385 }
296 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 386 end.size = htons (sizeof (struct GNUNET_MessageHeader));
297 GNUNET_MESSAGE_TYPE_STATISTICS_END); 387 end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END);
298 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 388 GNUNET_SERVER_notification_context_unicast (nc,
389 client,
390 &end,
391 GNUNET_NO);
392 GNUNET_SERVER_receive_done (client,
393 GNUNET_OK);
299} 394}
300 395
301 396
397static void
398notify_change (struct StatsEntry *se)
399{
400 struct GNUNET_STATISTICS_WatchValueMessage wvm;
401 struct WatchEntry *pos;
402
403 pos = se->we_head;
404 while (pos != NULL)
405 {
406 if (pos->last_value != se->value)
407 {
408 wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE);
409 wvm.header.size = htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage));
410 wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0);
411 wvm.wid = htonl (pos->wid);
412 wvm.reserved = htonl (0);
413 wvm.value = GNUNET_htonll (se->value);
414 GNUNET_SERVER_notification_context_unicast (nc,
415 pos->client,
416 &wvm.header,
417 GNUNET_NO);
418 pos->last_value = se->value;
419 }
420 pos = pos->next;
421 }
422}
423
302/** 424/**
303 * Handle SET-message. 425 * Handle SET-message.
304 * 426 *
@@ -311,11 +433,6 @@ handle_set (void *cls,
311 struct GNUNET_SERVER_Client *client, 433 struct GNUNET_SERVER_Client *client,
312 const struct GNUNET_MessageHeader *message) 434 const struct GNUNET_MessageHeader *message)
313{ 435{
314 /**
315 * Counter used to generate unique values.
316 */
317 static uint32_t uidgen;
318
319 char *service; 436 char *service;
320 char *name; 437 char *name;
321 uint16_t msize; 438 uint16_t msize;
@@ -326,7 +443,9 @@ handle_set (void *cls,
326 uint32_t flags; 443 uint32_t flags;
327 uint64_t value; 444 uint64_t value;
328 int64_t delta; 445 int64_t delta;
446 int changed;
329 447
448 make_client_entry (client);
330 msize = ntohs (message->size); 449 msize = ntohs (message->size);
331 if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage)) 450 if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage))
332 { 451 {
@@ -344,13 +463,15 @@ handle_set (void *cls,
344 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 463 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
345 return; 464 return;
346 } 465 }
466 flags = ntohl (msg->flags);
467 value = GNUNET_ntohll (msg->value);
347#if DEBUG_STATISTICS 468#if DEBUG_STATISTICS
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 "Received request to update statistic on `%s:%s'\n", 470 "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
350 service, name); 471 service, name,
472 (unsigned int) flags,
473 (unsigned long long) value);
351#endif 474#endif
352 flags = ntohl (msg->flags);
353 value = GNUNET_ntohll (msg->value);
354 pos = start; 475 pos = start;
355 prev = NULL; 476 prev = NULL;
356 while (pos != NULL) 477 while (pos != NULL)
@@ -359,17 +480,20 @@ handle_set (void *cls,
359 { 480 {
360 if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) 481 if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
361 { 482 {
483 changed = (pos->value != value);
362 pos->value = value; 484 pos->value = value;
363 } 485 }
364 else 486 else
365 { 487 {
366 delta = (int64_t) value; 488 delta = (int64_t) value;
367 if ((delta < 0) && (pos->value < -delta)) 489 if ((delta < 0) && (pos->value < -delta))
368 { 490 {
369 pos->value = 0; 491 changed = (pos->value != 0);
492 pos->value = 0;
370 } 493 }
371 else 494 else
372 { 495 {
496 changed = (delta != 0);
373 GNUNET_break ((delta <= 0) || 497 GNUNET_break ((delta <= 0) ||
374 (pos->value + delta > pos->value)); 498 (pos->value + delta > pos->value));
375 pos->value += delta; 499 pos->value += delta;
@@ -391,6 +515,8 @@ handle_set (void *cls,
391 "Statistic `%s:%s' updated to value %llu.\n", 515 "Statistic `%s:%s' updated to value %llu.\n",
392 service, name, pos->value); 516 service, name, pos->value);
393#endif 517#endif
518 if (changed)
519 notify_change (pos);
394 GNUNET_SERVER_receive_done (client, GNUNET_OK); 520 GNUNET_SERVER_receive_done (client, GNUNET_OK);
395 return; 521 return;
396 } 522 }
@@ -420,6 +546,86 @@ handle_set (void *cls,
420 546
421 547
422/** 548/**
549 * Handle WATCH-message.
550 *
551 * @param cls closure
552 * @param client identification of the client
553 * @param message the actual message
554 */
555static void
556handle_watch (void *cls,
557 struct GNUNET_SERVER_Client *client,
558 const struct GNUNET_MessageHeader *message)
559{
560 char *service;
561 char *name;
562 uint16_t msize;
563 uint16_t size;
564 struct StatsEntry *pos;
565 struct ClientEntry *ce;
566 struct WatchEntry *we;
567
568 ce = make_client_entry (client);
569 msize = ntohs (message->size);
570 if (msize < sizeof (struct GNUNET_MessageHeader))
571 {
572 GNUNET_break (0);
573 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
574 return;
575 }
576 size = msize - sizeof (struct GNUNET_MessageHeader);
577 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
578 size, 2, &service, &name))
579 {
580 GNUNET_break (0);
581 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
582 return;
583 }
584#if DEBUG_STATISTICS
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "Received request to watch statistic on `%s:%s'\n",
587 service, name);
588#endif
589 pos = start;
590 while (pos != NULL)
591 {
592 if (matches (pos, service, name))
593 break;
594 pos = pos->next;
595 }
596 if (pos == NULL)
597 {
598 pos = GNUNET_malloc (sizeof (struct StatsEntry) +
599 sizeof (struct GNUNET_STATISTICS_SetMessage) +
600 size);
601 pos->next = start;
602 pos->uid = uidgen++;
603 pos->msg = (void *) &pos[1];
604 pos->msg->header.size = htons (sizeof (struct GNUNET_STATISTICS_SetMessage) +
605 size);
606 pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
607 memcpy (pos->msg, message, ntohs (message->size));
608 pos->service = (const char *) &pos->msg[1];
609 memcpy (&pos->msg[1], service, strlen (service)+1);
610 pos->name = &pos->service[strlen (pos->service) + 1];
611 memcpy ((void*) pos->name, name, strlen (name)+1);
612 start = pos;
613 }
614 we = GNUNET_malloc (sizeof (struct WatchEntry));
615 we->client = client;
616 GNUNET_SERVER_client_keep (client);
617 we->wid = ce->max_wid++;
618 GNUNET_CONTAINER_DLL_insert (pos->we_head,
619 pos->we_tail,
620 we);
621 if (pos->value != 0)
622 notify_change (pos);
623 GNUNET_SERVER_receive_done (client,
624 GNUNET_OK);
625}
626
627
628/**
423 * Task run during shutdown. 629 * Task run during shutdown.
424 * 630 *
425 * @param cls unused 631 * @param cls unused
@@ -429,7 +635,84 @@ static void
429shutdown_task (void *cls, 635shutdown_task (void *cls,
430 const struct GNUNET_SCHEDULER_TaskContext *tc) 636 const struct GNUNET_SCHEDULER_TaskContext *tc)
431{ 637{
638 struct ClientEntry *ce;
639 struct WatchEntry *we;
640 struct StatsEntry *se;
641
432 save (); 642 save ();
643 GNUNET_SERVER_notification_context_destroy (nc);
644 nc = NULL;
645 while (NULL != (ce = client_head))
646 {
647 GNUNET_SERVER_client_drop (ce->client);
648 GNUNET_CONTAINER_DLL_remove (client_head,
649 client_tail,
650 ce);
651 GNUNET_free (ce);
652 }
653 while (NULL != (se = start))
654 {
655 start = se->next;
656 while (NULL != (we = se->we_head))
657 {
658 GNUNET_SERVER_client_drop (we->client);
659 GNUNET_CONTAINER_DLL_remove (se->we_head,
660 se->we_tail,
661 we);
662 GNUNET_free (we);
663 }
664 GNUNET_free (se);
665 }
666}
667
668
669/**
670 * A client disconnected. Remove all of its data structure entries.
671 *
672 * @param cls closure, NULL
673 * @param client identification of the client
674 */
675static void
676handle_client_disconnect (void *cls,
677 struct GNUNET_SERVER_Client
678 * client)
679{
680 struct ClientEntry *ce;
681 struct WatchEntry *we;
682 struct WatchEntry *wen;
683 struct StatsEntry *se;
684
685 ce = client_head;
686 while (NULL != ce)
687 {
688 if (ce->client == client)
689 {
690 GNUNET_SERVER_client_drop (ce->client);
691 GNUNET_CONTAINER_DLL_remove (client_head,
692 client_tail,
693 ce);
694 GNUNET_free (ce);
695 break;
696 }
697 ce = ce->next;
698 }
699 se = start;
700 while (NULL != se)
701 {
702 wen = se->we_head;
703 while (NULL != (we = wen))
704 {
705 wen = we->next;
706 if (we->client != client)
707 continue;
708 GNUNET_SERVER_client_drop (we->client);
709 GNUNET_CONTAINER_DLL_remove (se->we_head,
710 se->we_tail,
711 we);
712 GNUNET_free (we);
713 }
714 se = se->next;
715 }
433} 716}
434 717
435 718
@@ -450,10 +733,15 @@ run (void *cls,
450 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 733 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
451 {&handle_set, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_SET, 0}, 734 {&handle_set, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_SET, 0},
452 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_GET, 0}, 735 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_GET, 0},
736 {&handle_watch, NULL, GNUNET_MESSAGE_TYPE_STATISTICS_WATCH, 0},
453 {NULL, NULL, 0, 0} 737 {NULL, NULL, 0, 0}
454 }; 738 };
455 cfg = c; 739 cfg = c;
456 GNUNET_SERVER_add_handlers (server, handlers); 740 GNUNET_SERVER_add_handlers (server, handlers);
741 nc = GNUNET_SERVER_notification_context_create (server, 16);
742 GNUNET_SERVER_disconnect_notify (server,
743 &handle_client_disconnect,
744 NULL);
457 load (server); 745 load (server);
458 GNUNET_SCHEDULER_add_delayed (sched, 746 GNUNET_SCHEDULER_add_delayed (sched,
459 GNUNET_TIME_UNIT_FOREVER_REL, 747 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
91 91
92}; 92};
93 93
94
95/**
96 * Message transmitted if a watched value changes.
97 */
98struct GNUNET_STATISTICS_WatchValueMessage
99{
100 /**
101 * Type: GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE
102 */
103 struct GNUNET_MessageHeader header;
104
105 /**
106 * 0 for absolute value, 1 for relative value; 2 to make persistent
107 * (see GNUNET_STATISTICS_SETFLAG_*).
108 */
109 uint32_t flags GNUNET_PACKED;
110
111 /**
112 * Unique watch identification number (watch
113 * requests are enumerated in the order they
114 * are received, the first request having
115 * a wid of zero).
116 */
117 uint32_t wid GNUNET_PACKED;
118
119 /**
120 * Reserved (always 0).
121 */
122 uint32_t reserved GNUNET_PACKED;
123
124 /**
125 * Value. Note that if this is a relative value, it will
126 * be signed even though the type given here is unsigned.
127 */
128 uint64_t value GNUNET_PACKED;
129
130};
131
132
94#endif 133#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 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -25,6 +25,7 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_client_lib.h" 27#include "gnunet_client_lib.h"
28#include "gnunet_constants.h"
28#include "gnunet_container_lib.h" 29#include "gnunet_container_lib.h"
29#include "gnunet_protocols.h" 30#include "gnunet_protocols.h"
30#include "gnunet_server_lib.h" 31#include "gnunet_server_lib.h"
@@ -47,7 +48,37 @@ enum ActionType
47{ 48{
48 ACTION_GET, 49 ACTION_GET,
49 ACTION_SET, 50 ACTION_SET,
50 ACTION_UPDATE 51 ACTION_UPDATE,
52 ACTION_WATCH
53};
54
55
56/**
57 * Entry kept for each value we are watching.
58 */
59struct GNUNET_STATISTICS_WatchEntry
60{
61
62 /**
63 * What subsystem is this action about? (never NULL)
64 */
65 char *subsystem;
66
67 /**
68 * What value is this action about? (never NULL)
69 */
70 char *name;
71
72 /**
73 * Function to call
74 */
75 GNUNET_STATISTICS_Iterator proc;
76
77 /**
78 * Closure for proc
79 */
80 void *proc_cls;
81
51}; 82};
52 83
53 84
@@ -118,7 +149,7 @@ struct GNUNET_STATISTICS_GetHandle
118 int aborted; 149 int aborted;
119 150
120 /** 151 /**
121 * Is this a GET, SET or UPDATE? 152 * Is this a GET, SET, UPDATE or WATCH?
122 */ 153 */
123 enum ActionType type; 154 enum ActionType type;
124 155
@@ -179,14 +210,103 @@ struct GNUNET_STATISTICS_Handle
179 struct GNUNET_STATISTICS_GetHandle *current; 210 struct GNUNET_STATISTICS_GetHandle *current;
180 211
181 /** 212 /**
213 * Array of watch entries.
214 */
215 struct GNUNET_STATISTICS_WatchEntry **watches;
216
217 /**
218 * Task doing exponential back-off trying to reconnect.
219 */
220 GNUNET_SCHEDULER_TaskIdentifier backoff_task;
221
222 /**
223 * Time for next connect retry.
224 */
225 struct GNUNET_TIME_Relative backoff;
226
227 /**
228 * Size of the 'watches' array.
229 */
230 unsigned int watches_size;
231
232 /**
182 * Should this handle auto-destruct once all actions have 233 * Should this handle auto-destruct once all actions have
183 * been processed? 234 * been processed?
184 */ 235 */
185 int do_destroy; 236 int do_destroy;
186 237
238 /**
239 * Are we currently receiving from the service?
240 */
241 int receiving;
242
187}; 243};
188 244
189 245
246
247/**
248 * Schedule the next action to be performed.
249 */
250static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
251
252/**
253 * Try to (re)connect to the statistics service.
254 *
255 * @return GNUNET_YES on success, GNUNET_NO on failure.
256 */
257static int
258try_connect (struct GNUNET_STATISTICS_Handle *ret);
259
260
261static void
262insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai)
263{
264 GNUNET_CONTAINER_DLL_insert_after (h->action_head,
265 h->action_tail,
266 h->action_tail,
267 ai);
268 if (h->action_head == ai)
269 schedule_action (h);
270}
271
272
273static void
274schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
275 struct GNUNET_STATISTICS_WatchEntry *watch)
276{
277
278 struct GNUNET_STATISTICS_GetHandle *ai;
279 size_t slen;
280 size_t nlen;
281 size_t nsize;
282
283 GNUNET_assert (h != NULL);
284 if (GNUNET_YES != try_connect (h))
285 {
286 schedule_action (h);
287 return;
288 }
289 slen = strlen (watch->subsystem) + 1;
290 nlen = strlen (watch->name) + 1;
291 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen;
292 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
293 {
294 GNUNET_break (0);
295 return;
296 }
297 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
298 ai->sh = h;
299 ai->subsystem = GNUNET_strdup (watch->subsystem);
300 ai->name = GNUNET_strdup (watch->name);
301 ai->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
302 ai->msize = nsize;
303 ai->type = ACTION_WATCH;
304 ai->proc = watch->proc;
305 ai->cls = watch->proc_cls;
306 insert_ai (h, ai);
307}
308
309
190/** 310/**
191 * Try to (re)connect to the statistics service. 311 * Try to (re)connect to the statistics service.
192 * 312 *
@@ -195,11 +315,16 @@ struct GNUNET_STATISTICS_Handle
195static int 315static int
196try_connect (struct GNUNET_STATISTICS_Handle *ret) 316try_connect (struct GNUNET_STATISTICS_Handle *ret)
197{ 317{
318 unsigned int i;
198 if (ret->client != NULL) 319 if (ret->client != NULL)
199 return GNUNET_YES; 320 return GNUNET_YES;
200 ret->client = GNUNET_CLIENT_connect (ret->sched, "statistics", ret->cfg); 321 ret->client = GNUNET_CLIENT_connect (ret->sched, "statistics", ret->cfg);
201 if (ret->client != NULL) 322 if (ret->client != NULL)
202 return GNUNET_YES; 323 {
324 for (i=0;i<ret->watches_size;i++)
325 schedule_watch_request (ret, ret->watches[i]);
326 return GNUNET_YES;
327 }
203#if DEBUG_STATISTICS 328#if DEBUG_STATISTICS
204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
205 _("Failed to connect to statistics service!\n")); 330 _("Failed to connect to statistics service!\n"));
@@ -221,12 +346,6 @@ free_action_item (struct GNUNET_STATISTICS_GetHandle *ai)
221 346
222 347
223/** 348/**
224 * Schedule the next action to be performed.
225 */
226static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
227
228
229/**
230 * GET processing is complete, tell client about it. 349 * GET processing is complete, tell client about it.
231 */ 350 */
232static void 351static void
@@ -259,7 +378,13 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
259 uint16_t size; 378 uint16_t size;
260 379
261 if (h->current->aborted) 380 if (h->current->aborted)
262 return GNUNET_OK; /* don't bother */ 381 {
382#if DEBUG_STATISTICS
383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
384 "Iteration was aborted, ignoring VALUE\n");
385#endif
386 return GNUNET_OK; /* don't bother */
387 }
263 size = ntohs (msg->size); 388 size = ntohs (msg->size);
264 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage)) 389 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage))
265 { 390 {
@@ -293,6 +418,42 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
293#endif 418#endif
294 h->current->aborted = GNUNET_YES; 419 h->current->aborted = GNUNET_YES;
295 } 420 }
421#if DEBUG_STATISTICS
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
423 "VALUE processed successfully\n");
424#endif
425 return GNUNET_OK;
426}
427
428
429static int
430process_watch_value (struct GNUNET_STATISTICS_Handle *h,
431 const struct GNUNET_MessageHeader *msg)
432{
433 const struct GNUNET_STATISTICS_WatchValueMessage *wvm;
434 struct GNUNET_STATISTICS_WatchEntry *w;
435 uint32_t wid;
436
437 if (sizeof(struct GNUNET_STATISTICS_WatchValueMessage) !=
438 ntohs (msg->size))
439 {
440 GNUNET_break (0);
441 return GNUNET_SYSERR;
442 }
443 wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *)msg;
444 wid = ntohl (wvm->wid);
445 if (wid >= h->watches_size)
446 {
447 GNUNET_break (0);
448 return GNUNET_SYSERR;
449 }
450 w = h->watches[wid];
451 (void) w->proc (w->proc_cls,
452 w->subsystem,
453 w->name,
454 GNUNET_ntohll (wvm->value),
455 0 !=
456 (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
296 return GNUNET_OK; 457 return GNUNET_OK;
297} 458}
298 459
@@ -329,21 +490,53 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
330 "Received end of statistics marker\n"); 491 "Received end of statistics marker\n");
331#endif 492#endif
493 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
332 finish (h, GNUNET_OK); 494 finish (h, GNUNET_OK);
495 if (h->watches_size > 0)
496 {
497 GNUNET_CLIENT_receive (h->client,
498 &receive_stats,
499 h,
500 GNUNET_TIME_UNIT_FOREVER_REL);
501 }
502 else
503 {
504 h->receiving = GNUNET_NO;
505 }
333 return; 506 return;
334 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE: 507 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
335 if (GNUNET_OK == process_message (h, msg)) 508 if (GNUNET_OK == process_message (h, msg))
336 { 509 {
337 /* finally, look for more! */ 510 /* finally, look for more! */
511#if DEBUG_STATISTICS
512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
513 "Processing VALUE done, now reading more\n");
514#endif
338 GNUNET_CLIENT_receive (h->client, 515 GNUNET_CLIENT_receive (h->client,
339 &receive_stats, 516 &receive_stats,
340 h, 517 h,
341 GNUNET_TIME_absolute_get_remaining 518 GNUNET_TIME_absolute_get_remaining
342 (h->current->timeout)); 519 (h->current->timeout));
520 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
343 return; 521 return;
344 } 522 }
345 GNUNET_break (0); 523 GNUNET_break (0);
346 break; 524 break;
525 case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
526 if (GNUNET_OK ==
527 process_watch_value (h,
528 msg))
529 {
530 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
531 GNUNET_assert (h->watches_size > 0);
532 GNUNET_CLIENT_receive (h->client,
533 &receive_stats,
534 h,
535 GNUNET_TIME_UNIT_FOREVER_REL);
536 return;
537 }
538 GNUNET_break (0);
539 break;
347 default: 540 default:
348 GNUNET_break (0); 541 GNUNET_break (0);
349 break; 542 break;
@@ -392,15 +585,69 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
392 2, 585 2,
393 handle->current->subsystem, 586 handle->current->subsystem,
394 handle->current->name)); 587 handle->current->name));
395 GNUNET_CLIENT_receive (handle->client, 588 if (! handle->receiving)
396 &receive_stats, 589 {
397 handle, 590#if DEBUG_STATISTICS
398 GNUNET_TIME_absolute_get_remaining (handle-> 591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
399 current->timeout)); 592 "Transmission of GET done, now reading response\n");
593#endif
594 handle->receiving = GNUNET_YES;
595 GNUNET_CLIENT_receive (handle->client,
596 &receive_stats,
597 handle,
598 GNUNET_TIME_absolute_get_remaining (handle->
599 current->timeout));
600 }
400 return msize; 601 return msize;
401} 602}
402 603
403 604
605/**
606 * Transmit a WATCH request (and if successful, start to receive
607 * the response).
608 */
609static size_t
610transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
611{
612 struct GNUNET_MessageHeader *hdr;
613 size_t slen1;
614 size_t slen2;
615 uint16_t msize;
616
617 if (buf == NULL)
618 {
619 /* timeout / error */
620#if DEBUG_STATISTICS
621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
622 "Transmission of request for statistics failed!\n");
623#endif
624 finish (handle, GNUNET_SYSERR);
625 return 0;
626 }
627 slen1 = strlen (handle->current->subsystem) + 1;
628 slen2 = strlen (handle->current->name) + 1;
629 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
630 GNUNET_assert (msize <= size);
631 hdr = (struct GNUNET_MessageHeader *) buf;
632 hdr->size = htons (msize);
633 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH);
634 GNUNET_assert (slen1 + slen2 ==
635 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1],
636 slen1 + slen2,
637 2,
638 handle->current->subsystem,
639 handle->current->name));
640 if (! handle->receiving)
641 {
642 handle->receiving = GNUNET_YES;
643 GNUNET_CLIENT_receive (handle->client,
644 &receive_stats,
645 handle,
646 GNUNET_TIME_UNIT_FOREVER_REL);
647 }
648 return msize;
649}
650
404 651
405/** 652/**
406 * Transmit a SET/UPDATE request. 653 * Transmit a SET/UPDATE request.
@@ -464,6 +711,9 @@ transmit_action (void *cls, size_t size, void *buf)
464 case ACTION_UPDATE: 711 case ACTION_UPDATE:
465 ret = transmit_set (handle, size, buf); 712 ret = transmit_set (handle, size, buf);
466 break; 713 break;
714 case ACTION_WATCH:
715 ret = transmit_watch (handle, size, buf);
716 break;
467 default: 717 default:
468 ret = 0; 718 ret = 0;
469 GNUNET_break (0); 719 GNUNET_break (0);
@@ -495,6 +745,7 @@ GNUNET_STATISTICS_create (struct GNUNET_SCHEDULER_Handle *sched,
495 ret->sched = sched; 745 ret->sched = sched;
496 ret->cfg = cfg; 746 ret->cfg = cfg;
497 ret->subsystem = GNUNET_strdup (subsystem); 747 ret->subsystem = GNUNET_strdup (subsystem);
748 ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
498 try_connect (ret); 749 try_connect (ret);
499 return ret; 750 return ret;
500} 751}
@@ -516,7 +767,11 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
516 struct GNUNET_STATISTICS_GetHandle *next; 767 struct GNUNET_STATISTICS_GetHandle *next;
517 struct GNUNET_STATISTICS_GetHandle *prev; 768 struct GNUNET_STATISTICS_GetHandle *prev;
518 struct GNUNET_TIME_Relative timeout; 769 struct GNUNET_TIME_Relative timeout;
770 int i;
519 771
772 if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task)
773 GNUNET_SCHEDULER_cancel (h->sched,
774 h->backoff_task);
520 if (sync_first) 775 if (sync_first)
521 { 776 {
522 if (h->current != NULL) 777 if (h->current != NULL)
@@ -591,11 +846,30 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
591 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES); 846 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES);
592 h->client = NULL; 847 h->client = NULL;
593 } 848 }
849 for (i=0;i<h->watches_size;i++)
850 {
851 GNUNET_free (h->watches[i]->subsystem);
852 GNUNET_free (h->watches[i]->name);
853 GNUNET_free (h->watches[i]);
854 }
855 GNUNET_array_grow (h->watches,
856 h->watches_size,
857 0);
594 GNUNET_free (h->subsystem); 858 GNUNET_free (h->subsystem);
595 GNUNET_free (h); 859 GNUNET_free (h);
596} 860}
597 861
598 862
863static void
864finish_task (void *cls,
865 const struct GNUNET_SCHEDULER_TaskContext *tc)
866{
867 struct GNUNET_STATISTICS_Handle *h = cls;
868
869 h->backoff_task = GNUNET_SCHEDULER_NO_TASK;
870 finish (h, GNUNET_SYSERR);
871}
872
599 873
600/** 874/**
601 * Schedule the next action to be performed. 875 * Schedule the next action to be performed.
@@ -609,7 +883,13 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
609 return; /* action already pending */ 883 return; /* action already pending */
610 if (GNUNET_YES != try_connect (h)) 884 if (GNUNET_YES != try_connect (h))
611 { 885 {
612 finish (h, GNUNET_SYSERR); 886 h->backoff_task = GNUNET_SCHEDULER_add_delayed (h->sched,
887 h->backoff,
888 &finish_task,
889 h);
890 h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2);
891 h->backoff = GNUNET_TIME_relative_min (h->backoff,
892 GNUNET_CONSTANTS_SERVICE_TIMEOUT);
613 return; 893 return;
614 } 894 }
615 895
@@ -643,19 +923,6 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
643 } 923 }
644} 924}
645 925
646
647static void
648insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai)
649{
650 GNUNET_CONTAINER_DLL_insert_after (h->action_head,
651 h->action_tail,
652 h->action_tail,
653 ai);
654 if (h->action_head == ai)
655 schedule_action (h);
656}
657
658
659/** 926/**
660 * Get statistic from the peer. 927 * Get statistic from the peer.
661 * 928 *
@@ -742,6 +1009,40 @@ GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
742} 1009}
743 1010
744 1011
1012/**
1013 * Watch statistics from the peer (be notified whenever they change).
1014 * Note that the only way to cancel a "watch" request is to destroy
1015 * the statistics handle given as the first argument to this call.
1016 *
1017 * @param handle identification of the statistics service
1018 * @param subsystem limit to the specified subsystem, never NULL
1019 * @param name name of the statistic value, never NULL
1020 * @param proc function to call on each value
1021 * @param proc_cls closure for proc
1022 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1023 */
1024int
1025GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
1026 const char *subsystem,
1027 const char *name,
1028 GNUNET_STATISTICS_Iterator proc,
1029 void *proc_cls)
1030{
1031 struct GNUNET_STATISTICS_WatchEntry *w;
1032
1033 w = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_WatchEntry));
1034 w->subsystem = GNUNET_strdup (subsystem);
1035 w->name = GNUNET_strdup (name);
1036 w->proc = proc;
1037 w->proc_cls = proc_cls;
1038 GNUNET_array_append (handle->watches,
1039 handle->watches_size,
1040 w);
1041 schedule_watch_request (handle, w);
1042 return GNUNET_OK;
1043}
1044
1045
745static void 1046static void
746add_setter_action (struct GNUNET_STATISTICS_Handle *h, 1047add_setter_action (struct GNUNET_STATISTICS_Handle *h,
747 const char *name, 1048 const char *name,
@@ -809,7 +1110,8 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
809 ai->type = type; 1110 ai->type = type;
810 } 1111 }
811 } 1112 }
812 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT); 1113 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
1114 ai->make_persistent = make_persistent;
813 return; 1115 return;
814 } 1116 }
815 ai = ai->next; 1117 ai = ai->next;
@@ -824,7 +1126,6 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
824 ai->value = value; 1126 ai->value = value;
825 ai->type = type; 1127 ai->type = type;
826 insert_ai (h, ai); 1128 insert_ai (h, ai);
827 schedule_action (h);
828} 1129}
829 1130
830 1131
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 @@
29#include "gnunet_scheduler_lib.h" 29#include "gnunet_scheduler_lib.h"
30#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
31 31
32#define VERBOSE GNUNET_NO 32#define DEBUG_STATISTICS GNUNET_NO
33 33
34#define START_SERVICE GNUNET_YES 34#define START_SERVICE GNUNET_YES
35 35
@@ -38,6 +38,11 @@ check_1 (void *cls,
38 const char *subsystem, 38 const char *subsystem,
39 const char *name, uint64_t value, int is_persistent) 39 const char *name, uint64_t value, int is_persistent)
40{ 40{
41 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
42 "Received value %llu for `%s:%s\n",
43 (unsigned long long) value,
44 subsystem,
45 name);
41 GNUNET_assert (0 == strcmp (name, "test-1")); 46 GNUNET_assert (0 == strcmp (name, "test-1"));
42 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api")); 47 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
43 GNUNET_assert (value == 1); 48 GNUNET_assert (value == 1);
@@ -50,6 +55,11 @@ check_2 (void *cls,
50 const char *subsystem, 55 const char *subsystem,
51 const char *name, uint64_t value, int is_persistent) 56 const char *name, uint64_t value, int is_persistent)
52{ 57{
58 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
59 "Received value %llu for `%s:%s\n",
60 (unsigned long long) value,
61 subsystem,
62 name);
53 GNUNET_assert (0 == strcmp (name, "test-2")); 63 GNUNET_assert (0 == strcmp (name, "test-2"));
54 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api")); 64 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
55 GNUNET_assert (value == 2); 65 GNUNET_assert (value == 2);
@@ -62,6 +72,11 @@ check_3 (void *cls,
62 const char *subsystem, 72 const char *subsystem,
63 const char *name, uint64_t value, int is_persistent) 73 const char *name, uint64_t value, int is_persistent)
64{ 74{
75 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
76 "Received value %llu for `%s:%s\n",
77 (unsigned long long) value,
78 subsystem,
79 name);
65 GNUNET_assert (0 == strcmp (name, "test-3")); 80 GNUNET_assert (0 == strcmp (name, "test-3"));
66 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api")); 81 GNUNET_assert (0 == strcmp (subsystem, "test-statistics-api"));
67 GNUNET_assert (value == 3); 82 GNUNET_assert (value == 3);
@@ -85,6 +100,8 @@ static void
85next (void *cls, int success) 100next (void *cls, int success)
86{ 101{
87 GNUNET_assert (success == GNUNET_OK); 102 GNUNET_assert (success == GNUNET_OK);
103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
104 "Issuing GET request\n");
88 GNUNET_break (NULL != 105 GNUNET_break (NULL !=
89 GNUNET_STATISTICS_get (h, NULL, "test-2", 106 GNUNET_STATISTICS_get (h, NULL, "test-2",
90 GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, cls)); 107 GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, cls));
@@ -102,6 +119,8 @@ run (void *cls,
102 GNUNET_STATISTICS_set (h, "test-2", 2, GNUNET_NO); 119 GNUNET_STATISTICS_set (h, "test-2", 2, GNUNET_NO);
103 GNUNET_STATISTICS_set (h, "test-3", 2, GNUNET_NO); 120 GNUNET_STATISTICS_set (h, "test-3", 2, GNUNET_NO);
104 GNUNET_STATISTICS_update (h, "test-3", 1, GNUNET_YES); 121 GNUNET_STATISTICS_update (h, "test-3", 1, GNUNET_YES);
122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
123 "Issuing GET request\n");
105 GNUNET_break (NULL != 124 GNUNET_break (NULL !=
106 GNUNET_STATISTICS_get (h, NULL, "test-1", 125 GNUNET_STATISTICS_get (h, NULL, "test-1",
107 GNUNET_TIME_UNIT_SECONDS, &next, &check_1, cls)); 126 GNUNET_TIME_UNIT_SECONDS, &next, &check_1, cls));
@@ -127,6 +146,11 @@ check ()
127 char *const argv[] = { "test-statistics-api", 146 char *const argv[] = { "test-statistics-api",
128 "-c", 147 "-c",
129 "test_statistics_api_data.conf", 148 "test_statistics_api_data.conf",
149#if DEBUG_STATISTICS
150 "-L", "DEBUG",
151#else
152 "-L", "WARNING",
153#endif
130 NULL 154 NULL
131 }; 155 };
132 struct GNUNET_GETOPT_CommandLineOption options[] = { 156 struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -141,7 +165,7 @@ check ()
141#endif 165#endif
142 "-c", "test_statistics_api_data.conf", NULL); 166 "-c", "test_statistics_api_data.conf", NULL);
143#endif 167#endif
144 GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp", 168 GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
145 options, &run, &ok); 169 options, &run, &ok);
146#if START_SERVICE 170#if START_SERVICE
147 if (0 != PLIBC_KILL (pid, SIGTERM)) 171 if (0 != PLIBC_KILL (pid, SIGTERM))
@@ -163,7 +187,7 @@ check ()
163#endif 187#endif
164 "-c", "test_statistics_api_data.conf", NULL); 188 "-c", "test_statistics_api_data.conf", NULL);
165#endif 189#endif
166 GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp", 190 GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
167 options, &run_more, &ok); 191 options, &run_more, &ok);
168#if START_SERVICE 192#if START_SERVICE
169 if (0 != PLIBC_KILL (pid, SIGTERM)) 193 if (0 != PLIBC_KILL (pid, SIGTERM))
@@ -181,6 +205,13 @@ main (int argc, char *argv[])
181{ 205{
182 int ret; 206 int ret;
183 207
208 GNUNET_log_setup ("test_statistics_api",
209#if DEBUG_STATISTICS
210 "DEBUG",
211#else
212 "WARNING",
213#endif
214 NULL);
184 ret = check (); 215 ret = check ();
185 216
186 return ret; 217 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
4 4
5[statistics] 5[statistics]
6PORT = 22353 6PORT = 22353
7UNIXPATH = /tmp/test-statistics-service-statistics.unix
8DEBUG = YES
7 9
8[arm] 10[arm]
9PORT = 22354 11PORT = 22354
10DEFAULTSERVICES = 12DEFAULTSERVICES =
13UNIXPATH = /tmp/test-statistics-service-arm.unix
11# DEBUG = YES 14# DEBUG = YES
12 15
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,
443 * Connect to the receiving peer 443 * Connect to the receiving peer
444 */ 444 */
445 pos->peer2handle = GNUNET_CORE_connect (sched, 445 pos->peer2handle = GNUNET_CORE_connect (sched,
446 pos->peer2->cfg, 446 pos->peer2->cfg,
447 TIMEOUT, 447 TIMEOUT,
448 pos, 448 pos,
449 &init_notify_peer2, 449 &init_notify_peer2,
450 NULL, 450 NULL,
451 NULL, 451 NULL,
452 NULL, 452 NULL, NULL,
453 GNUNET_YES, NULL, GNUNET_YES, handlers); 453 GNUNET_YES, NULL, GNUNET_YES, handlers);
454 454
455} 455}
456 456
@@ -485,7 +485,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
485 TIMEOUT, 485 TIMEOUT,
486 pos, 486 pos,
487 &init_notify_peer1, 487 &init_notify_peer1,
488 NULL, 488 NULL, NULL,
489 NULL, 489 NULL,
490 NULL, 490 NULL,
491 GNUNET_NO, NULL, GNUNET_NO, no_handlers); 491 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,
513 ARM_START_WAIT, 513 ARM_START_WAIT,
514 d, 514 d,
515 &testing_init, 515 &testing_init,
516 NULL, NULL, 516 NULL, NULL, NULL,
517 NULL, GNUNET_NO, 517 NULL, GNUNET_NO,
518 NULL, GNUNET_NO, no_handlers); 518 NULL, GNUNET_NO, no_handlers);
519 break; 519 break;
@@ -1380,7 +1380,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1380 timeout, 1380 timeout,
1381 ctx, 1381 ctx,
1382 NULL, 1382 NULL,
1383 &connect_notify, NULL, 1383 &connect_notify, NULL, NULL,
1384 NULL, GNUNET_NO, 1384 NULL, GNUNET_NO,
1385 NULL, GNUNET_NO, no_handlers); 1385 NULL, GNUNET_NO, no_handlers);
1386 if (ctx->d1core == NULL) 1386 if (ctx->d1core == NULL)
@@ -1442,7 +1442,7 @@ reattempt_daemons_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext
1442 GNUNET_TIME_absolute_get_remaining(ctx->timeout), 1442 GNUNET_TIME_absolute_get_remaining(ctx->timeout),
1443 ctx, 1443 ctx,
1444 NULL, 1444 NULL,
1445 &connect_notify, NULL, 1445 &connect_notify, NULL, NULL,
1446 NULL, GNUNET_NO, 1446 NULL, GNUNET_NO,
1447 NULL, GNUNET_NO, no_handlers); 1447 NULL, GNUNET_NO, no_handlers);
1448 if (ctx->d1core == NULL) 1448 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)
934 * @param cls closure (not used) 934 * @param cls closure (not used)
935 * @param peer potential peer to connect to 935 * @param peer potential peer to connect to
936 * @param hello HELLO for this peer (or NULL) 936 * @param hello HELLO for this peer (or NULL)
937 * @param trust how much we trust the peer (not used)
938 */ 937 */
939static void 938static void
940process_peer (void *cls, 939process_peer (void *cls,
941 const struct GNUNET_PeerIdentity *peer, 940 const struct GNUNET_PeerIdentity *peer,
942 const struct GNUNET_HELLO_Message *hello, 941 const struct GNUNET_HELLO_Message *hello)
943 uint32_t trust)
944{ 942{
945 struct Peer *pos; 943 struct Peer *pos;
946 944
@@ -1404,7 +1402,8 @@ run (void *cls,
1404 NULL, 1402 NULL,
1405 &core_init, 1403 &core_init,
1406 &connect_notify, 1404 &connect_notify,
1407 &disconnect_notify, 1405 &disconnect_notify,
1406 NULL,
1408 NULL, GNUNET_NO, 1407 NULL, GNUNET_NO,
1409 NULL, GNUNET_NO, 1408 NULL, GNUNET_NO,
1410 handlers); 1409 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,
2612 * @param cls closure ('struct NeighbourList*') 2612 * @param cls closure ('struct NeighbourList*')
2613 * @param peer id of the peer, NULL for last call 2613 * @param peer id of the peer, NULL for last call
2614 * @param h hello message for the peer (can be NULL) 2614 * @param h hello message for the peer (can be NULL)
2615 * @param trust amount of trust we have in the peer (not used)
2616 */ 2615 */
2617static void 2616static void
2618add_hello_for_peer (void *cls, 2617add_hello_for_peer (void *cls,
2619 const struct GNUNET_PeerIdentity *peer, 2618 const struct GNUNET_PeerIdentity *peer,
2620 const struct GNUNET_HELLO_Message *h, 2619 const struct GNUNET_HELLO_Message *h)
2621 uint32_t trust)
2622{ 2620{
2623 struct NeighbourList *n = cls; 2621 struct NeighbourList *n = cls;
2624 2622
@@ -2706,7 +2704,7 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
2706 if (do_hello) 2704 if (do_hello)
2707 { 2705 {
2708 n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer, 2706 n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer,
2709 0, GNUNET_TIME_UNIT_FOREVER_REL, 2707 GNUNET_TIME_UNIT_FOREVER_REL,
2710 &add_hello_for_peer, n); 2708 &add_hello_for_peer, n);
2711 transmit_to_peer (NULL, NULL, 0, 2709 transmit_to_peer (NULL, NULL, 0,
2712 HELLO_ADDRESS_EXPIRATION, 2710 HELLO_ADDRESS_EXPIRATION,
@@ -3870,13 +3868,11 @@ run_validation (void *cls,
3870 * @param cls closure 3868 * @param cls closure
3871 * @param peer id of the peer, NULL for last call 3869 * @param peer id of the peer, NULL for last call
3872 * @param h hello message for the peer (can be NULL) 3870 * @param h hello message for the peer (can be NULL)
3873 * @param trust amount of trust we have in the peer (not used)
3874 */ 3871 */
3875static void 3872static void
3876check_hello_validated (void *cls, 3873check_hello_validated (void *cls,
3877 const struct GNUNET_PeerIdentity *peer, 3874 const struct GNUNET_PeerIdentity *peer,
3878 const struct GNUNET_HELLO_Message *h, 3875 const struct GNUNET_HELLO_Message *h)
3879 uint32_t trust)
3880{ 3876{
3881 struct CheckHelloValidatedContext *chvc = cls; 3877 struct CheckHelloValidatedContext *chvc = cls;
3882 struct GNUNET_HELLO_Message *plain_hello; 3878 struct GNUNET_HELLO_Message *plain_hello;
@@ -4088,7 +4084,6 @@ process_hello (struct TransportPlugin *plugin,
4088 (continuation will then schedule actual validation) */ 4084 (continuation will then schedule actual validation) */
4089 chvc->piter = GNUNET_PEERINFO_iterate (peerinfo, 4085 chvc->piter = GNUNET_PEERINFO_iterate (peerinfo,
4090 &target, 4086 &target,
4091 0,
4092 HELLO_VERIFICATION_TIMEOUT, 4087 HELLO_VERIFICATION_TIMEOUT,
4093 &check_hello_validated, chvc); 4088 &check_hello_validated, chvc);
4094 return GNUNET_OK; 4089 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,
164 } 164 }
165 if (pos == NULL) 165 if (pos == NULL)
166 return; 166 return;
167#if DEBUG_SERVER_NC
168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
169 "Client disconnected, cleaning up %u messages in NC queue\n",
170 pos->num_pending);
171#endif
167 if (prev == NULL) 172 if (prev == NULL)
168 nc->clients = pos->next; 173 nc->clients = pos->next;
169 else 174 else
@@ -285,6 +290,10 @@ transmit_message (void *cls,
285 if (buf == NULL) 290 if (buf == NULL)
286 { 291 {
287 /* 'cl' should be freed via disconnect notification shortly */ 292 /* 'cl' should be freed via disconnect notification shortly */
293#if DEBUG_SERVER_NC
294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
295 "Failed to transmit message from NC queue to client\n");
296#endif
288 return 0; 297 return 0;
289 } 298 }
290 ret = 0; 299 ret = 0;
@@ -310,11 +319,18 @@ transmit_message (void *cls,
310 cl->num_pending--; 319 cl->num_pending--;
311 } 320 }
312 if (cl->pending_head != NULL) 321 if (cl->pending_head != NULL)
313 cl->th = GNUNET_SERVER_notify_transmit_ready (cl->client, 322 {
314 ntohs (cl->pending_head->msg->size), 323#if DEBUG_SERVER_NC
315 GNUNET_TIME_UNIT_FOREVER_REL, 324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
316 &transmit_message, 325 "Have %u messages left in NC queue, will try transmission again\n",
317 cl); 326 cl->num_pending);
327#endif
328 cl->th = GNUNET_SERVER_notify_transmit_ready (cl->client,
329 ntohs (cl->pending_head->msg->size),
330 GNUNET_TIME_UNIT_FOREVER_REL,
331 &transmit_message,
332 cl);
333 }
318 return ret; 334 return ret;
319} 335}
320 336