aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO7
-rw-r--r--src/Makefile.am2
-rw-r--r--src/core/Makefile.am5
-rw-r--r--src/core/core.h143
-rw-r--r--src/core/core_api.c1537
-rw-r--r--src/core/core_api_iterate_peers.c169
-rw-r--r--src/core/core_api_peer_get_info.c175
-rw-r--r--src/core/core_api_peer_request.c179
-rw-r--r--src/core/gnunet-service-core.c364
-rw-r--r--src/core/test_core_api.c19
-rw-r--r--src/core/test_core_api_reliability.c14
-rw-r--r--src/core/test_core_api_start_only.c17
-rw-r--r--src/core/test_core_quota_compliance.c106
-rw-r--r--src/dht/gnunet-dht-driver.c6
-rw-r--r--src/dht/gnunet-service-dht.c59
-rw-r--r--src/dv/Makefile.am2
-rw-r--r--src/dv/gnunet-service-dv.c76
-rw-r--r--src/fs/gnunet-service-fs.c57
-rw-r--r--src/hostlist/gnunet-daemon-hostlist.c20
-rw-r--r--src/hostlist/hostlist-client.c16
-rw-r--r--src/hostlist/hostlist-server.c6
-rw-r--r--src/hostlist/test_gnunet_daemon_hostlist_learning.c11
-rw-r--r--src/include/gnunet_core_service.h78
-rw-r--r--src/include/gnunet_protocols.h19
-rw-r--r--src/include/gnunet_testing_lib.h2
-rw-r--r--src/include/gnunet_transport_plugin.h335
-rw-r--r--src/include/gnunet_transport_service.h338
-rw-r--r--src/testing/test_testing_topology.c7
-rw-r--r--src/testing/testing.c42
-rw-r--r--src/testing/testing_group.c14
-rw-r--r--src/topology/gnunet-daemon-topology.c15
31 files changed, 2170 insertions, 1670 deletions
diff --git a/TODO b/TODO
index e172e3b0d..9d9eccf97 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,11 @@
10.9.0pre2: 10.9.0pre2:
2* BIG CORE REFACTORING:
3 - get testcases to pass again (!)
4 - fix transport service API (ATS!)
5 - fix transport plugin API (ATS!)
6 - actually transmit ATS data through core API
7 - fix FS 'latency' ATS function
8 - fix DV
2* Integration test: 9* Integration test:
3 - test bootstrapping via hostlist + transport/core/dht connect 10 - test bootstrapping via hostlist + transport/core/dht connect
4 11
diff --git a/src/Makefile.am b/src/Makefile.am
index 97a9e8992..3e56a2bcb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,7 @@ SUBDIRS = \
28 peerinfo-tool \ 28 peerinfo-tool \
29 core \ 29 core \
30 testing \ 30 testing \
31 dv \ 31 $(dv) \
32 dht \ 32 dht \
33 hostlist \ 33 hostlist \
34 topology \ 34 topology \
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index ded3d476c..94db94959 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -14,10 +14,7 @@ lib_LTLIBRARIES = \
14 libgnunetcore.la 14 libgnunetcore.la
15 15
16libgnunetcore_la_SOURCES = \ 16libgnunetcore_la_SOURCES = \
17 core_api.c core.h \ 17 core_api.c core.h
18 core_api_peer_get_info.c \
19 core_api_peer_request.c \
20 core_api_iterate_peers.c
21libgnunetcore_la_LIBADD = \ 18libgnunetcore_la_LIBADD = \
22 $(top_builddir)/src/util/libgnunetutil.la \ 19 $(top_builddir)/src/util/libgnunetutil.la \
23 $(GN_LIBINTL) $(XLIB) 20 $(GN_LIBINTL) $(XLIB)
diff --git a/src/core/core.h b/src/core/core.h
index 021aa4184..a8d90b81a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -22,6 +22,17 @@
22 * @file core/core.h 22 * @file core/core.h
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 *
26 * TODO:
27 * - bound message queue size
28 * - on disconnect from core, signal disconnect for all peers
29 * and clean up peer records
30 * - create / destroy peer records on connect/disconnect events
31 * - implement iterator API
32 * - implement re-configure API
33 * - check on peer-related events that connection is known
34 * (if not, GNUNET_break + reconnect)
35 * - handle atsi records
25 */ 36 */
26#include "gnunet_bandwidth_lib.h" 37#include "gnunet_bandwidth_lib.h"
27#include "gnunet_crypto_lib.h" 38#include "gnunet_crypto_lib.h"
@@ -112,9 +123,10 @@ struct ConnectNotifyMessage
112 struct GNUNET_MessageHeader header; 123 struct GNUNET_MessageHeader header;
113 124
114 /** 125 /**
115 * Distance to the peer. 126 * Number of ATS key-value pairs that follow this struct
127 * (excluding the 0-terminator).
116 */ 128 */
117 uint32_t distance GNUNET_PACKED; 129 uint32_t ats_count GNUNET_PACKED;
118 130
119 /** 131 /**
120 * Currently observed latency. 132 * Currently observed latency.
@@ -126,6 +138,12 @@ struct ConnectNotifyMessage
126 */ 138 */
127 struct GNUNET_PeerIdentity peer; 139 struct GNUNET_PeerIdentity peer;
128 140
141 /**
142 * First of the ATS information blocks (we must have at least
143 * one due to the 0-termination requirement).
144 */
145 struct GNUNET_TRANSPORT_ATS_Information ats;
146
129}; 147};
130 148
131 149
@@ -141,14 +159,10 @@ struct PeerStatusNotifyMessage
141 struct GNUNET_MessageHeader header; 159 struct GNUNET_MessageHeader header;
142 160
143 /** 161 /**
144 * Distance to the peer. 162 * Number of ATS key-value pairs that follow this struct
145 */ 163 * (excluding the 0-terminator).
146 uint32_t distance GNUNET_PACKED;
147
148 /**
149 * Currently observed latency.
150 */ 164 */
151 struct GNUNET_TIME_RelativeNBO latency; 165 uint32_t ats_count GNUNET_PACKED;
152 166
153 /** 167 /**
154 * When the peer would time out (unless we see activity) 168 * When the peer would time out (unless we see activity)
@@ -170,6 +184,12 @@ struct PeerStatusNotifyMessage
170 */ 184 */
171 struct GNUNET_PeerIdentity peer; 185 struct GNUNET_PeerIdentity peer;
172 186
187 /**
188 * First of the ATS information blocks (we must have at least
189 * one due to the 0-termination requirement).
190 */
191 struct GNUNET_TRANSPORT_ATS_Information ats;
192
173}; 193};
174 194
175 195
@@ -197,7 +217,6 @@ struct DisconnectNotifyMessage
197}; 217};
198 218
199 219
200
201/** 220/**
202 * Message sent by the service to clients to notify them about 221 * Message sent by the service to clients to notify them about
203 * messages being received or transmitted. This overall message is 222 * messages being received or transmitted. This overall message is
@@ -216,9 +235,10 @@ struct NotifyTrafficMessage
216 struct GNUNET_MessageHeader header; 235 struct GNUNET_MessageHeader header;
217 236
218 /** 237 /**
219 * Distance to the peer. 238 * Number of ATS key-value pairs that follow this struct
239 * (excluding the 0-terminator).
220 */ 240 */
221 uint32_t distance GNUNET_PACKED; 241 uint32_t ats_count GNUNET_PACKED;
222 242
223 /** 243 /**
224 * Currently observed latency. 244 * Currently observed latency.
@@ -230,6 +250,12 @@ struct NotifyTrafficMessage
230 */ 250 */
231 struct GNUNET_PeerIdentity peer; 251 struct GNUNET_PeerIdentity peer;
232 252
253 /**
254 * First of the ATS information blocks (we must have at least
255 * one due to the 0-termination requirement).
256 */
257 struct GNUNET_TRANSPORT_ATS_Information ats;
258
233}; 259};
234 260
235 261
@@ -245,9 +271,9 @@ struct RequestInfoMessage
245 struct GNUNET_MessageHeader header; 271 struct GNUNET_MessageHeader header;
246 272
247 /** 273 /**
248 * Always zero. 274 * Unique request ID.
249 */ 275 */
250 uint32_t reserved GNUNET_PACKED; 276 uint32_t rim_id GNUNET_PACKED;
251 277
252 /** 278 /**
253 * Limit the number of bytes of outbound traffic to this 279 * Limit the number of bytes of outbound traffic to this
@@ -296,10 +322,9 @@ struct ConfigurationInfoMessage
296 int32_t reserved_amount GNUNET_PACKED; 322 int32_t reserved_amount GNUNET_PACKED;
297 323
298 /** 324 /**
299 * Available bandwidth in for this peer. 325 * Unique request ID.
300 * 0 if we have been disconnected.
301 */ 326 */
302 struct GNUNET_BANDWIDTH_Value32NBO bw_in; 327 uint32_t rim_id GNUNET_PACKED;
303 328
304 /** 329 /**
305 * Available bandwidth out for this peer, 330 * Available bandwidth out for this peer,
@@ -314,7 +339,85 @@ struct ConfigurationInfoMessage
314 uint64_t preference; 339 uint64_t preference;
315 340
316 /** 341 /**
317 * Identity of the receiver or sender. 342 * Identity of the peer.
343 */
344 struct GNUNET_PeerIdentity peer;
345
346};
347
348
349/**
350 * Client notifying core about the maximum-priority
351 * message it has in the queue for a particular target.
352 */
353struct SendMessageRequest
354{
355 /**
356 * Header with type GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST
357 */
358 struct GNUNET_MessageHeader header;
359
360 /**
361 * How important is this message?
362 */
363 uint32_t priority GNUNET_PACKED;
364
365 /**
366 * By what time would the sender really like to see this
367 * message transmitted?
368 */
369 struct GNUNET_TIME_AbsoluteNBO deadline;
370
371 /**
372 * Identity of the intended target.
373 */
374 struct GNUNET_PeerIdentity peer;
375
376 /**
377 * How large is the client's message queue for this peer?
378 */
379 uint32_t queue_size GNUNET_PACKED;
380
381 /**
382 * How large is the message?
383 */
384 uint16_t size GNUNET_PACKED;
385
386 /**
387 * Counter for this peer to match SMRs to replies.
388 */
389 uint16_t smr_id GNUNET_PACKED;
390
391};
392
393
394/**
395 * Core notifying client that it is allowed to now
396 * transmit a message to the given target
397 * (response to GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST).
398 */
399struct SendMessageReady
400{
401 /**
402 * Header with type GNUNET_MESSAGE_TYPE_CORE_SEND_READY
403 */
404 struct GNUNET_MessageHeader header;
405
406 /**
407 * How many bytes are allowed for transmission?
408 * Guaranteed to be at least as big as the requested size,
409 * or ZERO if the request is rejected (will timeout,
410 * peer disconnected, queue full, etc.).
411 */
412 uint16_t size GNUNET_PACKED;
413
414 /**
415 * smr_id from the request.
416 */
417 uint16_t smr_id GNUNET_PACKED;
418
419 /**
420 * Identity of the intended target.
318 */ 421 */
319 struct GNUNET_PeerIdentity peer; 422 struct GNUNET_PeerIdentity peer;
320 423
@@ -322,8 +425,8 @@ struct ConfigurationInfoMessage
322 425
323 426
324/** 427/**
325 * Client asking core to transmit a particular message to 428 * Client asking core to transmit a particular message to a particular
326 * a particular target. 429 * target (responsde to GNUNET_MESSAGE_TYPE_CORE_SEND_READY).
327 */ 430 */
328struct SendMessage 431struct SendMessage
329{ 432{
diff --git a/src/core/core_api.c b/src/core/core_api.c
index a1e6aea65..9500a1316 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -23,6 +23,9 @@
23 * @brief core service; this is the main API for encrypted P2P 23 * @brief core service; this is the main API for encrypted P2P
24 * communications 24 * communications
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 *
27 * TODO:
28 * - implement atsi parsing and passing
26 */ 29 */
27#include "platform.h" 30#include "platform.h"
28#include "gnunet_constants.h" 31#include "gnunet_constants.h"
@@ -31,12 +34,124 @@
31 34
32 35
33/** 36/**
37 * Information we track for each peer.
38 */
39struct PeerRecord
40{
41
42 /**
43 * We generally do NOT keep peer records in a DLL; this
44 * DLL is only used IF this peer's 'pending_head' message
45 * is ready for transmission.
46 */
47 struct PeerRecord *prev;
48
49 /**
50 * We generally do NOT keep peer records in a DLL; this
51 * DLL is only used IF this peer's 'pending_head' message
52 * is ready for transmission.
53 */
54 struct PeerRecord *next;
55
56 /**
57 * Peer the record is about.
58 */
59 struct GNUNET_PeerIdentity peer;
60
61 /**
62 * Corresponding core handle.
63 */
64 struct GNUNET_CORE_Handle *ch;
65
66 /**
67 * Head of doubly-linked list of pending requests.
68 * Requests are sorted by deadline *except* for HEAD,
69 * which is only modified upon transmission to core.
70 */
71 struct GNUNET_CORE_TransmitHandle *pending_head;
72
73 /**
74 * Tail of doubly-linked list of pending requests.
75 */
76 struct GNUNET_CORE_TransmitHandle *pending_tail;
77
78 /**
79 * Pending callback waiting for peer information, or NULL for none.
80 */
81 GNUNET_CORE_PeerConfigurationInfoCallback pcic;
82
83 /**
84 * Closure for pcic.
85 */
86 void *pcic_cls;
87
88 /**
89 * Request information ID for the given pcic (needed in case a
90 * request is cancelled after being submitted to core and a new
91 * one is generated; in this case, we need to avoid matching the
92 * reply to the first (cancelled) request to the second request).
93 */
94 uint32_t rim_id;
95
96 /**
97 * ID of timeout task for the 'pending_head' handle
98 * which is the one with the smallest timeout.
99 */
100 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
101
102 /**
103 * Current size of the queue of pending requests.
104 */
105 unsigned int queue_size;
106
107 /**
108 * SendMessageRequest ID generator for this peer.
109 */
110 uint16_t smr_id_gen;
111
112};
113
114
115/**
116 * Entry in a doubly-linked list of control messages to be transmitted
117 * to the core service. Control messages include traffic allocation,
118 * connection requests and of course our initial 'init' request.
119 *
120 * The actual message is allocated at the end of this struct.
121 */
122struct ControlMessage
123{
124 /**
125 * This is a doubly-linked list.
126 */
127 struct ControlMessage *next;
128
129 /**
130 * This is a doubly-linked list.
131 */
132 struct ControlMessage *prev;
133
134 /**
135 * Function to run after successful transmission (or call with
136 * reason 'TIMEOUT' on error).
137 */
138 GNUNET_SCHEDULER_Task cont;
139
140 /**
141 * Closure for 'cont'.
142 */
143 void *cont_cls;
144
145};
146
147
148
149/**
34 * Context for the core service connection. 150 * Context for the core service connection.
35 */ 151 */
36struct GNUNET_CORE_Handle 152struct GNUNET_CORE_Handle
37{ 153{
38 154
39
40 /** 155 /**
41 * Configuration we're using. 156 * Configuration we're using.
42 */ 157 */
@@ -83,9 +198,9 @@ struct GNUNET_CORE_Handle
83 const struct GNUNET_CORE_MessageHandler *handlers; 198 const struct GNUNET_CORE_MessageHandler *handlers;
84 199
85 /** 200 /**
86 * Our connection to the service for notifications. 201 * Our connection to the service.
87 */ 202 */
88 struct GNUNET_CLIENT_Connection *client_notifications; 203 struct GNUNET_CLIENT_Connection *client;
89 204
90 /** 205 /**
91 * Handle for our current transmission request. 206 * Handle for our current transmission request.
@@ -95,41 +210,43 @@ struct GNUNET_CORE_Handle
95 /** 210 /**
96 * Head of doubly-linked list of pending requests. 211 * Head of doubly-linked list of pending requests.
97 */ 212 */
98 struct GNUNET_CORE_TransmitHandle *pending_head; 213 struct ControlMessage *pending_head;
99 214
100 /** 215 /**
101 * Tail of doubly-linked list of pending requests. 216 * Tail of doubly-linked list of pending requests.
102 */ 217 */
103 struct GNUNET_CORE_TransmitHandle *pending_tail; 218 struct ControlMessage *pending_tail;
104 219
105 /** 220 /**
106 * Currently submitted request (or NULL) 221 * Head of doubly-linked list of peers that are core-approved
222 * to send their next message.
107 */ 223 */
108 struct GNUNET_CORE_TransmitHandle *submitted; 224 struct PeerRecord *ready_peer_head;
109 225
110 /** 226 /**
111 * Currently submitted request based on solicitation (or NULL) 227 * Tail of doubly-linked list of peers that are core-approved
228 * to send their next message.
112 */ 229 */
113 struct GNUNET_CORE_TransmitHandle *solicit_transmit_req; 230 struct PeerRecord *ready_peer_tail;
114 231
115 /** 232 /**
116 * Buffer where we store a message for transmission in response 233 * Hash map listing all of the peers that we are currently
117 * to a traffic solicitation (or NULL). 234 * connected to.
118 */ 235 */
119 char *solicit_buffer; 236 struct GNUNET_CONTAINER_MultiHashMap *peers;
120 237
121 /** 238 /**
122 * How long to wait until we time out the connection attempt? 239 * ID of reconnect task (if any).
123 */ 240 */
124 struct GNUNET_TIME_Absolute startup_timeout; 241 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
125 242
126 /** 243 /**
127 * ID of reconnect task (if any). 244 * Request information ID generator.
128 */ 245 */
129 GNUNET_SCHEDULER_TaskIdentifier reconnect_task; 246 uint32_t rim_id_gen;
130 247
131 /** 248 /**
132 * Number of messages we should queue per target. 249 * Number of messages we are allowed to queue per target.
133 */ 250 */
134 unsigned int queue_size; 251 unsigned int queue_size;
135 252
@@ -155,6 +272,7 @@ struct GNUNET_CORE_Handle
155 * requests? 272 * requests?
156 */ 273 */
157 int currently_down; 274 int currently_down;
275
158}; 276};
159 277
160 278
@@ -175,9 +293,15 @@ struct GNUNET_CORE_TransmitHandle
175 struct GNUNET_CORE_TransmitHandle *prev; 293 struct GNUNET_CORE_TransmitHandle *prev;
176 294
177 /** 295 /**
178 * Corresponding core handle. 296 * Corresponding peer record.
179 */ 297 */
180 struct GNUNET_CORE_Handle *ch; 298 struct PeerRecord *peer;
299
300 /**
301 * Corresponding SEND_REQUEST message. Only non-NULL
302 * while SEND_REQUEST message is pending.
303 */
304 struct ControlMessage *cm;
181 305
182 /** 306 /**
183 * Function that will be called to get the actual request 307 * Function that will be called to get the actual request
@@ -193,32 +317,11 @@ struct GNUNET_CORE_TransmitHandle
193 void *get_message_cls; 317 void *get_message_cls;
194 318
195 /** 319 /**
196 * If this entry is for a transmission request, pointer
197 * to the notify callback; otherwise NULL.
198 */
199 GNUNET_CONNECTION_TransmitReadyNotify notify;
200
201 /**
202 * Closure for notify.
203 */
204 void *notify_cls;
205
206 /**
207 * Peer the request is about.
208 */
209 struct GNUNET_PeerIdentity peer;
210
211 /**
212 * Timeout for this handle. 320 * Timeout for this handle.
213 */ 321 */
214 struct GNUNET_TIME_Absolute timeout; 322 struct GNUNET_TIME_Absolute timeout;
215 323
216 /** 324 /**
217 * ID of timeout task.
218 */
219 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
220
221 /**
222 * How important is this message? 325 * How important is this message?
223 */ 326 */
224 uint32_t priority; 327 uint32_t priority;
@@ -228,54 +331,127 @@ struct GNUNET_CORE_TransmitHandle
228 */ 331 */
229 uint16_t msize; 332 uint16_t msize;
230 333
334 /**
335 * Send message request ID for this request.
336 */
337 uint16_t smr_id;
231 338
232}; 339};
233 340
234 341
342/**
343 * Our current client connection went down. Clean it up
344 * and try to reconnect!
345 *
346 * @param h our handle to the core service
347 */
348static void
349reconnect (struct GNUNET_CORE_Handle *h);
350
351
352/**
353 * Task schedule to try to re-connect to core.
354 *
355 * @param cls the 'struct GNUNET_CORE_Handle'
356 * @param tc task context
357 */
358static void
359reconnect_task (void *cls,
360 const struct GNUNET_SCHEDULER_TaskContext *tc)
361{
362 struct GNUNET_CORE_Handle *h = cls;
363
364 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
365 reconnect (h);
366}
367
368
369/**
370 * Check the list of pending requests, send the next
371 * one to the core.
372 *
373 * @param h core handle
374 */
235static void 375static void
236reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 376trigger_next_request (struct GNUNET_CORE_Handle *h);
237 377
238 378
239/** 379/**
240 * Function called when we are ready to transmit our 380 * The given request hit its timeout. Remove from the
241 * "START" message (or when this operation timed out). 381 * doubly-linked list and call the respective continuation.
242 * 382 *
243 * @param cls closure 383 * @param cls the transmit handle of the request that timed out
244 * @param size number of bytes available in buf 384 * @param tc context, can be NULL (!)
245 * @param buf where the callee should write the message
246 * @return number of bytes written to buf
247 */ 385 */
248static size_t transmit_start (void *cls, size_t size, void *buf); 386static void
387transmission_timeout (void *cls,
388 const struct GNUNET_SCHEDULER_TaskContext *tc);
249 389
250 390
251/** 391/**
252 * Our current client connection went down. Clean it up 392 * Control message was sent, mark it as such.
253 * and try to reconnect!
254 * 393 *
255 * @param h our handle to the core service 394 * @param cls the 'struct GNUNET_CORE_TransmitHandle*'
395 * @param tc scheduler context
256 */ 396 */
257static void 397static void
258reconnect (struct GNUNET_CORE_Handle *h) 398mark_control_message_sent (void *cls,
399 const struct GNUNET_SCHEDULER_TaskContext *tc)
259{ 400{
260#if DEBUG_CORE 401 struct GNUNET_CORE_TransmitHandle *th = cls;
261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 402
262 "Reconnecting to CORE service\n"); 403 th->cm = NULL;
263#endif 404}
264 if (h->client_notifications != NULL) 405
265 GNUNET_CLIENT_disconnect (h->client_notifications, GNUNET_NO); 406
266 h->currently_down = GNUNET_YES; 407/**
267 h->client_notifications = GNUNET_CLIENT_connect ("core", h->cfg); 408 * Send a control message to the peer asking for transmission
268 if (h->client_notifications == NULL) 409 * of the message in the given peer record.
269 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 410 *
270 &reconnect_task, 411 * @param pr peer to request transmission to
271 h); 412 */
272 else 413static void
273 h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, 414request_next_transmission (struct PeerRecord *pr)
274 sizeof (struct InitMessage) + 415{
275 sizeof (uint16_t) * h->hcnt, 416 struct GNUNET_CORE_Handle *h = pr->ch;
276 GNUNET_TIME_UNIT_SECONDS, 417 struct ControlMessage *cm;
277 GNUNET_NO, 418 struct SendMessageRequest *smr;
278 &transmit_start, h); 419 struct GNUNET_CORE_TransmitHandle *th;
420
421 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
422 {
423 GNUNET_SCHEDULER_cancel (pr->timeout_task);
424 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
425 }
426 if (NULL == (th = pr->pending_head))
427 {
428 trigger_next_request (h);
429 return;
430 }
431 GNUNET_assert (pr->prev == NULL);
432 GNUNET_assert (pr->next == NULL);
433 pr->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (th->timeout),
434 &transmission_timeout,
435 pr);
436 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
437 sizeof (struct SendMessageRequest));
438 cm->cont = &mark_control_message_sent;
439 cm->cont_cls = th;
440 th->cm = cm;
441 smr = (struct SendMessageRequest*) &cm[1];
442 smr->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST);
443 smr->header.size = htons (sizeof (struct SendMessageRequest));
444 smr->priority = htonl (th->priority);
445 smr->deadline = GNUNET_TIME_absolute_hton (th->timeout);
446 smr->peer = pr->peer;
447 smr->queue_size = htonl (pr->queue_size);
448 smr->size = htons (th->msize);
449 smr->smr_id = htons (th->smr_id = pr->smr_id_gen++);
450 GNUNET_CONTAINER_DLL_insert_after (h->pending_head,
451 h->pending_tail,
452 h->pending_tail,
453 cm);
454 trigger_next_request (h);
279} 455}
280 456
281 457
@@ -287,97 +463,225 @@ reconnect (struct GNUNET_CORE_Handle *h)
287 * @param tc context, can be NULL (!) 463 * @param tc context, can be NULL (!)
288 */ 464 */
289static void 465static void
290timeout_request (void *cls, 466transmission_timeout (void *cls,
291 const struct GNUNET_SCHEDULER_TaskContext *tc) 467 const struct GNUNET_SCHEDULER_TaskContext *tc)
292{ 468{
293 struct GNUNET_CORE_TransmitHandle *th = cls; 469 struct PeerRecord *pr = cls;
470 struct GNUNET_CORE_TransmitHandle *th;
294 471
295 th->timeout_task = GNUNET_SCHEDULER_NO_TASK; 472 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
296 GNUNET_CONTAINER_DLL_remove (th->ch->pending_head, 473 th = pr->pending_head;
297 th->ch->pending_tail, 474 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
475 pr->pending_tail,
298 th); 476 th);
477 pr->queue_size--;
299#if DEBUG_CORE 478#if DEBUG_CORE
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301 "Signalling timeout of request for transmission to CORE service\n"); 480 "Signalling timeout of request for transmission to CORE service\n");
302#endif 481#endif
303 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); 482 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
483 request_next_transmission (pr);
304} 484}
305 485
306 486
307/** 487/**
308 * Function called when we are ready to transmit a request from our 488 * Transmit the next message to the core service.
309 * request list (or when this operation timed out).
310 *
311 * @param cls closure
312 * @param size number of bytes available in buf
313 * @param buf where the callee should write the message
314 * @return number of bytes written to buf
315 */ 489 */
316static size_t 490static size_t
317request_start (void *cls, size_t size, void *buf) 491transmit_message (void *cls,
492 size_t size,
493 void *buf)
318{ 494{
319 struct GNUNET_CORE_Handle *h = cls; 495 struct GNUNET_CORE_Handle *h = cls;
496 struct ControlMessage *cm;
320 struct GNUNET_CORE_TransmitHandle *th; 497 struct GNUNET_CORE_TransmitHandle *th;
498 struct PeerRecord *pr;
499 struct SendMessage *sm;
500 const struct GNUNET_MessageHeader *hdr;
501 uint16_t msize;
321 size_t ret; 502 size_t ret;
322 503
323 h->cth = NULL; 504 h->cth = NULL;
324 th = h->pending_head;
325 if (th == NULL)
326 return 0;
327 if (buf == NULL) 505 if (buf == NULL)
328 { 506 {
329 if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK) 507 reconnect (h);
508 return 0;
509 }
510 /* first check for control messages */
511 if (NULL != (cm = h->pending_head))
512 {
513 hdr = (const struct GNUNET_MessageHeader*) &cm[1];
514 msize = ntohs (hdr->size);
515 if (size < msize)
330 { 516 {
331 GNUNET_SCHEDULER_cancel(th->timeout_task); 517 trigger_next_request (h);
332 th->timeout_task = GNUNET_SCHEDULER_NO_TASK; 518 return 0;
333 } 519 }
334 timeout_request (th, NULL); 520 memcpy (buf, hdr, msize);
335 return 0; 521 GNUNET_CONTAINER_DLL_remove (h->pending_head,
522 h->pending_tail,
523 cm);
524 if (NULL != cm->cont)
525 GNUNET_SCHEDULER_add_now (cm->cont, cm->cont_cls);
526 GNUNET_free (cm);
527 trigger_next_request (h);
528 return msize;
336 } 529 }
337 GNUNET_CONTAINER_DLL_remove (h->pending_head, 530 /* now check for 'ready' P2P messages */
338 h->pending_tail, 531 if (NULL != (pr = h->ready_peer_head))
339 th); 532 {
340 GNUNET_assert (h->submitted == NULL); 533 th = pr->pending_head;
341 h->submitted = th; 534 if (size < th->msize + sizeof (struct SendMessage))
342 GNUNET_assert (size >= th->msize); 535 {
343 ret = th->get_message (th->get_message_cls, size, buf); 536 trigger_next_request (h);
344 GNUNET_assert (ret <= size); 537 return 0;
538 }
539 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
540 h->ready_peer_tail,
541 pr);
542 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
543 pr->pending_tail,
544 th);
545 pr->queue_size--;
546 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
547 {
548 GNUNET_SCHEDULER_cancel (pr->timeout_task);
549 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
550 }
551
552 sm = (struct SendMessage *) buf;
553 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
554 sm->priority = htonl (th->priority);
555 sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
556 sm->peer = pr->peer;
557 ret = th->get_message (th->get_message_cls,
558 size - sizeof (struct SendMessage),
559 &sm[1]);
560
561 if (0 == ret)
562 {
345#if DEBUG_CORE 563#if DEBUG_CORE
346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
347 "Transmitting %u bytes to core\n", 565 "Size of clients message to peer %s is 0!\n",
348 ret); 566 GNUNET_i2s(&pr->peer));
349#endif 567#endif
350 return ret; 568 /* client decided to send nothing! */
569 request_next_transmission (pr);
570 return 0;
571 }
572#if DEBUG_CORE
573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
574 "Produced SEND message to core with %u bytes payload\n",
575 (unsigned int) ret);
576#endif
577 GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader));
578 if (ret + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
579 {
580 GNUNET_break (0);
581 request_next_transmission (pr);
582 return 0;
583 }
584 ret += sizeof (struct SendMessage);
585 sm->header.size = htons (ret);
586 GNUNET_assert (ret <= size);
587 GNUNET_free (th);
588 request_next_transmission (pr);
589 return ret;
590 }
591 return 0;
351} 592}
352 593
353 594
354/** 595/**
355 * Check the list of pending requests, send the next 596 * Check the list of pending requests, send the next
356 * one to the core. 597 * one to the core.
598 *
599 * @param h core handle
357 */ 600 */
358static void 601static void
359trigger_next_request (struct GNUNET_CORE_Handle *h) 602trigger_next_request (struct GNUNET_CORE_Handle *h)
360{ 603{
604 uint16_t msize;
605
606 if (GNUNET_YES == h->currently_down)
607 return;
608 if (NULL != h->cth)
609 return;
610 if (h->pending_head != NULL)
611 msize = ntohs (((struct GNUNET_MessageHeader*) &h->pending_head[1])->size);
612 else if (h->ready_peer_head != NULL)
613 msize = h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage);
614 else
615 return; /* no pending message */
616 h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client,
617 msize,
618 GNUNET_TIME_UNIT_FOREVER_REL,
619 GNUNET_NO,
620 &transmit_message, h);
621}
622
623
624
625
626/**
627 * Notify clients about disconnect and free
628 * the entry for connected peer.
629 *
630 * @param cls the 'struct GNUNET_CORE_Handle*'
631 * @param key the peer identity (not used)
632 * @param value the 'struct PeerRecord' to free.
633 * @return GNUNET_YES (continue)
634 */
635static int
636disconnect_and_free_peer_entry (void *cls,
637 const GNUNET_HashCode *key,
638 void *value)
639{
640 struct GNUNET_CORE_Handle *h = cls;
361 struct GNUNET_CORE_TransmitHandle *th; 641 struct GNUNET_CORE_TransmitHandle *th;
642 struct PeerRecord *pr = value;
362 643
363 if (h->currently_down) 644 while (NULL != (th = pr->pending_head))
364 { 645 {
365#if DEBUG_CORE 646 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 647 pr->pending_tail,
367 "In trigger_next_request, connection currently down...\n"); 648 th);
368#endif 649 pr->queue_size--;
369 return; /* connection temporarily down */ 650 GNUNET_assert (0 ==
651 th->get_message (th->get_message_cls,
652 0, NULL));
653 GNUNET_free (th);
370 } 654 }
371 if (NULL == (th = h->pending_head)) 655 if (pr->pcic != NULL)
372 return; /* no requests pending */ 656 {
373 GNUNET_assert (NULL == h->cth); 657 // FIXME: call pcic callback!
374 h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, 658 }
375 th->msize, 659 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
376 GNUNET_TIME_absolute_get_remaining 660 {
377 (th->timeout), 661 GNUNET_SCHEDULER_cancel (pr->timeout_task);
378 GNUNET_NO, 662 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
379 &request_start, 663 }
380 h); 664 GNUNET_assert (pr->queue_size == 0);
665 if ( (pr->prev != NULL) ||
666 (pr->next != NULL) ||
667 (h->ready_peer_head == pr) )
668 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
669 h->ready_peer_tail,
670 pr);
671 if (h->disconnects != NULL)
672 h->disconnects (h->cls,
673 &pr->peer);
674 GNUNET_assert (GNUNET_YES ==
675 GNUNET_CONTAINER_multihashmap_remove (h->peers,
676 key,
677 pr));
678 GNUNET_assert (pr->pending_head == NULL);
679 GNUNET_assert (pr->pending_tail == NULL);
680 GNUNET_assert (pr->ch = h);
681 GNUNET_assert (pr->queue_size == 0);
682 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
683 GNUNET_free (pr);
684 return GNUNET_YES;
381} 685}
382 686
383 687
@@ -388,18 +692,28 @@ trigger_next_request (struct GNUNET_CORE_Handle *h)
388 * @param msg the message received from the core service 692 * @param msg the message received from the core service
389 */ 693 */
390static void 694static void
391main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) 695main_notify_handler (void *cls,
696 const struct GNUNET_MessageHeader *msg)
392{ 697{
393 struct GNUNET_CORE_Handle *h = cls; 698 struct GNUNET_CORE_Handle *h = cls;
394 unsigned int hpos; 699 const struct InitReplyMessage *m;
395 const struct ConnectNotifyMessage *cnm; 700 const struct ConnectNotifyMessage *cnm;
396 const struct DisconnectNotifyMessage *dnm; 701 const struct DisconnectNotifyMessage *dnm;
397 const struct NotifyTrafficMessage *ntm; 702 const struct NotifyTrafficMessage *ntm;
398 const struct GNUNET_MessageHeader *em; 703 const struct GNUNET_MessageHeader *em;
704 const struct ConfigurationInfoMessage *cim;
399 const struct PeerStatusNotifyMessage *psnm; 705 const struct PeerStatusNotifyMessage *psnm;
706 const struct SendMessageReady *smr;
707 const struct GNUNET_CORE_MessageHandler *mh;
708 GNUNET_CORE_StartupCallback init;
709 GNUNET_CORE_PeerConfigurationInfoCallback pcic;
710 struct GNUNET_PeerIdentity my_identity;
711 struct PeerRecord *pr;
712 struct GNUNET_CORE_TransmitHandle *th;
713 unsigned int hpos;
714 int trigger;
400 uint16_t msize; 715 uint16_t msize;
401 uint16_t et; 716 uint16_t et;
402 const struct GNUNET_CORE_MessageHandler *mh;
403 717
404 if (msg == NULL) 718 if (msg == NULL)
405 { 719 {
@@ -417,37 +731,85 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
417#endif 731#endif
418 switch (ntohs (msg->type)) 732 switch (ntohs (msg->type))
419 { 733 {
734 case GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY:
735 if (ntohs (msg->size) != sizeof (struct InitReplyMessage))
736 {
737 GNUNET_break (0);
738 reconnect (h);
739 return;
740 }
741 m = (const struct InitReplyMessage *) msg;
742 GNUNET_break (0 == ntohl (m->reserved));
743 /* start our message processing loop */
744#if DEBUG_CORE
745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
746 "Successfully connected to core service, starting processing loop.\n");
747#endif
748 if (GNUNET_YES == h->currently_down)
749 {
750 h->currently_down = GNUNET_NO;
751 trigger_next_request (h);
752 }
753 if (NULL != (init = h->init))
754 {
755 /* mark so we don't call init on reconnect */
756 h->init = NULL;
757 GNUNET_CRYPTO_hash (&m->publicKey,
758 sizeof (struct
759 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
760 &my_identity.hashPubKey);
761 init (h->cls, h, &my_identity, &m->publicKey);
762 }
763 break;
420 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: 764 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
421 if (NULL == h->connects)
422 {
423 GNUNET_break (0);
424 break;
425 }
426 if (msize != sizeof (struct ConnectNotifyMessage)) 765 if (msize != sizeof (struct ConnectNotifyMessage))
427 { 766 {
428 GNUNET_break (0); 767 GNUNET_break (0);
429 break; 768 break;
430 } 769 }
431 cnm = (const struct ConnectNotifyMessage *) msg; 770 cnm = (const struct ConnectNotifyMessage *) msg;
432 h->connects (h->cls, 771 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
433 &cnm->peer, 772 &cnm->peer.hashPubKey);
434 GNUNET_TIME_relative_ntoh (cnm->latency), 773 if (pr != NULL)
435 ntohl (cnm->distance)); 774 {
775 GNUNET_break (0);
776 reconnect (h);
777 return;
778 }
779 pr = GNUNET_malloc (sizeof (struct PeerRecord));
780 pr->peer = cnm->peer;
781 pr->ch = h;
782 GNUNET_assert (GNUNET_YES ==
783 GNUNET_CONTAINER_multihashmap_put (h->peers,
784 &cnm->peer.hashPubKey,
785 pr,
786 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
787 if (NULL != h->connects)
788 h->connects (h->cls,
789 &cnm->peer,
790 NULL /* FIXME: atsi! */);
436 break; 791 break;
437 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT: 792 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT:
438 if (NULL == h->disconnects)
439 {
440 GNUNET_break (0);
441 break;
442 }
443 if (msize != sizeof (struct DisconnectNotifyMessage)) 793 if (msize != sizeof (struct DisconnectNotifyMessage))
444 { 794 {
445 GNUNET_break (0); 795 GNUNET_break (0);
446 break; 796 break;
447 } 797 }
448 dnm = (const struct DisconnectNotifyMessage *) msg; 798 dnm = (const struct DisconnectNotifyMessage *) msg;
449 h->disconnects (h->cls, 799 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
450 &dnm->peer); 800 &dnm->peer.hashPubKey);
801 if (pr == NULL)
802 {
803 GNUNET_break (0);
804 reconnect (h);
805 return;
806 }
807 trigger = ( (pr->prev != NULL) ||
808 (pr->next != NULL) ||
809 (h->ready_peer_head == pr) );
810 disconnect_and_free_peer_entry (h, &dnm->peer.hashPubKey, pr);
811 if (trigger)
812 trigger_next_request (h);
451 break; 813 break;
452 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE: 814 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
453 if (NULL == h->status_events) 815 if (NULL == h->status_events)
@@ -461,13 +823,20 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
461 break; 823 break;
462 } 824 }
463 psnm = (const struct PeerStatusNotifyMessage *) msg; 825 psnm = (const struct PeerStatusNotifyMessage *) msg;
826 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
827 &psnm->peer.hashPubKey);
828 if (pr == NULL)
829 {
830 GNUNET_break (0);
831 reconnect (h);
832 return;
833 }
464 h->status_events (h->cls, 834 h->status_events (h->cls,
465 &psnm->peer, 835 &psnm->peer,
466 GNUNET_TIME_relative_ntoh (psnm->latency),
467 ntohl (psnm->distance),
468 psnm->bandwidth_in, 836 psnm->bandwidth_in,
469 psnm->bandwidth_out, 837 psnm->bandwidth_out,
470 GNUNET_TIME_absolute_ntoh (psnm->timeout)); 838 GNUNET_TIME_absolute_ntoh (psnm->timeout),
839 NULL /* FIXME: atsi */);
471 break; 840 break;
472 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND: 841 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
473 if (msize < 842 if (msize <
@@ -486,6 +855,14 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
486 ntohs (em->size), 855 ntohs (em->size),
487 GNUNET_i2s (&ntm->peer)); 856 GNUNET_i2s (&ntm->peer));
488#endif 857#endif
858 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
859 &ntm->peer.hashPubKey);
860 if (pr == NULL)
861 {
862 GNUNET_break (0);
863 reconnect (h);
864 return;
865 }
489 if ((GNUNET_NO == h->inbound_hdr_only) && 866 if ((GNUNET_NO == h->inbound_hdr_only) &&
490 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage))) 867 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
491 { 868 {
@@ -506,8 +883,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
506 } 883 }
507 if (GNUNET_OK != 884 if (GNUNET_OK !=
508 h->handlers[hpos].callback (h->cls, &ntm->peer, em, 885 h->handlers[hpos].callback (h->cls, &ntm->peer, em,
509 GNUNET_TIME_relative_ntoh (ntm->latency), 886 NULL /* FIXME: atsi */))
510 ntohl (ntm->distance)))
511 { 887 {
512 /* error in processing, do not process other messages! */ 888 /* error in processing, do not process other messages! */
513 break; 889 break;
@@ -515,8 +891,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
515 } 891 }
516 if (NULL != h->inbound_notify) 892 if (NULL != h->inbound_notify)
517 h->inbound_notify (h->cls, &ntm->peer, em, 893 h->inbound_notify (h->cls, &ntm->peer, em,
518 GNUNET_TIME_relative_ntoh (ntm->latency), 894 NULL /* FIXME: atsi */);
519 ntohl (ntm->distance));
520 break; 895 break;
521 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND: 896 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND:
522 if (msize < 897 if (msize <
@@ -528,6 +903,14 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
528 } 903 }
529 ntm = (const struct NotifyTrafficMessage *) msg; 904 ntm = (const struct NotifyTrafficMessage *) msg;
530 em = (const struct GNUNET_MessageHeader *) &ntm[1]; 905 em = (const struct GNUNET_MessageHeader *) &ntm[1];
906 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
907 &ntm->peer.hashPubKey);
908 if (pr == NULL)
909 {
910 GNUNET_break (0);
911 reconnect (h);
912 return;
913 }
531 if ((GNUNET_NO == h->outbound_hdr_only) && 914 if ((GNUNET_NO == h->outbound_hdr_only) &&
532 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage))) 915 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
533 { 916 {
@@ -540,159 +923,157 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
540 break; 923 break;
541 } 924 }
542 h->outbound_notify (h->cls, &ntm->peer, em, 925 h->outbound_notify (h->cls, &ntm->peer, em,
543 GNUNET_TIME_relative_ntoh (ntm->latency), 926 NULL /* FIXME: atsi? */);
544 ntohl (ntm->distance)); 927 break;
928 case GNUNET_MESSAGE_TYPE_CORE_SEND_READY:
929 if (msize != sizeof (struct SendMessageReady))
930 {
931 GNUNET_break (0);
932 break;
933 }
934 smr = (const struct SendMessageReady *) msg;
935 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
936 &smr->peer.hashPubKey);
937 if (pr == NULL)
938 {
939 GNUNET_break (0);
940 reconnect (h);
941 return;
942 }
943 th = pr->pending_head;
944 if (ntohs (smr->smr_id) != th->smr_id)
945 {
946 /* READY message is for expired or cancelled message,
947 ignore! (we should have already sent another request) */
948 break;
949 }
950 if ( (pr->prev != NULL) ||
951 (pr->next != NULL) ||
952 (h->ready_peer_head == pr) )
953 {
954 /* we should not already be on the ready list... */
955 GNUNET_break (0);
956 reconnect (h);
957 return;
958 }
959 GNUNET_CONTAINER_DLL_insert (h->ready_peer_head,
960 h->ready_peer_tail,
961 pr);
962 trigger_next_request (h);
963 break;
964 case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO:
965 if (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage))
966 {
967 GNUNET_break (0);
968 break;
969 }
970 cim = (const struct ConfigurationInfoMessage*) msg;
971 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
972 &cim->peer.hashPubKey);
973 if (pr == NULL)
974 {
975 GNUNET_break (0);
976 reconnect (h);
977 return;
978 }
979 if (pr->rim_id != ntohl (cim->rim_id))
980 break;
981 pcic = pr->pcic;
982 pr->pcic = NULL;
983 if (pcic != NULL)
984 pcic (pr->pcic_cls,
985 &pr->peer,
986 cim->bw_out,
987 ntohl (cim->reserved_amount),
988 GNUNET_ntohll (cim->preference));
545 break; 989 break;
546 default: 990 default:
547 GNUNET_break (0); 991 GNUNET_break (0);
548 break; 992 break;
549 } 993 }
550 GNUNET_CLIENT_receive (h->client_notifications, 994 GNUNET_CLIENT_receive (h->client,
551 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); 995 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
552} 996}
553 997
554 998
555/** 999/**
556 * Function called when we are ready to transmit our 1000 * Task executed once we are done transmitting the INIT message.
557 * "START" message (or when this operation timed out). 1001 * Starts our 'receive' loop.
558 * 1002 *
559 * @param cls closure 1003 * @param cls the 'struct GNUNET_CORE_Handle'
560 * @param size number of bytes available in buf 1004 * @param tc task context
561 * @param buf where the callee should write the message
562 * @return number of bytes written to buf
563 */
564static size_t transmit_start (void *cls, size_t size, void *buf);
565
566
567/**
568 * Function called on the first message received from
569 * the service (contains our public key, etc.).
570 * Should trigger calling the init callback
571 * and then start our regular message processing.
572 *
573 * @param cls closure
574 * @param msg message received, NULL on timeout or fatal error
575 */ 1005 */
576static void 1006static void
577init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) 1007init_done_task (void *cls,
1008 const struct GNUNET_SCHEDULER_TaskContext *tc)
578{ 1009{
579 struct GNUNET_CORE_Handle *h = cls; 1010 struct GNUNET_CORE_Handle *h = cls;
580 const struct InitReplyMessage *m;
581 GNUNET_CORE_StartupCallback init;
582 struct GNUNET_PeerIdentity my_identity;
583 1011
584 if ((msg == NULL) || 1012 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
585 (ntohs (msg->size) != sizeof (struct InitReplyMessage)) ||
586 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY))
587 { 1013 {
588 if (msg != NULL) 1014 if (h->client != NULL)
589 {
590 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
591 _
592 ("Error connecting to core service (failed to receive `%s' message, got message of type %u and size %u).\n"),
593 "INIT_REPLY",
594 ntohs (msg->type),
595 ntohs (msg->size));
596 GNUNET_break (0);
597 }
598 else
599 { 1015 {
600#if DEBUG_CORE 1016 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1017 h->client = NULL;
602 _("Failed to connect to core service, will retry.\n"));
603#endif
604 } 1018 }
605 transmit_start (h, 0, NULL); 1019 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
1020 &reconnect_task,
1021 h);
606 return; 1022 return;
607 } 1023 }
608 m = (const struct InitReplyMessage *) msg; 1024 GNUNET_CLIENT_receive (h->client,
609 GNUNET_break (0 == ntohl (m->reserved)); 1025 &main_notify_handler,
610 /* start our message processing loop */ 1026 h,
611#if DEBUG_CORE 1027 GNUNET_TIME_UNIT_FOREVER_REL);
612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
613 "Successfully connected to core service, starting processing loop.\n");
614#endif
615 h->currently_down = GNUNET_NO;
616 trigger_next_request (h);
617 GNUNET_CLIENT_receive (h->client_notifications,
618 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
619 if (NULL != (init = h->init))
620 {
621 /* mark so we don't call init on reconnect */
622 h->init = NULL;
623 GNUNET_CRYPTO_hash (&m->publicKey,
624 sizeof (struct
625 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
626 &my_identity.hashPubKey);
627 init (h->cls, h, &my_identity, &m->publicKey);
628 }
629}
630
631
632static void
633reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
634{
635 struct GNUNET_CORE_Handle *h = cls;
636 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
637 reconnect (h);
638} 1028}
639 1029
640 1030
641/** 1031/**
642 * Function called when we are ready to transmit our 1032 * Our current client connection went down. Clean it up
643 * "START" message (or when this operation timed out). 1033 * and try to reconnect!
644 * 1034 *
645 * @param cls closure 1035 * @param h our handle to the core service
646 * @param size number of bytes available in buf
647 * @param buf where the callee should write the message
648 * @return number of bytes written to buf
649 */ 1036 */
650static size_t 1037static void
651transmit_start (void *cls, size_t size, void *buf) 1038reconnect (struct GNUNET_CORE_Handle *h)
652{ 1039{
653 struct GNUNET_CORE_Handle *h = cls; 1040 struct ControlMessage *cm;
654 struct InitMessage *init; 1041 struct InitMessage *init;
655 uint16_t *ts;
656 uint16_t msize;
657 uint32_t opt; 1042 uint32_t opt;
1043 uint16_t msize;
1044 uint16_t *ts;
658 unsigned int hpos; 1045 unsigned int hpos;
659 struct GNUNET_TIME_Relative delay;
660 1046
661 h->cth = NULL; 1047#if DEBUG_CORE
662 if (size == 0) 1048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1049 "Reconnecting to CORE service\n");
1050#endif
1051 if (h->client != NULL)
663 { 1052 {
664 if ((h->init == NULL) || 1053 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
665 (GNUNET_TIME_absolute_get ().abs_value < h->startup_timeout.abs_value)) 1054 h->client = NULL;
666 { 1055 GNUNET_CONTAINER_multihashmap_iterate (h->peers,
667 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1056 &disconnect_and_free_peer_entry,
668 _("Failed to connect to core service, retrying.\n")); 1057 h);
669 delay = GNUNET_TIME_absolute_get_remaining (h->startup_timeout); 1058 }
670 if ((h->init == NULL) || (delay.rel_value > 1000)) 1059 h->currently_down = GNUNET_YES;
671 delay = GNUNET_TIME_UNIT_SECONDS; 1060 h->client = GNUNET_CLIENT_connect ("core", h->cfg);
672 if (h->init == NULL) 1061 if (h->client == NULL)
673 h->startup_timeout = 1062 {
674 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); 1063 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
675 h->reconnect_task = 1064 &reconnect_task,
676 GNUNET_SCHEDULER_add_delayed (delay, &reconnect_task, h); 1065 h);
677 return 0; 1066 return;
678 }
679 /* timeout on initial connect */
680 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
681 _("Failed to connect to core service, giving up.\n"));
682 h->init (h->cls, NULL, NULL, NULL);
683 GNUNET_CORE_disconnect (h);
684 return 0;
685 } 1067 }
686 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage); 1068 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage);
687 GNUNET_assert (size >= msize); 1069 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
688 init = buf; 1070 msize);
1071 cm->cont = &init_done_task;
1072 cm->cont_cls = h;
1073 init = (struct InitMessage*) &cm[1];
689 init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT); 1074 init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
690 init->header.size = htons (msize); 1075 init->header.size = htons (msize);
691 opt = GNUNET_CORE_OPTION_NOTHING; 1076 opt = GNUNET_CORE_OPTION_SEND_CONNECT | GNUNET_CORE_OPTION_SEND_DISCONNECT;
692 if (h->connects != NULL)
693 opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
694 if (h->disconnects != NULL)
695 opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
696 if (h->status_events != NULL) 1077 if (h->status_events != NULL)
697 opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE; 1078 opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
698 if (h->inbound_notify != NULL) 1079 if (h->inbound_notify != NULL)
@@ -710,25 +1091,23 @@ transmit_start (void *cls, size_t size, void *buf)
710 opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND; 1091 opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND;
711 } 1092 }
712 init->options = htonl (opt); 1093 init->options = htonl (opt);
713 ts = (uint16_t *) & init[1]; 1094 ts = (uint16_t *) &init[1];
714 for (hpos = 0; hpos < h->hcnt; hpos++) 1095 for (hpos = 0; hpos < h->hcnt; hpos++)
715 ts[hpos] = htons (h->handlers[hpos].type); 1096 ts[hpos] = htons (h->handlers[hpos].type);
716 GNUNET_CLIENT_receive (h->client_notifications, 1097 GNUNET_CONTAINER_DLL_insert (h->pending_head,
717 &init_reply_handler, 1098 h->pending_tail,
718 h, 1099 cm);
719 GNUNET_TIME_absolute_get_remaining 1100 trigger_next_request (h);
720 (h->startup_timeout));
721 return sizeof (struct InitMessage) + h->hcnt * sizeof (uint16_t);
722} 1101}
723 1102
724 1103
1104
725/** 1105/**
726 * Connect to the core service. Note that the connection may 1106 * Connect to the core service. Note that the connection may
727 * complete (or fail) asynchronously. 1107 * complete (or fail) asynchronously.
728 * 1108 *
729 * @param cfg configuration to use 1109 * @param cfg configuration to use
730 * @param queue_size size of the per-peer message queue 1110 * @param queue_size size of the per-peer message queue
731 * @param timeout after how long should we give up trying to connect to the core service?
732 * @param cls closure for the various callbacks that follow (including handlers in the handlers array) 1111 * @param cls closure for the various callbacks that follow (including handlers in the handlers array)
733 * @param init callback to call on timeout or once we have successfully 1112 * @param init callback to call on timeout or once we have successfully
734 * connected to the core service; note that timeout is only meaningful if init is not NULL 1113 * connected to the core service; note that timeout is only meaningful if init is not NULL
@@ -750,7 +1129,6 @@ transmit_start (void *cls, size_t size, void *buf)
750struct GNUNET_CORE_Handle * 1129struct GNUNET_CORE_Handle *
751GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 1130GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
752 unsigned int queue_size, 1131 unsigned int queue_size,
753 struct GNUNET_TIME_Relative timeout,
754 void *cls, 1132 void *cls,
755 GNUNET_CORE_StartupCallback init, 1133 GNUNET_CORE_StartupCallback init,
756 GNUNET_CORE_ConnectEventHandler connects, 1134 GNUNET_CORE_ConnectEventHandler connects,
@@ -766,6 +1144,7 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
766 1144
767 h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle)); 1145 h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle));
768 h->cfg = cfg; 1146 h->cfg = cfg;
1147 h->queue_size = queue_size;
769 h->cls = cls; 1148 h->cls = cls;
770 h->init = init; 1149 h->init = init;
771 h->connects = connects; 1150 h->connects = connects;
@@ -776,133 +1155,57 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
776 h->inbound_hdr_only = inbound_hdr_only; 1155 h->inbound_hdr_only = inbound_hdr_only;
777 h->outbound_hdr_only = outbound_hdr_only; 1156 h->outbound_hdr_only = outbound_hdr_only;
778 h->handlers = handlers; 1157 h->handlers = handlers;
779 h->queue_size = queue_size;
780 h->client_notifications = GNUNET_CLIENT_connect ("core", cfg);
781 if (h->client_notifications == NULL)
782 {
783 GNUNET_free (h);
784 return NULL;
785 }
786 h->startup_timeout = GNUNET_TIME_relative_to_absolute (timeout);
787 h->hcnt = 0; 1158 h->hcnt = 0;
788 while (handlers[h->hcnt].callback != NULL) 1159 while (handlers[h->hcnt].callback != NULL)
789 h->hcnt++; 1160 h->hcnt++;
790 GNUNET_assert (h->hcnt < 1161 GNUNET_assert (h->hcnt <
791 (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1162 (GNUNET_SERVER_MAX_MESSAGE_SIZE -
792 sizeof (struct InitMessage)) / sizeof (uint16_t)); 1163 sizeof (struct InitMessage)) / sizeof (uint16_t));
793#if DEBUG_CORE 1164 reconnect (h);
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795 "Trying to connect to core service in next %llu ms.\n",
796 timeout.rel_value);
797#endif
798 h->cth =
799 GNUNET_CLIENT_notify_transmit_ready (h->client_notifications,
800 sizeof (struct InitMessage) +
801 sizeof (uint16_t) * h->hcnt, timeout,
802 GNUNET_YES,
803 &transmit_start, h);
804 return h; 1165 return h;
805} 1166}
806 1167
807 1168
808/** 1169/**
809 * Disconnect from the core service. 1170 * Disconnect from the core service. This function can only
1171 * be called *after* all pending 'GNUNET_CORE_notify_transmit_ready'
1172 * requests have been explicitly cancelled.
810 * 1173 *
811 * @param handle connection to core to disconnect 1174 * @param handle connection to core to disconnect
812 */ 1175 */
813void 1176void
814GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) 1177GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
815{ 1178{
816 if (handle->cth != NULL) 1179 struct ControlMessage *cm;
817 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth); 1180
818 if (handle->solicit_transmit_req != NULL)
819 GNUNET_CORE_notify_transmit_ready_cancel (handle->solicit_transmit_req);
820 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 1181 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
821 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
822 if (handle->client_notifications != NULL)
823 GNUNET_CLIENT_disconnect (handle->client_notifications, GNUNET_NO);
824 GNUNET_break (handle->pending_head == NULL);
825 GNUNET_free_non_null (handle->solicit_buffer);
826 GNUNET_free (handle);
827}
828
829
830/**
831 * Build the message requesting data transmission.
832 */
833static size_t
834produce_send (void *cls, size_t size, void *buf)
835{
836 struct GNUNET_CORE_TransmitHandle *th = cls;
837 struct GNUNET_CORE_Handle *h;
838 struct SendMessage *sm;
839 size_t dt;
840 GNUNET_CONNECTION_TransmitReadyNotify notify;
841 void *notify_cls;
842
843 h = th->ch;
844 if (buf == NULL)
845 { 1182 {
846 /* timeout or error */ 1183 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
847#if DEBUG_CORE 1184 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
849 "P2P transmission request for `%4s' timed out.\n",
850 GNUNET_i2s(&th->peer));
851#endif
852 GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
853 GNUNET_CORE_notify_transmit_ready_cancel (th);
854 if ((h->pending_head == th) && (h->cth != NULL)) /* Request hasn't been canceled yet! */
855 {
856 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
857 h->cth = NULL;
858 trigger_next_request (h);
859 }
860 /* Otherwise this request timed out, but another is actually queued for sending, so don't try to send another! */
861 return 0;
862 } 1185 }
863 sm = (struct SendMessage *) buf; 1186 if (handle->cth != NULL)
864 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
865 sm->priority = htonl (th->priority);
866 sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
867 sm->peer = th->peer;
868 notify = th->notify;
869 notify_cls = th->notify_cls;
870 GNUNET_CORE_notify_transmit_ready_cancel (th);
871 trigger_next_request (h);
872 size = GNUNET_MIN (size,
873 GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE);
874 GNUNET_assert (size >= sizeof (struct SendMessage));
875 dt = notify (notify_cls, size - sizeof (struct SendMessage), &sm[1]);
876 if (0 == dt)
877 { 1187 {
878#if DEBUG_CORE 1188 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
879 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1189 handle->cth = NULL;
880 "Size of clients message to peer %s is 0!\n",
881 GNUNET_i2s(&sm->peer));
882#endif
883 /* client decided to send nothing! */
884 return 0;
885 } 1190 }
886#if DEBUG_CORE 1191 if (handle->client != NULL)
887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
888 "Produced SEND message to core with %u bytes payload\n",
889 dt);
890#endif
891 GNUNET_assert (dt >= sizeof (struct GNUNET_MessageHeader));
892 if (dt + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
893 { 1192 {
894 GNUNET_break (0); 1193 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
895 return 0; 1194 handle->client = NULL;
896 } 1195 }
897#if DEBUG_CORE 1196 while (NULL != (cm = handle->pending_head))
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1197 {
899 "Preparing for P2P transmission of %u bytes to `%4s'.\n", 1198 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
900 dt, 1199 handle->pending_tail,
901 GNUNET_i2s(&sm->peer)); 1200 cm);
902#endif 1201 GNUNET_free (cm);
903 sm->header.size = htons (dt + sizeof (struct SendMessage)); 1202 }
904 GNUNET_assert (dt + sizeof (struct SendMessage) <= size); 1203 GNUNET_CONTAINER_multihashmap_iterate (handle->peers,
905 return dt + sizeof (struct SendMessage); 1204 &disconnect_and_free_peer_entry,
1205 handle);
1206 GNUNET_CONTAINER_multihashmap_destroy (handle->peers);
1207 GNUNET_break (handle->ready_peer_head == NULL);
1208 GNUNET_free (handle);
906} 1209}
907 1210
908 1211
@@ -926,61 +1229,489 @@ produce_send (void *cls, size_t size, void *buf)
926 */ 1229 */
927struct GNUNET_CORE_TransmitHandle * 1230struct GNUNET_CORE_TransmitHandle *
928GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, 1231GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
929 unsigned int priority, 1232 uint32_t priority,
930 struct GNUNET_TIME_Relative maxdelay, 1233 struct GNUNET_TIME_Relative maxdelay,
931 const struct GNUNET_PeerIdentity *target, 1234 const struct GNUNET_PeerIdentity *target,
932 size_t notify_size, 1235 size_t notify_size,
933 GNUNET_CONNECTION_TransmitReadyNotify notify, 1236 GNUNET_CONNECTION_TransmitReadyNotify notify,
934 void *notify_cls) 1237 void *notify_cls)
935{ 1238{
1239 struct PeerRecord *pr;
936 struct GNUNET_CORE_TransmitHandle *th; 1240 struct GNUNET_CORE_TransmitHandle *th;
1241 struct GNUNET_CORE_TransmitHandle *pos;
1242 struct GNUNET_CORE_TransmitHandle *prev;
1243 struct GNUNET_CORE_TransmitHandle *minp;
937 1244
1245 pr = GNUNET_CONTAINER_multihashmap_get (handle->peers,
1246 &target->hashPubKey);
1247 if (NULL == pr)
1248 {
1249 /* attempt to send to peer that is not connected */
1250 GNUNET_break (0);
1251 return NULL;
1252 }
938 GNUNET_assert (notify_size + sizeof (struct SendMessage) < 1253 GNUNET_assert (notify_size + sizeof (struct SendMessage) <
939 GNUNET_SERVER_MAX_MESSAGE_SIZE); 1254 GNUNET_SERVER_MAX_MESSAGE_SIZE);
940 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle)); 1255 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle));
941 th->ch = handle; 1256 th->peer = pr;
942 GNUNET_CONTAINER_DLL_insert_after (handle->pending_head, 1257 th->get_message = notify;
943 handle->pending_tail, 1258 th->get_message_cls = notify_cls;
944 handle->pending_tail,
945 th);
946 th->get_message = &produce_send;
947 th->get_message_cls = th;
948 th->notify = notify;
949 th->notify_cls = notify_cls;
950 th->peer = *target;
951 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); 1259 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
952 th->timeout_task = GNUNET_SCHEDULER_add_delayed (maxdelay,
953 &timeout_request, th);
954 th->priority = priority; 1260 th->priority = priority;
955 th->msize = sizeof (struct SendMessage) + notify_size; 1261 th->msize = notify_size;
1262 /* bound queue size */
1263 if (pr->queue_size == handle->queue_size)
1264 {
1265 /* find lowest-priority entry */
1266 minp = pr->pending_head;
1267 prev = minp->next;
1268 while (prev != NULL)
1269 {
1270 if (prev->priority < minp->priority)
1271 minp = prev;
1272 prev = prev->next;
1273 }
1274 if (minp == NULL)
1275 {
1276 GNUNET_break (handle->queue_size != 0);
1277 GNUNET_break (pr->queue_size == 0);
1278 return NULL;
1279 }
1280 if (priority <= minp->priority)
1281 return NULL; /* priority too low */
1282 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
1283 pr->pending_tail,
1284 minp);
1285 pr->queue_size--;
1286 GNUNET_assert (0 ==
1287 minp->get_message (minp->get_message_cls,
1288 0, NULL));
1289 GNUNET_free (minp);
1290 }
1291
1292 /* Order entries by deadline, but SKIP 'HEAD' if
1293 we're in the 'ready_peer_*' DLL */
1294 pos = pr->pending_head;
1295 if ( (pr->prev != NULL) ||
1296 (pr->next != NULL) ||
1297 (pr == handle->ready_peer_head) )
1298 {
1299 GNUNET_assert (pos != NULL);
1300 pos = pos->next; /* skip head */
1301 }
1302
1303 /* insertion sort */
1304 prev = pos;
1305 while ( (pos != NULL) &&
1306 (pos->timeout.abs_value < th->timeout.abs_value) )
1307 {
1308 prev = pos;
1309 pos = pos->next;
1310 }
1311 GNUNET_CONTAINER_DLL_insert_after (pr->pending_head,
1312 pr->pending_tail,
1313 prev,
1314 th);
1315 pr->queue_size++;
956 /* was the request queue previously empty? */ 1316 /* was the request queue previously empty? */
957 if ( (handle->pending_head == th) && 1317 if (pr->pending_head == th)
958 (handle->cth == NULL) ) 1318 request_next_transmission (pr);
959 trigger_next_request (handle);
960 return th; 1319 return th;
961} 1320}
962 1321
963 1322
964/** 1323/**
965 * Cancel the specified transmission-ready notification. 1324 * Cancel the specified transmission-ready notification.
966 *s 1325 *
967 * @param th handle that was returned by "notify_transmit_ready". 1326 * @param th handle that was returned by "notify_transmit_ready".
968 */ 1327 */
969void 1328void
970GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle 1329GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
971 *th) 1330 *th)
972{ 1331{
973 struct GNUNET_CORE_Handle *h = th->ch; 1332 struct PeerRecord *pr = th->peer;
1333 struct GNUNET_CORE_Handle *h = pr->ch;
1334 int was_head;
974 1335
975 if (h->submitted == th) 1336 was_head = (pr->pending_head == th);
976 h->submitted = NULL; 1337 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
977 else 1338 pr->pending_tail,
978 GNUNET_CONTAINER_DLL_remove (h->pending_head, 1339 th);
979 h->pending_tail, 1340 if (th->cm != NULL)
980 th); 1341 {
981 if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK) 1342 /* we're currently in the control queue, remove */
982 GNUNET_SCHEDULER_cancel (th->timeout_task); 1343 GNUNET_CONTAINER_DLL_remove (h->pending_head,
1344 h->pending_tail,
1345 th->cm);
1346 GNUNET_free (th->cm);
1347 }
983 GNUNET_free (th); 1348 GNUNET_free (th);
1349 if (was_head)
1350 {
1351 if ( (pr->prev != NULL) ||
1352 (pr->next != NULL) ||
1353 (pr == h->ready_peer_head) )
1354 {
1355 /* the request that was 'approved' by core was
1356 cancelled before it could be transmitted; remove
1357 us from the 'ready' list */
1358 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
1359 h->ready_peer_tail,
1360 pr);
1361 }
1362 request_next_transmission (pr);
1363 }
1364}
1365
1366
1367/* ****************** GNUNET_CORE_peer_request_connect ******************** */
1368
1369/**
1370 * Handle for a request to the core to connect to
1371 * a particular peer. Can be used to cancel the request
1372 * (before the 'cont'inuation is called).
1373 */
1374struct GNUNET_CORE_PeerRequestHandle
1375{
1376
1377 /**
1378 * Link to control message.
1379 */
1380 struct ControlMessage *cm;
1381
1382 /**
1383 * Core handle used.
1384 */
1385 struct GNUNET_CORE_Handle *h;
1386
1387 /**
1388 * Continuation to run when done.
1389 */
1390 GNUNET_SCHEDULER_Task cont;
1391
1392 /**
1393 * Closure for 'cont'.
1394 */
1395 void *cont_cls;
1396
1397};
1398
1399
1400
1401/**
1402 * Continuation called when the control message was transmitted.
1403 * Calls the original continuation and frees the remaining
1404 * resources.
1405 *
1406 * @param cls the 'struct GNUNET_CORE_PeerRequestHandle'
1407 * @param tc scheduler context
1408 */
1409static void
1410peer_request_connect_cont (void *cls,
1411 const struct GNUNET_SCHEDULER_TaskContext *tc)
1412{
1413 struct GNUNET_CORE_PeerRequestHandle *ret = cls;
1414
1415 if (ret->cont != NULL)
1416 ret->cont (ret->cont_cls, tc);
1417 GNUNET_free (ret);
1418}
1419
1420
1421/**
1422 * Request that the core should try to connect to a particular peer.
1423 * Once the request has been transmitted to the core, the continuation
1424 * function will be called. Note that this does NOT mean that a
1425 * connection was successfully established -- it only means that the
1426 * core will now try. Successful establishment of the connection
1427 * will be signalled to the 'connects' callback argument of
1428 * 'GNUNET_CORE_connect' only. If the core service does not respond
1429 * to our connection attempt within the given time frame, 'cont' will
1430 * be called with the TIMEOUT reason code.
1431 *
1432 * @param h core handle
1433 * @param timeout how long to try to talk to core
1434 * @param peer who should we connect to
1435 * @param cont function to call once the request has been completed (or timed out)
1436 * @param cont_cls closure for cont
1437 * @return NULL on error (cont will not be called), otherwise handle for cancellation
1438 */
1439struct GNUNET_CORE_PeerRequestHandle *
1440GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
1441 struct GNUNET_TIME_Relative timeout,
1442 const struct GNUNET_PeerIdentity * peer,
1443 GNUNET_SCHEDULER_Task cont,
1444 void *cont_cls)
1445{
1446 struct GNUNET_CORE_PeerRequestHandle *ret;
1447 struct ControlMessage *cm;
1448 struct ConnectMessage *msg;
1449
1450 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
1451 sizeof (struct ConnectMessage));
1452 msg = (struct ConnectMessage*) &cm[1];
1453 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT);
1454 msg->header.size = htons (sizeof (struct ConnectMessage));
1455 msg->reserved = htonl (0);
1456 msg->timeout = GNUNET_TIME_relative_hton (timeout);
1457 msg->peer = *peer;
1458 GNUNET_CONTAINER_DLL_insert (h->pending_head,
1459 h->pending_tail,
1460 cm);
1461 ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
1462 ret->h = h;
1463 ret->cm = cm;
1464 ret->cont = cont;
1465 ret->cont_cls = cont_cls;
1466 cm->cont = &peer_request_connect_cont;
1467 cm->cont_cls = ret;
1468 if (h->pending_head == cm)
1469 trigger_next_request (h);
1470 return ret;
1471}
1472
1473
1474/**
1475 * Cancel a pending request to connect to a particular peer. Must not
1476 * be called after the 'cont' function was invoked.
1477 *
1478 * @param req request handle that was returned for the original request
1479 */
1480void
1481GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *req)
1482{
1483 struct GNUNET_CORE_Handle *h = req->h;
1484 struct ControlMessage *cm = req->cm;
1485
1486 GNUNET_CONTAINER_DLL_remove (h->pending_head,
1487 h->pending_tail,
1488 cm);
1489 GNUNET_free (cm);
1490 GNUNET_free (req);
1491}
1492
1493
1494/* ****************** GNUNET_CORE_peer_change_preference ******************** */
1495
1496
1497struct GNUNET_CORE_InformationRequestContext
1498{
1499
1500 /**
1501 * Our connection to the service.
1502 */
1503 struct GNUNET_CORE_Handle *h;
1504
1505 /**
1506 * Function to call with the information.
1507 */
1508 GNUNET_CORE_PeerConfigurationInfoCallback info;
1509
1510 /**
1511 * Closure for info.
1512 */
1513 void *info_cls;
1514
1515 /**
1516 * Link to control message, NULL if CM was sent.
1517 */
1518 struct ControlMessage *cm;
1519
1520 /**
1521 * Link to peer record.
1522 */
1523 struct PeerRecord *pr;
1524};
1525
1526
1527/**
1528 * CM was sent, remove link so we don't double-free.
1529 *
1530 * @param cls the 'struct GNUNET_CORE_InformationRequestContext'
1531 * @param tc scheduler context
1532 */
1533static void
1534change_preference_send_continuation (void *cls,
1535 const struct GNUNET_SCHEDULER_TaskContext *tc)
1536{
1537 struct GNUNET_CORE_InformationRequestContext *irc = cls;
1538
1539 irc->cm = NULL;
1540}
1541
1542
1543/**
1544 * Obtain statistics and/or change preferences for the given peer.
1545 *
1546 * @param h core handle
1547 * @param peer identifies the peer
1548 * @param timeout after how long should we give up (and call "info" with NULL
1549 * for "peer" to signal an error)?
1550 * @param bw_out set to the current bandwidth limit (sending) for this peer,
1551 * caller should set "bw_out" to "-1" to avoid changing
1552 * the current value; otherwise "bw_out" will be lowered to
1553 * the specified value; passing a pointer to "0" can be used to force
1554 * us to disconnect from the peer; "bw_out" might not increase
1555 * as specified since the upper bound is generally
1556 * determined by the other peer!
1557 * @param amount reserve N bytes for receiving, negative
1558 * amounts can be used to undo a (recent) reservation;
1559 * @param preference increase incoming traffic share preference by this amount;
1560 * in the absence of "amount" reservations, we use this
1561 * preference value to assign proportional bandwidth shares
1562 * to all connected peers
1563 * @param info function to call with the resulting configuration information
1564 * @param info_cls closure for info
1565 * @return NULL on error
1566 */
1567struct GNUNET_CORE_InformationRequestContext *
1568GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
1569 const struct GNUNET_PeerIdentity *peer,
1570 struct GNUNET_TIME_Relative timeout,
1571 struct GNUNET_BANDWIDTH_Value32NBO bw_out,
1572 int32_t amount,
1573 uint64_t preference,
1574 GNUNET_CORE_PeerConfigurationInfoCallback info,
1575 void *info_cls)
1576{
1577 struct GNUNET_CORE_InformationRequestContext *irc;
1578 struct PeerRecord *pr;
1579 struct RequestInfoMessage *rim;
1580 struct ControlMessage *cm;
1581
1582 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
1583 &peer->hashPubKey);
1584 if (NULL == pr)
1585 {
1586 /* attempt to change preference on peer that is not connected */
1587 GNUNET_break (0);
1588 return NULL;
1589 }
1590 if (pr->pcic != NULL)
1591 {
1592 /* second change before first one is done */
1593 GNUNET_break (0);
1594 return NULL;
1595 }
1596 irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
1597 irc->h = h;
1598 irc->info = info;
1599 irc->info_cls = info_cls;
1600 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
1601 sizeof (struct RequestInfoMessage));
1602 cm->cont = &change_preference_send_continuation;
1603 cm->cont_cls = irc;
1604 irc->cm = cm;
1605 rim = (struct RequestInfoMessage*) &cm[1];
1606 rim->header.size = htons (sizeof (struct RequestInfoMessage));
1607 rim->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
1608 rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++);
1609 rim->limit_outbound = bw_out;
1610 rim->reserve_inbound = htonl (amount);
1611 rim->preference_change = GNUNET_htonll(preference);
1612 rim->peer = *peer;
1613 GNUNET_CONTAINER_DLL_insert (h->pending_head,
1614 h->pending_tail,
1615 cm);
1616 pr->pcic = info;
1617 pr->pcic_cls = info_cls;
1618 return irc;
1619}
1620
1621
1622/**
1623 * Cancel request for getting information about a peer.
1624 * Note that an eventual change in preference, trust or bandwidth
1625 * assignment MAY have already been committed at the time,
1626 * so cancelling a request is NOT sure to undo the original
1627 * request. The original request may or may not still commit.
1628 * The only thing cancellation ensures is that the callback
1629 * from the original request will no longer be called.
1630 *
1631 * @param irc context returned by the original GNUNET_CORE_peer_get_info call
1632 */
1633void
1634GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc)
1635{
1636 struct GNUNET_CORE_Handle *h = irc->h;
1637 struct PeerRecord *pr = irc->pr;
1638
1639 if (irc->cm != NULL)
1640 {
1641 GNUNET_CONTAINER_DLL_remove (h->pending_head,
1642 h->pending_tail,
1643 irc->cm);
1644 GNUNET_free (irc->cm);
1645 }
1646 pr->pcic = NULL;
1647 pr->pcic_cls = NULL;
1648 GNUNET_free (irc);
1649}
1650
1651
1652/* ********************* GNUNET_CORE_iterate_peers *********************** */
1653
1654/**
1655 * Context for 'iterate_peers' helper function.
1656 */
1657struct IterationContext
1658{
1659 /**
1660 * Callback to call.
1661 */
1662 GNUNET_CORE_ConnectEventHandler peer_cb;
1663
1664 /**
1665 * Closure for 'peer_cb'.
1666 */
1667 void *cb_cls;
1668};
1669
1670
1671/**
1672 * Call callback for each peer.
1673 *
1674 * @param cls the 'struct IterationContext'
1675 * @param hc peer identity, not used
1676 * @param value the 'struct PeerRecord'
1677 * @return GNUNET_YES (continue iteration)
1678 */
1679static int
1680iterate_peers (void *cls,
1681 const GNUNET_HashCode *hc,
1682 void *value)
1683{
1684 struct IterationContext *ic = cls;
1685 struct PeerRecord *pr = value;
1686
1687 ic->peer_cb (ic->cb_cls,
1688 &pr->peer,
1689 NULL /* FIXME: pass atsi? */);
1690 return GNUNET_YES;
1691}
1692
1693
1694/**
1695 * Obtain statistics and/or change preferences for the given peer.
1696 *
1697 * @param h handle to core
1698 * @param peer_cb function to call with the peer information
1699 * @param cb_cls closure for peer_cb
1700 * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
1701 */
1702int
1703GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h,
1704 GNUNET_CORE_ConnectEventHandler peer_cb,
1705 void *cb_cls)
1706{
1707 struct IterationContext ic;
1708
1709 ic.peer_cb = peer_cb;
1710 ic.cb_cls = cb_cls;
1711 GNUNET_CONTAINER_multihashmap_iterate (h->peers,
1712 &iterate_peers,
1713 &ic);
1714 return GNUNET_OK;
984} 1715}
985 1716
986 1717
diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c
deleted file mode 100644
index aeef67f88..000000000
--- a/src/core/core_api_iterate_peers.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file core/core_api_iterate_peers.c
23 * @brief implementation of the peer_iterate function
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "platform.h"
28#include "gnunet_core_service.h"
29#include "core.h"
30
31
32struct GNUNET_CORE_RequestContext
33{
34
35 /**
36 * Our connection to the service.
37 */
38 struct GNUNET_CLIENT_Connection *client;
39
40 /**
41 * Handle for transmitting a request.
42 */
43 struct GNUNET_CLIENT_TransmitHandle *th;
44
45 /**
46 * Function called with the peer.
47 */
48 GNUNET_CORE_ConnectEventHandler peer_cb;
49
50 /**
51 * Closure for peer_cb.
52 */
53 void *cb_cls;
54
55};
56
57
58/**
59 * Receive reply from core service with information about a peer.
60 *
61 * @param cls our 'struct GNUNET_CORE_RequestContext *'
62 * @param msg NULL on error or last entry
63 */
64static void
65receive_info (void *cls,
66 const struct GNUNET_MessageHeader *msg)
67{
68 struct GNUNET_CORE_RequestContext *request_context = cls;
69 const struct ConnectNotifyMessage *connect_message;
70
71
72 /* Handle last message or error case, disconnect and clean up */
73 if ( (msg == NULL) ||
74 ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) &&
75 (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))) )
76 {
77 if (request_context->peer_cb != NULL)
78 request_context->peer_cb (request_context->cb_cls,
79 NULL, GNUNET_TIME_relative_get_zero(), 0);
80 GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO);
81 GNUNET_free (request_context);
82 return;
83 }
84
85 /* Handle incorrect message type or size, disconnect and clean up */
86 if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) ||
87 (ntohs (msg->size) != sizeof (struct ConnectNotifyMessage)) )
88 {
89 GNUNET_break (0);
90 if (request_context->peer_cb != NULL)
91 request_context->peer_cb (request_context->cb_cls,
92 NULL, GNUNET_TIME_relative_get_zero(), 0);
93 GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO);
94 GNUNET_free (request_context);
95 return;
96 }
97
98 /* Normal case */
99 connect_message = (const struct ConnectNotifyMessage *) msg;
100 if (request_context->peer_cb != NULL)
101 request_context->peer_cb (request_context->cb_cls,
102 &connect_message->peer,
103 GNUNET_TIME_relative_ntoh(connect_message->latency),
104 ntohl (connect_message->distance));
105
106 GNUNET_CLIENT_receive(request_context->client, &receive_info, request_context, GNUNET_TIME_relative_get_forever());
107}
108
109/**
110 * Function called to notify a client about the socket
111 * begin ready to queue more data. "buf" will be
112 * NULL and "size" zero if the socket was closed for
113 * writing in the meantime.
114 *
115 * @param cls closure
116 * @param size number of bytes available in buf
117 * @param buf where the callee should write the message
118 * @return number of bytes written to buf
119 */
120static size_t
121transmit_request(void *cls,
122 size_t size, void *buf)
123{
124 struct GNUNET_MessageHeader *msg;
125 if ((size < sizeof(struct GNUNET_MessageHeader)) || (buf == NULL))
126 return 0;
127
128 msg = (struct GNUNET_MessageHeader *)buf;
129 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
130 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS);
131 return sizeof(struct GNUNET_MessageHeader);
132}
133
134/**
135 * Obtain statistics and/or change preferences for the given peer.
136 *
137 * @param cfg configuration to use
138 * @param peer_cb function to call with the peer information
139 * @param cb_cls closure for peer_cb
140 * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
141 */
142int
143GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
144 GNUNET_CORE_ConnectEventHandler peer_cb,
145 void *cb_cls)
146{
147 struct GNUNET_CORE_RequestContext *request_context;
148 struct GNUNET_CLIENT_Connection *client;
149
150 client = GNUNET_CLIENT_connect ("core", cfg);
151 if (client == NULL)
152 return GNUNET_SYSERR;
153 request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext));
154 request_context->client = client;
155 request_context->peer_cb = peer_cb;
156 request_context->cb_cls = cb_cls;
157
158 /*GNUNET_assert (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client,
159 &request_message,
160 GNUNET_TIME_relative_get_forever(),
161 GNUNET_YES,
162 &receive_info,
163 request_context));*/
164 request_context->th = GNUNET_CLIENT_notify_transmit_ready(client, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_relative_get_forever(), GNUNET_YES, &transmit_request, NULL);
165 GNUNET_CLIENT_receive(client, &receive_info, request_context, GNUNET_TIME_relative_get_forever());
166 return GNUNET_OK;
167}
168
169/* end of core_api_iterate_peers.c */
diff --git a/src/core/core_api_peer_get_info.c b/src/core/core_api_peer_get_info.c
deleted file mode 100644
index 1ca8d82af..000000000
--- a/src/core/core_api_peer_get_info.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file core/core_api_peer_get_info.c
23 * @brief implementation of the peer_change_preference functions
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_core_service.h"
28#include "core.h"
29
30
31struct GNUNET_CORE_InformationRequestContext
32{
33
34 /**
35 * Our connection to the service.
36 */
37 struct GNUNET_CLIENT_Connection *client;
38
39 /**
40 * Function to call with the information.
41 */
42 GNUNET_CORE_PeerConfigurationInfoCallback info;
43
44 /**
45 * Closure for info.
46 */
47 void *info_cls;
48
49};
50
51
52/**
53 * Receive reply from core service with information about a peer.
54 *
55 * @param cls our 'struct GNUNET_CORE_InformationRequestContext *'
56 * @param msg NULL on error (i.e. timeout)
57 */
58static void
59receive_info (void *cls,
60 const struct GNUNET_MessageHeader *msg)
61{
62 struct GNUNET_CORE_InformationRequestContext *irc = cls;
63 const struct ConfigurationInfoMessage *cim;
64 static struct GNUNET_BANDWIDTH_Value32NBO zbw; /* zero bandwidth */
65
66 if (msg == NULL)
67 {
68 if (irc->info != NULL)
69 irc->info (irc->info_cls,
70 NULL, zbw, zbw, 0, 0);
71 GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
72 GNUNET_free (irc);
73 return;
74 }
75 if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO) ||
76 (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage)) )
77 {
78 GNUNET_break (0);
79 if (irc->info != NULL)
80 irc->info (irc->info_cls,
81 NULL, zbw, zbw, 0, 0);
82 GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
83 GNUNET_free (irc);
84 return;
85 }
86 cim = (const struct ConfigurationInfoMessage*) msg;
87 if (irc->info != NULL)
88 irc->info (irc->info_cls,
89 &cim->peer,
90 cim->bw_in,
91 cim->bw_out,
92 ntohl (cim->reserved_amount),
93 GNUNET_ntohll (cim->preference));
94 GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
95 GNUNET_free (irc);
96}
97
98
99/**
100 * Obtain statistics and/or change preferences for the given peer.
101 *
102 * @param cfg configuration to use
103 * @param peer identifies the peer
104 * @param timeout after how long should we give up (and call "info" with NULL
105 * for "peer" to signal an error)?
106 * @param bw_out set to the current bandwidth limit (sending) for this peer,
107 * caller should set "bw_out" to "-1" to avoid changing
108 * the current value; otherwise "bw_out" will be lowered to
109 * the specified value; passing a pointer to "0" can be used to force
110 * us to disconnect from the peer; "bw_out" might not increase
111 * as specified since the upper bound is generally
112 * determined by the other peer!
113 * @param amount reserve N bytes for receiving, negative
114 * amounts can be used to undo a (recent) reservation;
115 * @param preference increase incoming traffic share preference by this amount;
116 * in the absence of "amount" reservations, we use this
117 * preference value to assign proportional bandwidth shares
118 * to all connected peers
119 * @param info function to call with the resulting configuration information
120 * @param info_cls closure for info
121 * @return NULL on error
122 */
123struct GNUNET_CORE_InformationRequestContext *
124GNUNET_CORE_peer_change_preference (const struct GNUNET_CONFIGURATION_Handle *cfg,
125 const struct GNUNET_PeerIdentity *peer,
126 struct GNUNET_TIME_Relative timeout,
127 struct GNUNET_BANDWIDTH_Value32NBO bw_out,
128 int32_t amount,
129 uint64_t preference,
130 GNUNET_CORE_PeerConfigurationInfoCallback info,
131 void *info_cls)
132{
133 struct GNUNET_CORE_InformationRequestContext *irc;
134 struct RequestInfoMessage rim;
135 struct GNUNET_CLIENT_Connection *client;
136 int retry;
137
138 client = GNUNET_CLIENT_connect ("core", cfg);
139 if (client == NULL)
140 return NULL;
141 irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
142 irc->client = client;
143 irc->info = info;
144 irc->info_cls = info_cls;
145 rim.header.size = htons (sizeof (struct RequestInfoMessage));
146 rim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
147 rim.reserved = htonl (0);
148 rim.limit_outbound = bw_out;
149 rim.reserve_inbound = htonl (amount);
150 rim.preference_change = GNUNET_htonll(preference);
151 rim.peer = *peer;
152 retry = ( (amount == 0) && (preference == 0) ) ? GNUNET_YES : GNUNET_NO;
153 GNUNET_assert (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client,
154 &rim.header,
155 timeout,
156 retry,
157 &receive_info,
158 irc));
159 return irc;
160}
161
162
163/**
164 * Cancel request for getting information about a peer.
165 *
166 * @param irc context returned by the original GNUNET_CORE_peer_get_info call
167 */
168void
169GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc)
170{
171 GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
172 GNUNET_free (irc);
173}
174
175/* end of core_api_peer_get_info.c */
diff --git a/src/core/core_api_peer_request.c b/src/core/core_api_peer_request.c
deleted file mode 100644
index 0f13f15f9..000000000
--- a/src/core/core_api_peer_request.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file core/core_api_peer_request.c
23 * @brief implementation of the peer_request functions
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_core_service.h"
28#include "core.h"
29
30
31/**
32 * Handle for a request to the core to connect to
33 * a particular peer. Can be used to cancel the request
34 * (before the 'cont'inuation is called).
35 */
36struct GNUNET_CORE_PeerRequestHandle
37{
38
39 /**
40 * Our connection to the service.
41 */
42 struct GNUNET_CLIENT_Connection *client;
43
44
45 /**
46 * Function to call once done.
47 */
48 GNUNET_SCHEDULER_Task cont;
49
50 /**
51 * Closure for 'cont'.
52 */
53 void *cont_cls;
54
55 /**
56 * When to time out.
57 */
58 struct GNUNET_TIME_Absolute timeout;
59
60 /**
61 * Identity of the peer to connect to.
62 */
63 struct GNUNET_PeerIdentity peer;
64
65 /**
66 * Message type to use.
67 */
68 uint16_t type;
69};
70
71
72/**
73 * Transmit the request to the core service.
74 *
75 * @param cls our 'struct GNUNET_CORE_PeerRequestHandle'
76 * @param size number of bytes available in buf
77 * @param buf where the callee should write the message
78 * @return number of bytes written to buf
79 */
80static size_t
81send_request (void *cls,
82 size_t size,
83 void *buf)
84{
85 struct GNUNET_CORE_PeerRequestHandle * prh = cls;
86 struct ConnectMessage msg;
87
88 if (buf == NULL)
89 {
90 if (prh->cont != NULL)
91 GNUNET_SCHEDULER_add_continuation (prh->cont,
92 prh->cont_cls,
93 GNUNET_SCHEDULER_REASON_TIMEOUT);
94 GNUNET_CLIENT_disconnect (prh->client, GNUNET_NO);
95 GNUNET_free (prh);
96 return 0;
97 }
98 GNUNET_assert (size >= sizeof (struct ConnectMessage));
99 msg.header.type = htons (prh->type);
100 msg.header.size = htons (sizeof (struct ConnectMessage));
101 msg.reserved = htonl (0);
102 msg.timeout = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (prh->timeout));
103 msg.peer = prh->peer;
104 memcpy (buf, &msg, sizeof (msg));
105 if (prh->cont != NULL)
106 {
107 GNUNET_SCHEDULER_add_continuation (prh->cont,
108 prh->cont_cls,
109 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
110 }
111 GNUNET_CLIENT_disconnect (prh->client, GNUNET_YES);
112 GNUNET_free (prh);
113 return sizeof (msg);
114}
115
116
117/**
118 * Request that the core should try to connect to a particular peer.
119 * Once the request has been transmitted to the core, the continuation
120 * function will be called. Note that this does NOT mean that a
121 * connection was successfully established -- it only means that the
122 * core will now try. Successful establishment of the connection
123 * will be signalled to the 'connects' callback argument of
124 * 'GNUNET_CORE_connect' only. If the core service does not respond
125 * to our connection attempt within the given time frame, 'cont' will
126 * be called with the TIMEOUT reason code.
127 *
128 * @param cfg configuration to use
129 * @param timeout how long to try to talk to core
130 * @param peer who should we connect to
131 * @param cont function to call once the request has been completed (or timed out)
132 * @param cont_cls closure for cont
133 * @return NULL on error (cont will not be called), otherwise handle for cancellation
134 */
135struct GNUNET_CORE_PeerRequestHandle *
136GNUNET_CORE_peer_request_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
137 struct GNUNET_TIME_Relative timeout,
138 const struct GNUNET_PeerIdentity * peer,
139 GNUNET_SCHEDULER_Task cont,
140 void *cont_cls)
141{
142 struct GNUNET_CORE_PeerRequestHandle *ret;
143 struct GNUNET_CLIENT_Connection *client;
144
145 client = GNUNET_CLIENT_connect ("core", cfg);
146 if (client == NULL)
147 return NULL;
148 ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
149 ret->client = client;
150 ret->cont = cont;
151 ret->cont_cls = cont_cls;
152 ret->peer = *peer;
153 ret->type = GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT;
154 ret->timeout = GNUNET_TIME_relative_to_absolute (timeout);
155 GNUNET_CLIENT_notify_transmit_ready (client,
156 sizeof (struct ConnectMessage),
157 timeout,
158 GNUNET_YES,
159 &send_request,
160 ret);
161 return ret;
162}
163
164
165/**
166 * Cancel a pending request to connect to a particular peer. Must not
167 * be called after the 'cont' function was invoked.
168 *
169 * @param req request handle that was returned for the original request
170 */
171void
172GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *req)
173{
174 GNUNET_CLIENT_disconnect (req->client, GNUNET_NO);
175 GNUNET_free (req);
176}
177
178
179/* end of core_api_peer_request.c */
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index c1ebdb9df..034f80060 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -391,6 +391,15 @@ struct MessageEntry
391}; 391};
392 392
393 393
394/**
395 * Record kept for each request for transmission issued by a
396 * client that is still pending.
397 */
398struct ClientActiveRequest;
399
400/**
401 * Data kept per neighbouring peer.
402 */
394struct Neighbour 403struct Neighbour
395{ 404{
396 /** 405 /**
@@ -416,6 +425,18 @@ struct Neighbour
416 struct MessageEntry *encrypted_tail; 425 struct MessageEntry *encrypted_tail;
417 426
418 /** 427 /**
428 * Head of list of requests from clients for transmission to
429 * this peer.
430 */
431 struct ClientActiveRequest *active_client_request_head;
432
433 /**
434 * Tail of list of requests from clients for transmission to
435 * this peer.
436 */
437 struct ClientActiveRequest *active_client_request_tail;
438
439 /**
419 * Handle for pending requests for transmission to this peer 440 * Handle for pending requests for transmission to this peer
420 * with the transport service. NULL if no request is pending. 441 * with the transport service. NULL if no request is pending.
421 */ 442 */
@@ -517,11 +538,6 @@ struct Neighbour
517 struct GNUNET_TIME_Absolute last_activity; 538 struct GNUNET_TIME_Absolute last_activity;
518 539
519 /** 540 /**
520 * Last latency observed from this peer.
521 */
522 struct GNUNET_TIME_Relative last_latency;
523
524 /**
525 * At what frequency are we currently re-trying SET_KEY messages? 541 * At what frequency are we currently re-trying SET_KEY messages?
526 */ 542 */
527 struct GNUNET_TIME_Relative set_key_retry_frequency; 543 struct GNUNET_TIME_Relative set_key_retry_frequency;
@@ -588,11 +604,6 @@ struct Neighbour
588 uint32_t ping_challenge; 604 uint32_t ping_challenge;
589 605
590 /** 606 /**
591 * What was the last distance to this peer as reported by the transports?
592 */
593 uint32_t last_distance;
594
595 /**
596 * What is our connection status? 607 * What is our connection status?
597 */ 608 */
598 enum PeerStateMachine status; 609 enum PeerStateMachine status;
@@ -628,6 +639,12 @@ struct Client
628 const uint16_t *types; 639 const uint16_t *types;
629 640
630 /** 641 /**
642 * Map of peer identities to active transmission requests of this
643 * client to the peer (of type 'struct ClientActiveRequest').
644 */
645 struct GNUNET_CONTAINER_MultiHashMap *requests;
646
647 /**
631 * Options for messages this client cares about, 648 * Options for messages this client cares about,
632 * see GNUNET_CORE_OPTION_ values. 649 * see GNUNET_CORE_OPTION_ values.
633 */ 650 */
@@ -643,6 +660,59 @@ struct Client
643 660
644 661
645/** 662/**
663 * Record kept for each request for transmission issued by a
664 * client that is still pending.
665 */
666struct ClientActiveRequest
667{
668
669 /**
670 * Active requests are kept in a doubly-linked list of
671 * the respective target peer.
672 */
673 struct ClientActiveRequest *next;
674
675 /**
676 * Active requests are kept in a doubly-linked list of
677 * the respective target peer.
678 */
679 struct ClientActiveRequest *prev;
680
681 /**
682 * Handle to the client.
683 */
684 struct Client *client;
685
686 /**
687 * By what time would the client want to see this message out?
688 */
689 struct GNUNET_TIME_Absolute deadline;
690
691 /**
692 * How important is this request.
693 */
694 uint32_t priority;
695
696 /**
697 * How many more requests does this client have?
698 */
699 uint32_t queue_size;
700
701 /**
702 * How many bytes does the client intend to send?
703 */
704 uint16_t msize;
705
706 /**
707 * Unique request ID (in big endian).
708 */
709 uint16_t smr_id;
710
711};
712
713
714
715/**
646 * Our public key. 716 * Our public key.
647 */ 717 */
648static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; 718static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
@@ -917,8 +987,6 @@ handle_peer_status_change (struct Neighbour *n)
917#endif 987#endif
918 psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage)); 988 psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
919 psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE); 989 psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
920 psnm.distance = htonl (n->last_distance);
921 psnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
922 psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity, 990 psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity,
923 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 991 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
924 psnm.bandwidth_in = n->bw_in; 992 psnm.bandwidth_in = n->bw_in;
@@ -933,46 +1001,127 @@ handle_peer_status_change (struct Neighbour *n)
933 GNUNET_NO); 1001 GNUNET_NO);
934} 1002}
935 1003
1004
936/** 1005/**
937 * Handle CORE_ITERATE_PEERS request. 1006 * Go over our message queue and if it is not too long, go
1007 * over the pending requests from clients for this
1008 * neighbour and send some clients a 'READY' notification.
1009 *
1010 * @param n which peer to process
938 */ 1011 */
939static void 1012static void
940handle_client_iterate_peers (void *cls, 1013schedule_peer_messages (struct Neighbour *n)
941 struct GNUNET_SERVER_Client *client,
942 const struct GNUNET_MessageHeader *message)
943{ 1014{
944 struct Neighbour *n; 1015 struct SendMessageReady smr;
945 struct ConnectNotifyMessage cnm; 1016 struct ClientActiveRequest *car;
946 struct GNUNET_MessageHeader done_msg; 1017 struct ClientActiveRequest *pos;
947 struct GNUNET_SERVER_TransmitContext *tc; 1018 struct Client *c;
948 1019 struct MessageEntry *mqe;
949 /* notify new client about existing neighbours */ 1020 unsigned int queue_size;
950 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); 1021
951 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 1022 /* check if neighbour queue is empty enough! */
952 done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); 1023 queue_size = 0;
953 done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 1024 mqe = n->messages;
954 tc = GNUNET_SERVER_transmit_context_create (client); 1025 while (mqe != NULL)
955 n = neighbours;
956 while (n != NULL)
957 { 1026 {
958 if (n->status == PEER_STATE_KEY_CONFIRMED) 1027 queue_size++;
959 { 1028 mqe = mqe->next;
960#if DEBUG_CORE_CLIENT 1029 }
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1030 if (queue_size >= MAX_PEER_QUEUE_SIZE)
962 "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); 1031 return; /* queue still full */
963#endif 1032 /* find highest priority request */
964 cnm.distance = htonl (n->last_distance); 1033 pos = n->active_client_request_head;
965 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency); 1034 car = NULL;
966 cnm.peer = n->peer; 1035 while (pos != NULL)
967 GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); 1036 {
968 /*send_to_client (c, &cnm.header, GNUNET_NO);*/ 1037 if ( (car == NULL) ||
969 } 1038 (pos->priority > car->priority) )
970 n = n->next; 1039 car = pos;
1040 pos = pos->next;
971 } 1041 }
1042 if (car == NULL)
1043 return; /* no pending requests */
1044 c = car->client;
1045 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1046 n->active_client_request_tail,
1047 car);
1048 GNUNET_CONTAINER_multihashmap_remove (c->requests,
1049 &n->peer.hashPubKey,
1050 car);
1051 smr.header.size = htons (sizeof (struct SendMessageReady));
1052 smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
1053 smr.size = htons (car->msize);
1054 smr.smr_id = car->smr_id;
1055 smr.peer = n->peer;
1056 send_to_client (c, &smr.header, GNUNET_NO);
1057 GNUNET_free (car);
1058}
972 1059
973 GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); 1060
974 GNUNET_SERVER_transmit_context_run (tc, 1061/**
975 GNUNET_TIME_UNIT_FOREVER_REL); 1062 * Handle CORE_SEND_REQUEST message.
1063 */
1064static void
1065handle_client_send_request (void *cls,
1066 struct GNUNET_SERVER_Client *client,
1067 const struct GNUNET_MessageHeader *message)
1068{
1069 const struct SendMessageRequest *req;
1070 struct Neighbour *n;
1071 struct Client *c;
1072 struct ClientActiveRequest *car;
1073
1074 req = (const struct SendMessageRequest*) message;
1075 n = find_neighbour (&req->peer);
1076 if ( (n == NULL) ||
1077 (GNUNET_YES != n->is_connected) )
1078 {
1079 /* neighbour must have disconnected since request was issued,
1080 ignore (client will realize it once it processes the
1081 disconnect notification) */
1082 GNUNET_STATISTICS_update (stats,
1083 gettext_noop ("# send requests dropped (disconnected)"),
1084 1,
1085 GNUNET_NO);
1086 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1087 return;
1088 }
1089 c = clients;
1090 while ( (c != NULL) &&
1091 (c->client_handle != client) )
1092 c = c->next;
1093 if (c == NULL)
1094 {
1095 /* client did not send INIT first! */
1096 GNUNET_break (0);
1097 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1098 return;
1099 }
1100 if (c->requests == NULL)
1101 c->requests = GNUNET_CONTAINER_multihashmap_create (16);
1102 car = GNUNET_CONTAINER_multihashmap_get (c->requests,
1103 &req->peer.hashPubKey);
1104 if (car == NULL)
1105 {
1106 /* create new entry */
1107 car = GNUNET_malloc (sizeof (struct ClientActiveRequest));
1108 GNUNET_assert (GNUNET_OK ==
1109 GNUNET_CONTAINER_multihashmap_put (c->requests,
1110 &req->peer.hashPubKey,
1111 car,
1112 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1113 GNUNET_CONTAINER_DLL_insert (n->active_client_request_head,
1114 n->active_client_request_tail,
1115 car);
1116 car->client = c;
1117 }
1118 car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
1119 car->priority = ntohl (req->priority);
1120 car->queue_size = ntohl (req->queue_size);
1121 car->msize = ntohs (req->size);
1122 car->smr_id = req->smr_id;
1123 schedule_peer_messages (n);
1124 GNUNET_SERVER_receive_done (client, GNUNET_OK);
976} 1125}
977 1126
978 1127
@@ -1064,8 +1213,6 @@ handle_client_init (void *cls,
1064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1065 "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); 1214 "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
1066#endif 1215#endif
1067 cnm.distance = htonl (n->last_distance);
1068 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
1069 cnm.peer = n->peer; 1216 cnm.peer = n->peer;
1070 send_to_client (c, &cnm.header, GNUNET_NO); 1217 send_to_client (c, &cnm.header, GNUNET_NO);
1071 } 1218 }
@@ -1077,6 +1224,33 @@ handle_client_init (void *cls,
1077 1224
1078 1225
1079/** 1226/**
1227 * Free client request records.
1228 *
1229 * @param cls NULL
1230 * @param key identity of peer for which this is an active request
1231 * @param value the 'struct ClientActiveRequest' to free
1232 * @return GNUNET_YES (continue iteration)
1233 */
1234static int
1235destroy_active_client_request (void *cls,
1236 const GNUNET_HashCode *key,
1237 void *value)
1238{
1239 struct ClientActiveRequest *car = cls;
1240 struct Neighbour *n;
1241 struct GNUNET_PeerIdentity peer;
1242
1243 peer.hashPubKey = *key;
1244 n = find_neighbour (&peer);
1245 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1246 n->active_client_request_tail,
1247 car);
1248 GNUNET_free (car);
1249 return GNUNET_YES;
1250}
1251
1252
1253/**
1080 * A client disconnected, clean up. 1254 * A client disconnected, clean up.
1081 * 1255 *
1082 * @param cls closure 1256 * @param cls closure
@@ -1100,18 +1274,27 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1100 while (pos != NULL) 1274 while (pos != NULL)
1101 { 1275 {
1102 if (client == pos->client_handle) 1276 if (client == pos->client_handle)
1103 { 1277 break;
1104 if (prev == NULL)
1105 clients = pos->next;
1106 else
1107 prev->next = pos->next;
1108 GNUNET_free (pos);
1109 return;
1110 }
1111 prev = pos; 1278 prev = pos;
1112 pos = pos->next; 1279 pos = pos->next;
1113 } 1280 }
1114 /* client never sent INIT */ 1281 if (pos == NULL)
1282 {
1283 /* client never sent INIT */
1284 return;
1285 }
1286 if (prev == NULL)
1287 clients = pos->next;
1288 else
1289 prev->next = pos->next;
1290 if (pos->requests != NULL)
1291 {
1292 GNUNET_CONTAINER_multihashmap_iterate (pos->requests,
1293 &destroy_active_client_request,
1294 NULL);
1295 GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
1296 }
1297 GNUNET_free (pos);
1115} 1298}
1116 1299
1117 1300
@@ -1192,7 +1375,7 @@ handle_client_request_info (void *cls,
1192 (int) got_reserv); 1375 (int) got_reserv);
1193#endif 1376#endif
1194 cim.reserved_amount = htonl (got_reserv); 1377 cim.reserved_amount = htonl (got_reserv);
1195 cim.bw_in = n->bw_in; 1378 cim.rim_id = rcm->rim_id;
1196 cim.bw_out = n->bw_out; 1379 cim.bw_out = n->bw_out;
1197 cim.preference = n->current_preference; 1380 cim.preference = n->current_preference;
1198 } 1381 }
@@ -1221,6 +1404,7 @@ static void
1221free_neighbour (struct Neighbour *n) 1404free_neighbour (struct Neighbour *n)
1222{ 1405{
1223 struct MessageEntry *m; 1406 struct MessageEntry *m;
1407 struct ClientActiveRequest *car;
1224 1408
1225#if DEBUG_CORE 1409#if DEBUG_CORE
1226 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1249,6 +1433,16 @@ free_neighbour (struct Neighbour *n)
1249 m); 1433 m);
1250 GNUNET_free (m); 1434 GNUNET_free (m);
1251 } 1435 }
1436 while (NULL != (car = n->active_client_request_head))
1437 {
1438 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1439 n->active_client_request_tail,
1440 car);
1441 GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
1442 &n->peer.hashPubKey,
1443 car);
1444 GNUNET_free (car);
1445 }
1252 if (NULL != n->th) 1446 if (NULL != n->th)
1253 { 1447 {
1254 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); 1448 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
@@ -1894,8 +2088,6 @@ batch_message (struct Neighbour *n,
1894 return 0; 2088 return 0;
1895 } 2089 }
1896 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND); 2090 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
1897 ntm->distance = htonl (n->last_distance);
1898 ntm->latency = GNUNET_TIME_relative_hton (n->last_latency);
1899 ntm->peer = n->peer; 2091 ntm->peer = n->peer;
1900 pos = n->messages; 2092 pos = n->messages;
1901 prev = NULL; 2093 prev = NULL;
@@ -1985,7 +2177,9 @@ discard_expired_messages (struct Neighbour *n)
1985 struct MessageEntry *pos; 2177 struct MessageEntry *pos;
1986 struct GNUNET_TIME_Absolute now; 2178 struct GNUNET_TIME_Absolute now;
1987 struct GNUNET_TIME_Relative delta; 2179 struct GNUNET_TIME_Relative delta;
2180 int disc;
1988 2181
2182 disc = GNUNET_NO;
1989 now = GNUNET_TIME_absolute_get (); 2183 now = GNUNET_TIME_absolute_get ();
1990 prev = NULL; 2184 prev = NULL;
1991 pos = n->messages; 2185 pos = n->messages;
@@ -2004,12 +2198,19 @@ discard_expired_messages (struct Neighbour *n)
2004 n->messages = next; 2198 n->messages = next;
2005 else 2199 else
2006 prev->next = next; 2200 prev->next = next;
2201 GNUNET_STATISTICS_update (stats,
2202 gettext_noop ("# messages discarded (expired prior to transmission)"),
2203 1,
2204 GNUNET_NO);
2205 disc = GNUNET_YES;
2007 GNUNET_free (pos); 2206 GNUNET_free (pos);
2008 } 2207 }
2009 else 2208 else
2010 prev = pos; 2209 prev = pos;
2011 pos = next; 2210 pos = next;
2012 } 2211 }
2212 if (GNUNET_YES == disc)
2213 schedule_peer_messages (n);
2013} 2214}
2014 2215
2015 2216
@@ -2217,6 +2418,7 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
2217 n->encrypted_tail, 2418 n->encrypted_tail,
2218 me); 2419 me);
2219 process_encrypted_neighbour_queue (n); 2420 process_encrypted_neighbour_queue (n);
2421 schedule_peer_messages (n);
2220} 2422}
2221 2423
2222 2424
@@ -2342,8 +2544,15 @@ handle_client_send (void *cls,
2342 (unsigned int) msize, 2544 (unsigned int) msize,
2343 GNUNET_i2s (&sm->peer)); 2545 GNUNET_i2s (&sm->peer));
2344#endif 2546#endif
2345 /* bound queue size */
2346 discard_expired_messages (n); 2547 discard_expired_messages (n);
2548 /* bound queue size */
2549 /* NOTE: this entire block to bound the queue size should be
2550 obsolete with the new client-request code and the
2551 'schedule_peer_messages' mechanism; we still have this code in
2552 here for now as a sanity check for the new mechanmism;
2553 ultimately, we should probably simply reject SEND messages that
2554 are not 'approved' (or provide a new core API for very unreliable
2555 delivery that always sends with priority 0). Food for thought. */
2347 min_prio = UINT32_MAX; 2556 min_prio = UINT32_MAX;
2348 min_prio_entry = NULL; 2557 min_prio_entry = NULL;
2349 min_prio_prev = NULL; 2558 min_prio_prev = NULL;
@@ -2367,7 +2576,8 @@ handle_client_send (void *cls,
2367 /* queue full */ 2576 /* queue full */
2368 if (ntohl(sm->priority) <= min_prio) 2577 if (ntohl(sm->priority) <= min_prio)
2369 { 2578 {
2370 /* discard new entry */ 2579 /* discard new entry; this should no longer happen! */
2580 GNUNET_break (0);
2371#if DEBUG_CORE 2581#if DEBUG_CORE
2372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2373 "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n", 2583 "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
@@ -2376,7 +2586,9 @@ handle_client_send (void *cls,
2376 (unsigned int) msize, 2586 (unsigned int) msize,
2377 (unsigned int) ntohs (message->type)); 2587 (unsigned int) ntohs (message->type));
2378#endif 2588#endif
2379 GNUNET_STATISTICS_update (stats, gettext_noop ("# discarded CORE_SEND requests"), 1, GNUNET_NO); 2589 GNUNET_STATISTICS_update (stats,
2590 gettext_noop ("# discarded CORE_SEND requests"),
2591 1, GNUNET_NO);
2380 2592
2381 if (client != NULL) 2593 if (client != NULL)
2382 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2594 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -3087,8 +3299,6 @@ handle_pong (struct Neighbour *n,
3087 } 3299 }
3088 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); 3300 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
3089 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 3301 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
3090 cnm.distance = htonl (n->last_distance);
3091 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
3092 cnm.peer = n->peer; 3302 cnm.peer = n->peer;
3093 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT); 3303 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT);
3094 process_encrypted_neighbour_queue (n); 3304 process_encrypted_neighbour_queue (n);
@@ -3308,8 +3518,6 @@ send_p2p_message_to_client (struct Neighbour *sender,
3308 ntm = (struct NotifyTrafficMessage *) buf; 3518 ntm = (struct NotifyTrafficMessage *) buf;
3309 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage)); 3519 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
3310 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND); 3520 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
3311 ntm->distance = htonl (sender->last_distance);
3312 ntm->latency = GNUNET_TIME_relative_hton (sender->last_latency);
3313 ntm->peer = sender->peer; 3521 ntm->peer = sender->peer;
3314 memcpy (&ntm[1], m, msize); 3522 memcpy (&ntm[1], m, msize);
3315 send_to_client (client, &ntm->header, GNUNET_YES); 3523 send_to_client (client, &ntm->header, GNUNET_YES);
@@ -3602,9 +3810,7 @@ handle_transport_receive (void *cls,
3602 n = find_neighbour (peer); 3810 n = find_neighbour (peer);
3603 if (n == NULL) 3811 if (n == NULL)
3604 n = create_neighbour (peer); 3812 n = create_neighbour (peer);
3605 changed = (latency.rel_value != n->last_latency.rel_value) || (distance != n->last_distance); 3813 changed = GNUNET_YES; /* FIXME... */
3606 n->last_latency = latency;
3607 n->last_distance = distance;
3608 up = (n->status == PEER_STATE_KEY_CONFIRMED); 3814 up = (n->status == PEER_STATE_KEY_CONFIRMED);
3609 type = ntohs (message->type); 3815 type = ntohs (message->type);
3610 size = ntohs (message->size); 3816 size = ntohs (message->size);
@@ -3832,8 +4038,6 @@ handle_transport_notify_connect (void *cls,
3832 1, 4038 1,
3833 GNUNET_NO); 4039 GNUNET_NO);
3834 n->is_connected = GNUNET_YES; 4040 n->is_connected = GNUNET_YES;
3835 n->last_latency = latency;
3836 n->last_distance = distance;
3837 GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, 4041 GNUNET_BANDWIDTH_tracker_init (&n->available_send_window,
3838 n->bw_out, 4042 n->bw_out,
3839 MAX_WINDOW_TIME_S); 4043 MAX_WINDOW_TIME_S);
@@ -3868,6 +4072,7 @@ handle_transport_notify_disconnect (void *cls,
3868{ 4072{
3869 struct DisconnectNotifyMessage cnm; 4073 struct DisconnectNotifyMessage cnm;
3870 struct Neighbour *n; 4074 struct Neighbour *n;
4075 struct ClientActiveRequest *car;
3871 struct GNUNET_TIME_Relative left; 4076 struct GNUNET_TIME_Relative left;
3872 4077
3873#if DEBUG_CORE 4078#if DEBUG_CORE
@@ -3890,6 +4095,17 @@ handle_transport_notify_disconnect (void *cls,
3890 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT); 4095 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
3891 } 4096 }
3892 n->is_connected = GNUNET_NO; 4097 n->is_connected = GNUNET_NO;
4098 while (NULL != (car = n->active_client_request_head))
4099 {
4100 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
4101 n->active_client_request_tail,
4102 car);
4103 GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
4104 &n->peer.hashPubKey,
4105 car);
4106 GNUNET_free (car);
4107 }
4108
3893 GNUNET_STATISTICS_update (stats, 4109 GNUNET_STATISTICS_update (stats,
3894 gettext_noop ("# peers connected (transport)"), 4110 gettext_noop ("# peers connected (transport)"),
3895 -1, 4111 -1,
@@ -3964,9 +4180,9 @@ run (void *cls,
3964 {&handle_client_request_info, NULL, 4180 {&handle_client_request_info, NULL,
3965 GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO, 4181 GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
3966 sizeof (struct RequestInfoMessage)}, 4182 sizeof (struct RequestInfoMessage)},
3967 {&handle_client_iterate_peers, NULL, 4183 {&handle_client_send_request, NULL,
3968 GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS, 4184 GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
3969 sizeof (struct GNUNET_MessageHeader)}, 4185 sizeof (struct SendMessageRequest)},
3970 {&handle_client_send, NULL, 4186 {&handle_client_send, NULL,
3971 GNUNET_MESSAGE_TYPE_CORE_SEND, 0}, 4187 GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
3972 {&handle_client_request_connect, NULL, 4188 {&handle_client_request_connect, NULL,
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c
index 129184587..b41d30450 100644
--- a/src/core/test_core_api.c
+++ b/src/core/test_core_api.c
@@ -38,11 +38,6 @@
38 38
39#define START_ARM GNUNET_YES 39#define START_ARM GNUNET_YES
40 40
41/**
42 * How long until we give up on transmitting the message?
43 */
44#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
45
46#define MTYPE 12345 41#define MTYPE 12345
47 42
48struct PeerContext 43struct PeerContext
@@ -103,8 +98,7 @@ terminate_task_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
103static void 98static void
104connect_notify (void *cls, 99connect_notify (void *cls,
105 const struct GNUNET_PeerIdentity *peer, 100 const struct GNUNET_PeerIdentity *peer,
106 struct GNUNET_TIME_Relative latency, 101 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
107 uint32_t distance)
108{ 102{
109 struct PeerContext *pc = cls; 103 struct PeerContext *pc = cls;
110 GNUNET_assert (pc->connect_status == 0); 104 GNUNET_assert (pc->connect_status == 0);
@@ -130,8 +124,7 @@ static int
130inbound_notify (void *cls, 124inbound_notify (void *cls,
131 const struct GNUNET_PeerIdentity *other, 125 const struct GNUNET_PeerIdentity *other,
132 const struct GNUNET_MessageHeader *message, 126 const struct GNUNET_MessageHeader *message,
133 struct GNUNET_TIME_Relative latency, 127 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
134 uint32_t distance)
135{ 128{
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
137 "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other)); 130 "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other));
@@ -143,8 +136,7 @@ static int
143outbound_notify (void *cls, 136outbound_notify (void *cls,
144 const struct GNUNET_PeerIdentity *other, 137 const struct GNUNET_PeerIdentity *other,
145 const struct GNUNET_MessageHeader *message, 138 const struct GNUNET_MessageHeader *message,
146 struct GNUNET_TIME_Relative latency, 139 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
147 uint32_t distance)
148{ 140{
149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 141 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
150 "Core notifies about outbound data for `%4s'.\n", 142 "Core notifies about outbound data for `%4s'.\n",
@@ -160,8 +152,7 @@ static int
160process_mtype (void *cls, 152process_mtype (void *cls,
161 const struct GNUNET_PeerIdentity *peer, 153 const struct GNUNET_PeerIdentity *peer,
162 const struct GNUNET_MessageHeader *message, 154 const struct GNUNET_MessageHeader *message,
163 struct GNUNET_TIME_Relative latency, 155 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
164 uint32_t distance)
165{ 156{
166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
167 "Receiving message from `%4s'.\n", GNUNET_i2s (peer)); 158 "Receiving message from `%4s'.\n", GNUNET_i2s (peer));
@@ -220,7 +211,6 @@ init_notify (void *cls,
220 OKPP; 211 OKPP;
221 /* connect p2 */ 212 /* connect p2 */
222 GNUNET_CORE_connect (p2.cfg, 1, 213 GNUNET_CORE_connect (p2.cfg, 1,
223 TIMEOUT,
224 &p2, 214 &p2,
225 &init_notify, 215 &init_notify,
226 &connect_notify, 216 &connect_notify,
@@ -311,7 +301,6 @@ run (void *cls,
311 setup_peer (&p1, "test_core_api_peer1.conf"); 301 setup_peer (&p1, "test_core_api_peer1.conf");
312 setup_peer (&p2, "test_core_api_peer2.conf"); 302 setup_peer (&p2, "test_core_api_peer2.conf");
313 GNUNET_CORE_connect (p1.cfg, 1, 303 GNUNET_CORE_connect (p1.cfg, 1,
314 TIMEOUT,
315 &p1, 304 &p1,
316 &init_notify, 305 &init_notify,
317 &connect_notify, 306 &connect_notify,
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c
index f22a9022e..14b69b80e 100644
--- a/src/core/test_core_api_reliability.c
+++ b/src/core/test_core_api_reliability.c
@@ -148,8 +148,7 @@ terminate_task_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
148static void 148static void
149connect_notify (void *cls, 149connect_notify (void *cls,
150 const struct GNUNET_PeerIdentity *peer, 150 const struct GNUNET_PeerIdentity *peer,
151 struct GNUNET_TIME_Relative latency, 151 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
152 uint32_t distance)
153{ 152{
154 struct PeerContext *pc = cls; 153 struct PeerContext *pc = cls;
155 GNUNET_assert (pc->connect_status == 0); 154 GNUNET_assert (pc->connect_status == 0);
@@ -175,8 +174,7 @@ static int
175inbound_notify (void *cls, 174inbound_notify (void *cls,
176 const struct GNUNET_PeerIdentity *other, 175 const struct GNUNET_PeerIdentity *other,
177 const struct GNUNET_MessageHeader *message, 176 const struct GNUNET_MessageHeader *message,
178 struct GNUNET_TIME_Relative latency, 177 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
179 uint32_t distance)
180{ 178{
181#if VERBOSE 179#if VERBOSE
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -190,8 +188,7 @@ static int
190outbound_notify (void *cls, 188outbound_notify (void *cls,
191 const struct GNUNET_PeerIdentity *other, 189 const struct GNUNET_PeerIdentity *other,
192 const struct GNUNET_MessageHeader *message, 190 const struct GNUNET_MessageHeader *message,
193 struct GNUNET_TIME_Relative latency, 191 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
194 uint32_t distance)
195{ 192{
196#if VERBOSE 193#if VERBOSE
197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -215,8 +212,7 @@ static int
215process_mtype (void *cls, 212process_mtype (void *cls,
216 const struct GNUNET_PeerIdentity *peer, 213 const struct GNUNET_PeerIdentity *peer,
217 const struct GNUNET_MessageHeader *message, 214 const struct GNUNET_MessageHeader *message,
218 struct GNUNET_TIME_Relative latency, 215 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
219 uint32_t distance)
220{ 216{
221 static int n; 217 static int n;
222 unsigned int s; 218 unsigned int s;
@@ -366,7 +362,6 @@ init_notify (void *cls,
366 OKPP; 362 OKPP;
367 /* connect p2 */ 363 /* connect p2 */
368 GNUNET_CORE_connect (p2.cfg, 1, 364 GNUNET_CORE_connect (p2.cfg, 1,
369 TIMEOUT,
370 &p2, 365 &p2,
371 &init_notify, 366 &init_notify,
372 &connect_notify, 367 &connect_notify,
@@ -456,7 +451,6 @@ run (void *cls,
456 setup_peer (&p1, "test_core_api_peer1.conf"); 451 setup_peer (&p1, "test_core_api_peer1.conf");
457 setup_peer (&p2, "test_core_api_peer2.conf"); 452 setup_peer (&p2, "test_core_api_peer2.conf");
458 GNUNET_CORE_connect (p1.cfg, 1, 453 GNUNET_CORE_connect (p1.cfg, 1,
459 TIMEOUT,
460 &p1, 454 &p1,
461 &init_notify, 455 &init_notify,
462 &connect_notify, 456 &connect_notify,
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c
index e39179196..6c042a2b2 100644
--- a/src/core/test_core_api_start_only.c
+++ b/src/core/test_core_api_start_only.c
@@ -35,12 +35,6 @@
35 35
36#define START_ARM GNUNET_YES 36#define START_ARM GNUNET_YES
37 37
38
39/**
40 * How long until we give up on transmitting the message?
41 */
42#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
43
44#define MTYPE 12345 38#define MTYPE 12345
45 39
46struct PeerContext 40struct PeerContext
@@ -71,8 +65,7 @@ static int ok;
71static void 65static void
72connect_notify (void *cls, 66connect_notify (void *cls,
73 const struct GNUNET_PeerIdentity *peer, 67 const struct GNUNET_PeerIdentity *peer,
74 struct GNUNET_TIME_Relative latency, 68 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
75 uint32_t distance)
76{ 69{
77} 70}
78 71
@@ -88,8 +81,7 @@ static int
88inbound_notify (void *cls, 81inbound_notify (void *cls,
89 const struct GNUNET_PeerIdentity *other, 82 const struct GNUNET_PeerIdentity *other,
90 const struct GNUNET_MessageHeader *message, 83 const struct GNUNET_MessageHeader *message,
91 struct GNUNET_TIME_Relative latency, 84 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
92 uint32_t distance)
93{ 85{
94 return GNUNET_OK; 86 return GNUNET_OK;
95} 87}
@@ -99,8 +91,7 @@ static int
99outbound_notify (void *cls, 91outbound_notify (void *cls,
100 const struct GNUNET_PeerIdentity *other, 92 const struct GNUNET_PeerIdentity *other,
101 const struct GNUNET_MessageHeader *message, 93 const struct GNUNET_MessageHeader *message,
102 struct GNUNET_TIME_Relative latency, 94 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
103 uint32_t distance)
104{ 95{
105 return GNUNET_OK; 96 return GNUNET_OK;
106} 97}
@@ -126,7 +117,6 @@ init_notify (void *cls,
126 { 117 {
127 /* connect p2 */ 118 /* connect p2 */
128 GNUNET_CORE_connect (p2.cfg, 1, 119 GNUNET_CORE_connect (p2.cfg, 1,
129 TIMEOUT,
130 &p2, 120 &p2,
131 &init_notify, 121 &init_notify,
132 &connect_notify, 122 &connect_notify,
@@ -173,7 +163,6 @@ run (void *cls,
173 setup_peer (&p1, "test_core_api_peer1.conf"); 163 setup_peer (&p1, "test_core_api_peer1.conf");
174 setup_peer (&p2, "test_core_api_peer2.conf"); 164 setup_peer (&p2, "test_core_api_peer2.conf");
175 GNUNET_CORE_connect (p1.cfg, 1, 165 GNUNET_CORE_connect (p1.cfg, 1,
176 TIMEOUT,
177 &p1, 166 &p1,
178 &init_notify, 167 &init_notify,
179 &connect_notify, 168 &connect_notify,
diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c
index 5a3e3dc14..9d231c4e0 100644
--- a/src/core/test_core_quota_compliance.c
+++ b/src/core/test_core_quota_compliance.c
@@ -191,8 +191,7 @@ static int
191inbound_notify (void *cls, 191inbound_notify (void *cls,
192 const struct GNUNET_PeerIdentity *other, 192 const struct GNUNET_PeerIdentity *other,
193 const struct GNUNET_MessageHeader *message, 193 const struct GNUNET_MessageHeader *message,
194 struct GNUNET_TIME_Relative latency, 194 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
195 uint32_t distance)
196{ 195{
197 total_bytes_recv += ntohs (message->size); 196 total_bytes_recv += ntohs (message->size);
198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -207,8 +206,7 @@ static int
207outbound_notify (void *cls, 206outbound_notify (void *cls,
208 const struct GNUNET_PeerIdentity *other, 207 const struct GNUNET_PeerIdentity *other,
209 const struct GNUNET_MessageHeader *message, 208 const struct GNUNET_MessageHeader *message,
210 struct GNUNET_TIME_Relative latency, 209 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
211 uint32_t distance)
212{ 210{
213#if DEBUG_CONNECTIONS 211#if DEBUG_CONNECTIONS
214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -238,38 +236,37 @@ static void
238measurement_end (void *cls, 236measurement_end (void *cls,
239 const struct GNUNET_SCHEDULER_TaskContext *tc) 237 const struct GNUNET_SCHEDULER_TaskContext *tc)
240{ 238{
241 struct GNUNET_TIME_Relative duration; 239 struct GNUNET_TIME_Relative duration;
242 240
243 measure_task = GNUNET_SCHEDULER_NO_TASK; 241 measure_task = GNUNET_SCHEDULER_NO_TASK;
244 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 242 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
245 return; 243 return;
246 244
247 if (err_task != GNUNET_SCHEDULER_NO_TASK) 245 if (err_task != GNUNET_SCHEDULER_NO_TASK)
248 GNUNET_SCHEDULER_cancel (err_task); 246 GNUNET_SCHEDULER_cancel (err_task);
249 if (send_task != GNUNET_SCHEDULER_NO_TASK) 247 if (send_task != GNUNET_SCHEDULER_NO_TASK)
250 GNUNET_SCHEDULER_cancel (send_task); 248 GNUNET_SCHEDULER_cancel (send_task);
251 249
252 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1); 250 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
253 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2); 251 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
254 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1); 252 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
255 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2); 253 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
256 254
257 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1); 255 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
258 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2); 256 GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
259 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1); 257 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
260 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2); 258 GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
261 measurement_running = GNUNET_NO; 259 measurement_running = GNUNET_NO;
262 duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get()); 260 duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
263 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 261 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
264 "\nQuota compliance: \n"\ 262 "\nQuota compliance: \n" \
265 "Receive rate: %10llu kB/s\n" 263 "Receive rate: %10llu kB/s\n"
266 "Send rate : %10llu kB/s\n"\ 264 "Send rate : %10llu kB/s\n" \
267 "Quota : %10llu kB/s\n", 265 "Quota : %10llu kB/s\n",
268 (total_bytes_recv/(duration.rel_value / 1000)/1024), 266 (total_bytes_recv/(duration.rel_value / 1000)/1024),
269 (total_bytes_sent/(duration.rel_value / 1000)/1024),current_quota_p1_in/1024); 267 (total_bytes_sent/(duration.rel_value / 1000)/1024),
270 268 current_quota_p1_in/1024);
271 269 GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
272 GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
273} 270}
274 271
275static size_t 272static size_t
@@ -279,17 +276,19 @@ static void
279send_tsk (void *cls, 276send_tsk (void *cls,
280 const struct GNUNET_SCHEDULER_TaskContext *tc) 277 const struct GNUNET_SCHEDULER_TaskContext *tc)
281{ 278{
282 send_task = GNUNET_SCHEDULER_NO_TASK; 279 send_task = GNUNET_SCHEDULER_NO_TASK;
283 280
284 ch = GNUNET_CORE_notify_transmit_ready (p1.ch, 281 ch = GNUNET_CORE_notify_transmit_ready (p1.ch,
285 0, 282 0,
286 FAST_TIMEOUT, 283 FAST_TIMEOUT,
287 &p2.id, 284 &p2.id,
288 sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE, 285 sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
289 &transmit_ready, &p1); 286 &transmit_ready, &p1);
290} 287}
291 288
292static void measure (unsigned long long quota_p1, unsigned long long quota_p2 ) 289
290static void
291measure (unsigned long long quota_p1, unsigned long long quota_p2)
293{ 292{
294#if VERBOSE 293#if VERBOSE
295 if ((is_asymmetric_send_constant == GNUNET_YES) || (is_asymmetric_recv_constant == GNUNET_YES)) 294 if ((is_asymmetric_send_constant == GNUNET_YES) || (is_asymmetric_recv_constant == GNUNET_YES))
@@ -316,11 +315,11 @@ static void measure (unsigned long long quota_p1, unsigned long long quota_p2 )
316 total_bytes = 0; 315 total_bytes = 0;
317 total_bytes_sent = 0; 316 total_bytes_sent = 0;
318 ch = GNUNET_CORE_notify_transmit_ready (p1.ch, 317 ch = GNUNET_CORE_notify_transmit_ready (p1.ch,
319 0, 318 0,
320 TIMEOUT, 319 TIMEOUT,
321 &p2.id, 320 &p2.id,
322 sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE, 321 sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
323 &transmit_ready, &p1); 322 &transmit_ready, &p1);
324} 323}
325 324
326static int tr_n; 325static int tr_n;
@@ -330,8 +329,7 @@ static int
330process_mtype (void *cls, 329process_mtype (void *cls,
331 const struct GNUNET_PeerIdentity *peer, 330 const struct GNUNET_PeerIdentity *peer,
332 const struct GNUNET_MessageHeader *message, 331 const struct GNUNET_MessageHeader *message,
333 struct GNUNET_TIME_Relative latency, 332 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
334 uint32_t distance)
335{ 333{
336 static int n; 334 static int n;
337 unsigned int s; 335 unsigned int s;
@@ -453,7 +451,6 @@ init_notify (void *cls,
453 OKPP; 451 OKPP;
454 /* connect p2 */ 452 /* connect p2 */
455 GNUNET_CORE_connect (p2.cfg, 1, 453 GNUNET_CORE_connect (p2.cfg, 1,
456 TIMEOUT,
457 &p2, 454 &p2,
458 &init_notify, 455 &init_notify,
459 &connect_notify, 456 &connect_notify,
@@ -534,7 +531,6 @@ run (void *cls,
534 setup_peer (&p1, "test_core_quota_peer1.conf"); 531 setup_peer (&p1, "test_core_quota_peer1.conf");
535 setup_peer (&p2, "test_core_quota_peer2.conf"); 532 setup_peer (&p2, "test_core_quota_peer2.conf");
536 GNUNET_CORE_connect (p1.cfg, 1, 533 GNUNET_CORE_connect (p1.cfg, 1,
537 TIMEOUT,
538 &p1, 534 &p1,
539 &init_notify, 535 &init_notify,
540 &connect_notify, 536 &connect_notify,
@@ -606,7 +602,7 @@ main (int argc, char *argv[])
606{ 602{
607 int ret; 603 int ret;
608 604
609 GNUNET_log_setup ("test-core-api", 605 GNUNET_log_setup ("test-core-quota-compliance",
610#if VERBOSE 606#if VERBOSE
611 "DEBUG", 607 "DEBUG",
612#else 608#else
diff --git a/src/dht/gnunet-dht-driver.c b/src/dht/gnunet-dht-driver.c
index fdd442cdb..8f1081a7a 100644
--- a/src/dht/gnunet-dht-driver.c
+++ b/src/dht/gnunet-dht-driver.c
@@ -854,8 +854,6 @@ static void
854log_topology_cb (void *cls, 854log_topology_cb (void *cls,
855 const struct GNUNET_PeerIdentity *first, 855 const struct GNUNET_PeerIdentity *first,
856 const struct GNUNET_PeerIdentity *second, 856 const struct GNUNET_PeerIdentity *second,
857 struct GNUNET_TIME_Relative latency,
858 uint32_t distance,
859 const char *emsg) 857 const char *emsg)
860{ 858{
861 struct TopologyIteratorContext *topo_ctx = cls; 859 struct TopologyIteratorContext *topo_ctx = cls;
@@ -1286,8 +1284,6 @@ static void
1286count_peers_churn_cb (void *cls, 1284count_peers_churn_cb (void *cls,
1287 const struct GNUNET_PeerIdentity *first, 1285 const struct GNUNET_PeerIdentity *first,
1288 const struct GNUNET_PeerIdentity *second, 1286 const struct GNUNET_PeerIdentity *second,
1289 struct GNUNET_TIME_Relative latency,
1290 uint32_t distance,
1291 const char *emsg) 1287 const char *emsg)
1292{ 1288{
1293 struct FindPeerContext *find_peer_context = cls; 1289 struct FindPeerContext *find_peer_context = cls;
@@ -1958,8 +1954,6 @@ static void
1958count_peers_cb (void *cls, 1954count_peers_cb (void *cls,
1959 const struct GNUNET_PeerIdentity *first, 1955 const struct GNUNET_PeerIdentity *first,
1960 const struct GNUNET_PeerIdentity *second, 1956 const struct GNUNET_PeerIdentity *second,
1961 struct GNUNET_TIME_Relative latency,
1962 uint32_t distance,
1963 const char *emsg) 1957 const char *emsg)
1964{ 1958{
1965 struct FindPeerContext *find_peer_context = cls; 1959 struct FindPeerContext *find_peer_context = cls;
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index 9e56e99b2..968f9a32f 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -285,19 +285,21 @@ struct PeerInfo
285 struct GNUNET_CORE_InformationRequestContext *info_ctx; 285 struct GNUNET_CORE_InformationRequestContext *info_ctx;
286 286
287 /** 287 /**
288 * What is the average latency for replies received? 288 * What is the identity of the peer?
289 */ 289 */
290 struct GNUNET_TIME_Relative latency; 290 struct GNUNET_PeerIdentity id;
291 291
292#if 0
292 /** 293 /**
293 * What is the identity of the peer? 294 * What is the average latency for replies received?
294 */ 295 */
295 struct GNUNET_PeerIdentity id; 296 struct GNUNET_TIME_Relative latency;
296 297
297 /** 298 /**
298 * Transport level distance to peer. 299 * Transport level distance to peer.
299 */ 300 */
300 unsigned int distance; 301 unsigned int distance;
302#endif
301 303
302 /** 304 /**
303 * Holds matching bits from peer to current target, 305 * Holds matching bits from peer to current target,
@@ -1380,7 +1382,6 @@ update_core_preference (void *cls,
1380 * 1382 *
1381 * @param cls closure 1383 * @param cls closure
1382 * @param peer identifies the peer 1384 * @param peer identifies the peer
1383 * @param bpm_in set to the current bandwidth limit (receiving) for this peer
1384 * @param bpm_out set to the current bandwidth limit (sending) for this peer 1385 * @param bpm_out set to the current bandwidth limit (sending) for this peer
1385 * @param amount set to the amount that was actually reserved or unreserved; 1386 * @param amount set to the amount that was actually reserved or unreserved;
1386 * either the full requested amount or zero (no partial reservations) 1387 * either the full requested amount or zero (no partial reservations)
@@ -1389,7 +1390,6 @@ update_core_preference (void *cls,
1389static void 1390static void
1390update_core_preference_finish (void *cls, 1391update_core_preference_finish (void *cls,
1391 const struct GNUNET_PeerIdentity * peer, 1392 const struct GNUNET_PeerIdentity * peer,
1392 struct GNUNET_BANDWIDTH_Value32NBO bpm_in,
1393 struct GNUNET_BANDWIDTH_Value32NBO bpm_out, 1393 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
1394 int amount, uint64_t preference) 1394 int amount, uint64_t preference)
1395{ 1395{
@@ -1416,7 +1416,7 @@ update_core_preference (void *cls,
1416 matching = 63; 1416 matching = 63;
1417 } 1417 }
1418 preference = 1LL << matching; 1418 preference = 1LL << matching;
1419 peer->info_ctx = GNUNET_CORE_peer_change_preference (cfg, 1419 peer->info_ctx = GNUNET_CORE_peer_change_preference (coreAPI,
1420 &peer->id, 1420 &peer->id,
1421 GNUNET_TIME_relative_get_forever(), 1421 GNUNET_TIME_relative_get_forever(),
1422 GNUNET_BANDWIDTH_value_init (UINT32_MAX), 1422 GNUNET_BANDWIDTH_value_init (UINT32_MAX),
@@ -1433,23 +1433,23 @@ update_core_preference (void *cls,
1433 * @param peer GNUNET_PeerIdentity of the peer to add 1433 * @param peer GNUNET_PeerIdentity of the peer to add
1434 * @param bucket the already figured out bucket to add 1434 * @param bucket the already figured out bucket to add
1435 * the peer to 1435 * the peer to
1436 * @param latency the core reported latency of this peer 1436 * @param atsi performance information
1437 * @param distance the transport level distance to this peer
1438 * 1437 *
1439 * @return the newly added PeerInfo 1438 * @return the newly added PeerInfo
1440 */ 1439 */
1441static struct PeerInfo * 1440static struct PeerInfo *
1442add_peer(const struct GNUNET_PeerIdentity *peer, 1441add_peer(const struct GNUNET_PeerIdentity *peer,
1443 unsigned int bucket, 1442 unsigned int bucket,
1444 struct GNUNET_TIME_Relative latency, 1443 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1445 unsigned int distance)
1446{ 1444{
1447 struct PeerInfo *new_peer; 1445 struct PeerInfo *new_peer;
1448 GNUNET_assert(bucket < MAX_BUCKETS); 1446 GNUNET_assert(bucket < MAX_BUCKETS);
1449 GNUNET_assert(peer != NULL); 1447 GNUNET_assert(peer != NULL);
1450 new_peer = GNUNET_malloc(sizeof(struct PeerInfo)); 1448 new_peer = GNUNET_malloc(sizeof(struct PeerInfo));
1449#if 0
1451 new_peer->latency = latency; 1450 new_peer->latency = latency;
1452 new_peer->distance = distance; 1451 new_peer->distance = distance;
1452#endif
1453 1453
1454 memcpy(&new_peer->id, peer, sizeof(struct GNUNET_PeerIdentity)); 1454 memcpy(&new_peer->id, peer, sizeof(struct GNUNET_PeerIdentity));
1455 1455
@@ -1769,8 +1769,7 @@ void schedule_ping_messages()
1769static struct PeerInfo * 1769static struct PeerInfo *
1770try_add_peer(const struct GNUNET_PeerIdentity *peer, 1770try_add_peer(const struct GNUNET_PeerIdentity *peer,
1771 unsigned int bucket, 1771 unsigned int bucket,
1772 struct GNUNET_TIME_Relative latency, 1772 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1773 unsigned int distance)
1774{ 1773{
1775 int peer_bucket; 1774 int peer_bucket;
1776 struct PeerInfo *new_peer; 1775 struct PeerInfo *new_peer;
@@ -1781,7 +1780,7 @@ try_add_peer(const struct GNUNET_PeerIdentity *peer,
1781 peer_bucket = find_current_bucket(&peer->hashPubKey); 1780 peer_bucket = find_current_bucket(&peer->hashPubKey);
1782 1781
1783 GNUNET_assert(peer_bucket >= lowest_bucket); 1782 GNUNET_assert(peer_bucket >= lowest_bucket);
1784 new_peer = add_peer(peer, peer_bucket, latency, distance); 1783 new_peer = add_peer(peer, peer_bucket, atsi);
1785 1784
1786 if ((k_buckets[lowest_bucket].peers_size) >= bucket_size) 1785 if ((k_buckets[lowest_bucket].peers_size) >= bucket_size)
1787 enable_next_bucket(); 1786 enable_next_bucket();
@@ -1991,7 +1990,8 @@ static int route_result_message(struct GNUNET_MessageHeader *msg,
1991 { 1990 {
1992 increment_stats(STAT_HELLOS_PROVIDED); 1991 increment_stats(STAT_HELLOS_PROVIDED);
1993 GNUNET_TRANSPORT_offer_hello(transport_handle, hello_msg); 1992 GNUNET_TRANSPORT_offer_hello(transport_handle, hello_msg);
1994 GNUNET_CORE_peer_request_connect(cfg, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &new_peer, NULL, NULL); 1993 GNUNET_CORE_peer_request_connect(coreAPI,
1994 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &new_peer, NULL, NULL);
1995 } 1995 }
1996 } 1996 }
1997 } 1997 }
@@ -2420,7 +2420,8 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2420 { 2420 {
2421 increment_stats(STAT_HELLOS_PROVIDED); 2421 increment_stats(STAT_HELLOS_PROVIDED);
2422 GNUNET_TRANSPORT_offer_hello(transport_handle, other_hello); 2422 GNUNET_TRANSPORT_offer_hello(transport_handle, other_hello);
2423 GNUNET_CORE_peer_request_connect(cfg, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &peer_id, NULL, NULL); 2423 GNUNET_CORE_peer_request_connect(coreAPI,
2424 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &peer_id, NULL, NULL);
2424 route_message (find_msg, msg_ctx); 2425 route_message (find_msg, msg_ctx);
2425 GNUNET_free (other_hello); 2426 GNUNET_free (other_hello);
2426 return; 2427 return;
@@ -4228,7 +4229,7 @@ static int
4228handle_dht_p2p_route_request (void *cls, 4229handle_dht_p2p_route_request (void *cls,
4229 const struct GNUNET_PeerIdentity *peer, 4230 const struct GNUNET_PeerIdentity *peer,
4230 const struct GNUNET_MessageHeader *message, 4231 const struct GNUNET_MessageHeader *message,
4231 struct GNUNET_TIME_Relative latency, uint32_t distance) 4232 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
4232{ 4233{
4233#if DEBUG_DHT 4234#if DEBUG_DHT
4234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4284,7 +4285,7 @@ static int
4284handle_dht_p2p_route_result (void *cls, 4285handle_dht_p2p_route_result (void *cls,
4285 const struct GNUNET_PeerIdentity *peer, 4286 const struct GNUNET_PeerIdentity *peer,
4286 const struct GNUNET_MessageHeader *message, 4287 const struct GNUNET_MessageHeader *message,
4287 struct GNUNET_TIME_Relative latency, uint32_t distance) 4288 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
4288{ 4289{
4289#if DEBUG_DHT 4290#if DEBUG_DHT
4290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4472,13 +4473,12 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = {
4472 * 4473 *
4473 * @param cls closure 4474 * @param cls closure
4474 * @param peer peer identity this notification is about 4475 * @param peer peer identity this notification is about
4475 * @param latency reported latency of the connection with peer 4476 * @param atsi performance data
4476 * @param distance reported distance (DV) to peer
4477 */ 4477 */
4478void handle_core_connect (void *cls, 4478static void
4479 const struct GNUNET_PeerIdentity * peer, 4479handle_core_connect (void *cls,
4480 struct GNUNET_TIME_Relative latency, 4480 const struct GNUNET_PeerIdentity * peer,
4481 uint32_t distance) 4481 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
4482{ 4482{
4483 struct PeerInfo *ret; 4483 struct PeerInfo *ret;
4484 4484
@@ -4497,8 +4497,7 @@ void handle_core_connect (void *cls,
4497 GNUNET_DATACACHE_put(datacache, &peer->hashPubKey, sizeof(struct GNUNET_PeerIdentity), (const char *)peer, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_TIME_absolute_get_forever()); 4497 GNUNET_DATACACHE_put(datacache, &peer->hashPubKey, sizeof(struct GNUNET_PeerIdentity), (const char *)peer, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_TIME_absolute_get_forever());
4498 ret = try_add_peer(peer, 4498 ret = try_add_peer(peer,
4499 find_current_bucket(&peer->hashPubKey), 4499 find_current_bucket(&peer->hashPubKey),
4500 latency, 4500 atsi);
4501 distance);
4502 if (ret != NULL) 4501 if (ret != NULL)
4503 { 4502 {
4504 newly_found_peers++; 4503 newly_found_peers++;
@@ -4517,9 +4516,10 @@ void handle_core_connect (void *cls,
4517 * @param cls closure 4516 * @param cls closure
4518 * @param peer peer identity this notification is about 4517 * @param peer peer identity this notification is about
4519 */ 4518 */
4520void handle_core_disconnect (void *cls, 4519static void
4521 const struct 4520handle_core_disconnect (void *cls,
4522 GNUNET_PeerIdentity * peer) 4521 const struct
4522 GNUNET_PeerIdentity * peer)
4523{ 4523{
4524 struct PeerInfo *to_remove; 4524 struct PeerInfo *to_remove;
4525 int current_bucket; 4525 int current_bucket;
@@ -4563,7 +4563,6 @@ run (void *cls,
4563 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); 4563 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
4564 coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */ 4564 coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */
4565 1, /* queue size */ 4565 1, /* queue size */
4566 GNUNET_TIME_UNIT_FOREVER_REL,
4567 NULL, /* Closure passed to DHT functions */ 4566 NULL, /* Closure passed to DHT functions */
4568 &core_init, /* Call core_init once connected */ 4567 &core_init, /* Call core_init once connected */
4569 &handle_core_connect, /* Handle connects */ 4568 &handle_core_connect, /* Handle connects */
diff --git a/src/dv/Makefile.am b/src/dv/Makefile.am
index af3102239..de72438d7 100644
--- a/src/dv/Makefile.am
+++ b/src/dv/Makefile.am
@@ -28,7 +28,7 @@ libgnunetdv_la_LDFLAGS = \
28 28
29bin_PROGRAMS = \ 29bin_PROGRAMS = \
30 gnunet-service-dv 30 gnunet-service-dv
31 31
32gnunet_service_dv_SOURCES = \ 32gnunet_service_dv_SOURCES = \
33 gnunet-service-dv.c 33 gnunet-service-dv.c
34gnunet_service_dv_LDADD = \ 34gnunet_service_dv_LDADD = \
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index 6001e33f4..d3897f23d 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -1311,11 +1311,11 @@ void send_message_delayed (void *cls,
1311 * @param latency the latency of the connection we received the message from 1311 * @param latency the latency of the connection we received the message from
1312 * @param distance the distance to the immediate peer 1312 * @param distance the distance to the immediate peer
1313 */ 1313 */
1314static int handle_dv_data_message (void *cls, 1314static int
1315 const struct GNUNET_PeerIdentity * peer, 1315handle_dv_data_message (void *cls,
1316 const struct GNUNET_MessageHeader * message, 1316 const struct GNUNET_PeerIdentity * peer,
1317 struct GNUNET_TIME_Relative latency, 1317 const struct GNUNET_MessageHeader * message,
1318 uint32_t distance) 1318 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1319{ 1319{
1320 const p2p_dv_MESSAGE_Data *incoming = (const p2p_dv_MESSAGE_Data *) message; 1320 const p2p_dv_MESSAGE_Data *incoming = (const p2p_dv_MESSAGE_Data *) message;
1321 const struct GNUNET_MessageHeader *packed_message; 1321 const struct GNUNET_MessageHeader *packed_message;
@@ -1919,14 +1919,12 @@ void handle_dv_send_message (void *cls,
1919static int handle_dv_gossip_message (void *cls, 1919static int handle_dv_gossip_message (void *cls,
1920 const struct GNUNET_PeerIdentity *peer, 1920 const struct GNUNET_PeerIdentity *peer,
1921 const struct GNUNET_MessageHeader *message, 1921 const struct GNUNET_MessageHeader *message,
1922 struct GNUNET_TIME_Relative latency, 1922 const struct GNUNET_TRANSPORT_ATS_Information *atsi);
1923 uint32_t distance);
1924 1923
1925static int handle_dv_disconnect_message (void *cls, 1924static int handle_dv_disconnect_message (void *cls,
1926 const struct GNUNET_PeerIdentity *peer, 1925 const struct GNUNET_PeerIdentity *peer,
1927 const struct GNUNET_MessageHeader *message, 1926 const struct GNUNET_MessageHeader *message,
1928 struct GNUNET_TIME_Relative latency, 1927 const struct GNUNET_TRANSPORT_ATS_Information *atsi);
1929 uint32_t distance);
1930/** End forward declarations **/ 1928/** End forward declarations **/
1931 1929
1932 1930
@@ -2327,7 +2325,8 @@ generate_hello_address (void *cls, size_t max, void *buf)
2327 * not added) 2325 * not added)
2328 */ 2326 */
2329static struct DistantNeighbor * 2327static struct DistantNeighbor *
2330addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey, 2328addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer,
2329 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey,
2331 unsigned int referrer_peer_id, 2330 unsigned int referrer_peer_id,
2332 struct DirectNeighbor *referrer, unsigned int cost) 2331 struct DirectNeighbor *referrer, unsigned int cost)
2333{ 2332{
@@ -2466,7 +2465,10 @@ addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct GNUNET_CRYPTO
2466#if DEBUG_DV_MESSAGES 2465#if DEBUG_DV_MESSAGES
2467 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: learned about peer %llu from which we have a previous unknown message, processing!\n", my_short_id, referrer_peer_id); 2466 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: learned about peer %llu from which we have a previous unknown message, processing!\n", my_short_id, referrer_peer_id);
2468#endif 2467#endif
2469 handle_dv_data_message(NULL, &referrer->pending_messages[i].sender, referrer->pending_messages[i].message, referrer->pending_messages[i].latency, referrer->pending_messages[i].distance); 2468 handle_dv_data_message(NULL, &referrer->pending_messages[i].sender,
2469 referrer->pending_messages[i].message,
2470 referrer->pending_messages[i].latency,
2471 referrer->pending_messages[i].distance);
2470 GNUNET_free(referrer->pending_messages[i].message); 2472 GNUNET_free(referrer->pending_messages[i].message);
2471 referrer->pending_messages[i].sender_id = 0; 2473 referrer->pending_messages[i].sender_id = 0;
2472 } 2474 }
@@ -2521,14 +2523,12 @@ addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct GNUNET_CRYPTO
2521 * @param cls closure 2523 * @param cls closure
2522 * @param peer peer which sent the message (immediate sender) 2524 * @param peer peer which sent the message (immediate sender)
2523 * @param message the message 2525 * @param message the message
2524 * @param latency the latency of the connection we received the message from 2526 * @param atsi performance data
2525 * @param distance the distance to the immediate peer
2526 */ 2527 */
2527static int handle_dv_disconnect_message (void *cls, 2528static int handle_dv_disconnect_message (void *cls,
2528 const struct GNUNET_PeerIdentity *peer, 2529 const struct GNUNET_PeerIdentity *peer,
2529 const struct GNUNET_MessageHeader *message, 2530 const struct GNUNET_MessageHeader *message,
2530 struct GNUNET_TIME_Relative latency, 2531 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2531 uint32_t distance)
2532{ 2532{
2533 struct DirectNeighbor *referrer; 2533 struct DirectNeighbor *referrer;
2534 struct DistantNeighbor *distant; 2534 struct DistantNeighbor *distant;
@@ -2570,14 +2570,13 @@ static int handle_dv_disconnect_message (void *cls,
2570 * @param cls closure 2570 * @param cls closure
2571 * @param peer peer which sent the message (immediate sender) 2571 * @param peer peer which sent the message (immediate sender)
2572 * @param message the message 2572 * @param message the message
2573 * @param latency the latency of the connection we received the message from 2573 * @param atsi performance data
2574 * @param distance the distance to the immediate peer
2575 */ 2574 */
2576static int handle_dv_gossip_message (void *cls, 2575static int
2577 const struct GNUNET_PeerIdentity *peer, 2576handle_dv_gossip_message (void *cls,
2578 const struct GNUNET_MessageHeader *message, 2577 const struct GNUNET_PeerIdentity *peer,
2579 struct GNUNET_TIME_Relative latency, 2578 const struct GNUNET_MessageHeader *message,
2580 uint32_t distance) 2579 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2581{ 2580{
2582 struct DirectNeighbor *referrer; 2581 struct DirectNeighbor *referrer;
2583 p2p_dv_MESSAGE_NeighborInfo *enc_message = (p2p_dv_MESSAGE_NeighborInfo *)message; 2582 p2p_dv_MESSAGE_NeighborInfo *enc_message = (p2p_dv_MESSAGE_NeighborInfo *)message;
@@ -2623,9 +2622,10 @@ static int handle_dv_gossip_message (void *cls,
2623 * 2622 *
2624 * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise 2623 * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
2625 */ 2624 */
2626static int add_all_extended_peers (void *cls, 2625static int
2627 const GNUNET_HashCode * key, 2626add_all_extended_peers (void *cls,
2628 void *value) 2627 const GNUNET_HashCode * key,
2628 void *value)
2629{ 2629{
2630 struct NeighborSendContext *send_context = (struct NeighborSendContext *)cls; 2630 struct NeighborSendContext *send_context = (struct NeighborSendContext *)cls;
2631 struct DistantNeighbor *distant = (struct DistantNeighbor *)value; 2631 struct DistantNeighbor *distant = (struct DistantNeighbor *)value;
@@ -2660,9 +2660,10 @@ static int add_all_extended_peers (void *cls,
2660 * iterate, 2660 * iterate,
2661 * GNUNET_NO if not. 2661 * GNUNET_NO if not.
2662 */ 2662 */
2663static int gossip_all_to_all_iterator (void *cls, 2663static int
2664 const GNUNET_HashCode * key, 2664gossip_all_to_all_iterator (void *cls,
2665 void *abs_value) 2665 const GNUNET_HashCode * key,
2666 void *abs_value)
2666{ 2667{
2667 struct DirectNeighbor *direct = abs_value; 2668 struct DirectNeighbor *direct = abs_value;
2668 2669
@@ -2704,9 +2705,10 @@ gossip_all_to_all (void *cls,
2704 * 2705 *
2705 * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise 2706 * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
2706 */ 2707 */
2707static int add_all_direct_neighbors (void *cls, 2708static int
2708 const GNUNET_HashCode * key, 2709add_all_direct_neighbors (void *cls,
2709 void *value) 2710 const GNUNET_HashCode * key,
2711 void *value)
2710{ 2712{
2711 struct DirectNeighbor *direct = (struct DirectNeighbor *)value; 2713 struct DirectNeighbor *direct = (struct DirectNeighbor *)value;
2712 struct DirectNeighbor *to = (struct DirectNeighbor *)cls; 2714 struct DirectNeighbor *to = (struct DirectNeighbor *)cls;
@@ -2832,13 +2834,12 @@ process_peerinfo (void *cls,
2832 * 2834 *
2833 * @param cls closure 2835 * @param cls closure
2834 * @param peer peer identity this notification is about 2836 * @param peer peer identity this notification is about
2835 * @param latency reported latency of the connection with peer 2837 * @param atsi performance data
2836 * @param distance reported distance (DV) to peer
2837 */ 2838 */
2838void handle_core_connect (void *cls, 2839static void
2839 const struct GNUNET_PeerIdentity * peer, 2840handle_core_connect (void *cls,
2840 struct GNUNET_TIME_Relative latency, 2841 const struct GNUNET_PeerIdentity * peer,
2841 uint32_t distance) 2842 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2842{ 2843{
2843 struct DirectNeighbor *neighbor; 2844 struct DirectNeighbor *neighbor;
2844 struct DistantNeighbor *about; 2845 struct DistantNeighbor *about;
@@ -2994,7 +2995,6 @@ run (void *cls,
2994 coreAPI = 2995 coreAPI =
2995 GNUNET_CORE_connect (cfg, 2996 GNUNET_CORE_connect (cfg,
2996 1, 2997 1,
2997 GNUNET_TIME_relative_get_forever(),
2998 NULL, /* FIXME: anything we want to pass around? */ 2998 NULL, /* FIXME: anything we want to pass around? */
2999 &core_init, 2999 &core_init,
3000 &handle_core_connect, 3000 &handle_core_connect,
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index fd4ec74ed..139cb5aa9 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -1556,25 +1556,39 @@ destroy_pending_request (struct PendingRequest *pr)
1556 1556
1557 1557
1558/** 1558/**
1559 * Find latency information in 'atsi'.
1560 *
1561 * @param atsi performance data
1562 * @return connection latency
1563 */
1564static struct GNUNET_TIME_Relative
1565get_latency (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1566{
1567 /* FIXME: extract latency data from 'atsi' */
1568 return GNUNET_TIME_UNIT_SECONDS;
1569}
1570
1571
1572/**
1559 * Method called whenever a given peer connects. 1573 * Method called whenever a given peer connects.
1560 * 1574 *
1561 * @param cls closure, not used 1575 * @param cls closure, not used
1562 * @param peer peer identity this notification is about 1576 * @param peer peer identity this notification is about
1563 * @param latency reported latency of the connection with 'other' 1577 * @param atsi performance information
1564 * @param distance reported distance (DV) to 'other'
1565 */ 1578 */
1566static void 1579static void
1567peer_connect_handler (void *cls, 1580peer_connect_handler (void *cls,
1568 const struct 1581 const struct
1569 GNUNET_PeerIdentity * peer, 1582 GNUNET_PeerIdentity * peer,
1570 struct GNUNET_TIME_Relative latency, 1583 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1571 uint32_t distance)
1572{ 1584{
1573 struct ConnectedPeer *cp; 1585 struct ConnectedPeer *cp;
1574 struct MigrationReadyBlock *pos; 1586 struct MigrationReadyBlock *pos;
1575 char *fn; 1587 char *fn;
1576 uint32_t trust; 1588 uint32_t trust;
1589 struct GNUNET_TIME_Relative latency;
1577 1590
1591 latency = get_latency (atsi);
1578 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, 1592 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
1579 &peer->hashPubKey); 1593 &peer->hashPubKey);
1580 if (NULL != cp) 1594 if (NULL != cp)
@@ -1612,25 +1626,25 @@ peer_connect_handler (void *cls,
1612 * 1626 *
1613 * @param cls closure 1627 * @param cls closure
1614 * @param peer peer identity this notification is about 1628 * @param peer peer identity this notification is about
1615 * @param latency reported latency of the connection with 'other'
1616 * @param distance reported distance (DV) to 'other'
1617 * @param bandwidth_in available amount of inbound bandwidth 1629 * @param bandwidth_in available amount of inbound bandwidth
1618 * @param bandwidth_out available amount of outbound bandwidth 1630 * @param bandwidth_out available amount of outbound bandwidth
1619 * @param timeout absolute time when this peer will time out 1631 * @param timeout absolute time when this peer will time out
1620 * unless we see some further activity from it 1632 * unless we see some further activity from it
1633 * @param atsi status information
1621 */ 1634 */
1622static void 1635static void
1623peer_status_handler (void *cls, 1636peer_status_handler (void *cls,
1624 const struct 1637 const struct
1625 GNUNET_PeerIdentity * peer, 1638 GNUNET_PeerIdentity * peer,
1626 struct GNUNET_TIME_Relative latency,
1627 uint32_t distance,
1628 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 1639 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
1629 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 1640 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
1630 struct GNUNET_TIME_Absolute timeout) 1641 struct GNUNET_TIME_Absolute timeout,
1642 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1631{ 1643{
1632 struct ConnectedPeer *cp; 1644 struct ConnectedPeer *cp;
1645 struct GNUNET_TIME_Relative latency;
1633 1646
1647 latency = get_latency (atsi);
1634 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, 1648 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
1635 &peer->hashPubKey); 1649 &peer->hashPubKey);
1636 if (cp == NULL) 1650 if (cp == NULL)
@@ -2529,7 +2543,6 @@ refresh_bloomfilter (struct PendingRequest *pr)
2529 * 2543 *
2530 * @param cls the requests "struct PendingRequest*" 2544 * @param cls the requests "struct PendingRequest*"
2531 * @param peer identifies the peer 2545 * @param peer identifies the peer
2532 * @param bpm_in set to the current bandwidth limit (receiving) for this peer
2533 * @param bpm_out set to the current bandwidth limit (sending) for this peer 2546 * @param bpm_out set to the current bandwidth limit (sending) for this peer
2534 * @param amount set to the amount that was actually reserved or unreserved 2547 * @param amount set to the amount that was actually reserved or unreserved
2535 * @param preference current traffic preference for the given peer 2548 * @param preference current traffic preference for the given peer
@@ -2538,7 +2551,6 @@ static void
2538target_reservation_cb (void *cls, 2551target_reservation_cb (void *cls,
2539 const struct 2552 const struct
2540 GNUNET_PeerIdentity * peer, 2553 GNUNET_PeerIdentity * peer,
2541 struct GNUNET_BANDWIDTH_Value32NBO bpm_in,
2542 struct GNUNET_BANDWIDTH_Value32NBO bpm_out, 2554 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
2543 int amount, 2555 int amount,
2544 uint64_t preference) 2556 uint64_t preference)
@@ -2984,7 +2996,7 @@ forward_request_task (void *cls,
2984 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, 2996 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
2985 &psc.target.hashPubKey); 2997 &psc.target.hashPubKey);
2986 GNUNET_assert (NULL != cp); 2998 GNUNET_assert (NULL != cp);
2987 pr->irc = GNUNET_CORE_peer_change_preference (cfg, 2999 pr->irc = GNUNET_CORE_peer_change_preference (core,
2988 &psc.target, 3000 &psc.target,
2989 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 3001 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
2990 GNUNET_BANDWIDTH_value_init (UINT32_MAX), 3002 GNUNET_BANDWIDTH_value_init (UINT32_MAX),
@@ -2999,7 +3011,7 @@ forward_request_task (void *cls,
2999 /* force forwarding */ 3011 /* force forwarding */
3000 static struct GNUNET_BANDWIDTH_Value32NBO zerobw; 3012 static struct GNUNET_BANDWIDTH_Value32NBO zerobw;
3001 target_reservation_cb (pr, &psc.target, 3013 target_reservation_cb (pr, &psc.target,
3002 zerobw, zerobw, 0, 0.0); 3014 zerobw, 0, 0.0);
3003 } 3015 }
3004} 3016}
3005 3017
@@ -3467,8 +3479,7 @@ put_migration_continuation (void *cls,
3467 * @param other the other peer involved (sender or receiver, NULL 3479 * @param other the other peer involved (sender or receiver, NULL
3468 * for loopback messages where we are both sender and receiver) 3480 * for loopback messages where we are both sender and receiver)
3469 * @param message the actual message 3481 * @param message the actual message
3470 * @param latency reported latency of the connection with 'other' 3482 * @param atsi performance information
3471 * @param distance reported distance (DV) to 'other'
3472 * @return GNUNET_OK to keep the connection open, 3483 * @return GNUNET_OK to keep the connection open,
3473 * GNUNET_SYSERR to close it (signal serious error) 3484 * GNUNET_SYSERR to close it (signal serious error)
3474 */ 3485 */
@@ -3476,8 +3487,7 @@ static int
3476handle_p2p_put (void *cls, 3487handle_p2p_put (void *cls,
3477 const struct GNUNET_PeerIdentity *other, 3488 const struct GNUNET_PeerIdentity *other,
3478 const struct GNUNET_MessageHeader *message, 3489 const struct GNUNET_MessageHeader *message,
3479 struct GNUNET_TIME_Relative latency, 3490 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
3480 uint32_t distance)
3481{ 3491{
3482 const struct PutMessage *put; 3492 const struct PutMessage *put;
3483 uint16_t msize; 3493 uint16_t msize;
@@ -3608,8 +3618,7 @@ handle_p2p_put (void *cls,
3608 * @param other the other peer involved (sender or receiver, NULL 3618 * @param other the other peer involved (sender or receiver, NULL
3609 * for loopback messages where we are both sender and receiver) 3619 * for loopback messages where we are both sender and receiver)
3610 * @param message the actual message 3620 * @param message the actual message
3611 * @param latency reported latency of the connection with 'other' 3621 * @param atsi performance information
3612 * @param distance reported distance (DV) to 'other'
3613 * @return GNUNET_OK to keep the connection open, 3622 * @return GNUNET_OK to keep the connection open,
3614 * GNUNET_SYSERR to close it (signal serious error) 3623 * GNUNET_SYSERR to close it (signal serious error)
3615 */ 3624 */
@@ -3617,8 +3626,7 @@ static int
3617handle_p2p_migration_stop (void *cls, 3626handle_p2p_migration_stop (void *cls,
3618 const struct GNUNET_PeerIdentity *other, 3627 const struct GNUNET_PeerIdentity *other,
3619 const struct GNUNET_MessageHeader *message, 3628 const struct GNUNET_MessageHeader *message,
3620 struct GNUNET_TIME_Relative latency, 3629 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
3621 uint32_t distance)
3622{ 3630{
3623 struct ConnectedPeer *cp; 3631 struct ConnectedPeer *cp;
3624 const struct MigrationStopMessage *msm; 3632 const struct MigrationStopMessage *msm;
@@ -3955,8 +3963,7 @@ check_duplicate_request_peer (void *cls,
3955 * @param other the other peer involved (sender or receiver, NULL 3963 * @param other the other peer involved (sender or receiver, NULL
3956 * for loopback messages where we are both sender and receiver) 3964 * for loopback messages where we are both sender and receiver)
3957 * @param message the actual message 3965 * @param message the actual message
3958 * @param latency reported latency of the connection with 'other' 3966 * @param atsi performance information
3959 * @param distance reported distance (DV) to 'other'
3960 * @return GNUNET_OK to keep the connection open, 3967 * @return GNUNET_OK to keep the connection open,
3961 * GNUNET_SYSERR to close it (signal serious error) 3968 * GNUNET_SYSERR to close it (signal serious error)
3962 */ 3969 */
@@ -3964,8 +3971,7 @@ static int
3964handle_p2p_get (void *cls, 3971handle_p2p_get (void *cls,
3965 const struct GNUNET_PeerIdentity *other, 3972 const struct GNUNET_PeerIdentity *other,
3966 const struct GNUNET_MessageHeader *message, 3973 const struct GNUNET_MessageHeader *message,
3967 struct GNUNET_TIME_Relative latency, 3974 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
3968 uint32_t distance)
3969{ 3975{
3970 struct PendingRequest *pr; 3976 struct PendingRequest *pr;
3971 struct ConnectedPeer *cp; 3977 struct ConnectedPeer *cp;
@@ -4491,7 +4497,6 @@ main_init (struct GNUNET_SERVER_Handle *server,
4491 requests_by_expiration_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 4497 requests_by_expiration_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
4492 core = GNUNET_CORE_connect (cfg, 4498 core = GNUNET_CORE_connect (cfg,
4493 1, /* larger? */ 4499 1, /* larger? */
4494 GNUNET_TIME_UNIT_FOREVER_REL,
4495 NULL, 4500 NULL,
4496 NULL, 4501 NULL,
4497 &peer_connect_handler, 4502 &peer_connect_handler,
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c
index 8c3bb9be7..bd76b17d3 100644
--- a/src/hostlist/gnunet-daemon-hostlist.c
+++ b/src/hostlist/gnunet-daemon-hostlist.c
@@ -141,13 +141,12 @@ core_init (void *cls,
141 * Core handler for p2p hostlist advertisements 141 * Core handler for p2p hostlist advertisements
142 */ 142 */
143static int advertisement_handler (void *cls, 143static int advertisement_handler (void *cls,
144 const struct GNUNET_PeerIdentity * peer, 144 const struct GNUNET_PeerIdentity * peer,
145 const struct GNUNET_MessageHeader * message, 145 const struct GNUNET_MessageHeader * message,
146 struct GNUNET_TIME_Relative latency, 146 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
147 uint32_t distance)
148{ 147{
149 GNUNET_assert (NULL != client_adv_handler); 148 GNUNET_assert (NULL != client_adv_handler);
150 return (*client_adv_handler) (cls, peer, message, latency, distance); 149 return (*client_adv_handler) (cls, peer, message, atsi);
151} 150}
152 151
153 152
@@ -156,23 +155,21 @@ static int advertisement_handler (void *cls,
156 * 155 *
157 * @param cls closure 156 * @param cls closure
158 * @param peer peer identity this notification is about 157 * @param peer peer identity this notification is about
159 * @param latency reported latency of the connection with 'other' 158 * @param atsi performance data
160 * @param distance reported distance (DV) to 'other'
161 */ 159 */
162static void 160static void
163connect_handler (void *cls, 161connect_handler (void *cls,
164 const struct 162 const struct
165 GNUNET_PeerIdentity * peer, 163 GNUNET_PeerIdentity * peer,
166 struct GNUNET_TIME_Relative latency, 164 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
167 uint32_t distance)
168{ 165{
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
170 "A new peer connected, notifying client and server\n"); 167 "A new peer connected, notifying client and server\n");
171 if ( NULL != client_ch) 168 if ( NULL != client_ch)
172 (*client_ch) (cls, peer, latency, distance); 169 (*client_ch) (cls, peer, atsi);
173#if HAVE_MHD 170#if HAVE_MHD
174 if ( NULL != server_ch) 171 if ( NULL != server_ch)
175 (*server_ch) (cls, peer, latency, distance); 172 (*server_ch) (cls, peer, atsi);
176#endif 173#endif
177} 174}
178 175
@@ -270,7 +267,6 @@ run (void *cls,
270 267
271 core = GNUNET_CORE_connect (cfg, 268 core = GNUNET_CORE_connect (cfg,
272 1, 269 1,
273 GNUNET_TIME_UNIT_FOREVER_REL,
274 NULL, 270 NULL,
275 &core_init, 271 &core_init,
276 &connect_handler, &disconnect_handler, NULL, 272 &connect_handler, &disconnect_handler, NULL,
diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c
index 9e5cbda65..503adb8a0 100644
--- a/src/hostlist/hostlist-client.c
+++ b/src/hostlist/hostlist-client.c
@@ -1137,15 +1137,13 @@ task_hostlist_saving (void *cls,
1137 * 1137 *
1138 * @param cls closure 1138 * @param cls closure
1139 * @param peer peer identity this notification is about 1139 * @param peer peer identity this notification is about
1140 * @param latency reported latency of the connection with 'other' 1140 * @param atsi performance data
1141 * @param distance reported distance (DV) to 'other'
1142 */ 1141 */
1143static void 1142static void
1144handler_connect (void *cls, 1143handler_connect (void *cls,
1145 const struct 1144 const struct
1146 GNUNET_PeerIdentity * peer, 1145 GNUNET_PeerIdentity * peer,
1147 struct GNUNET_TIME_Relative latency, 1146 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1148 uint32_t distance)
1149{ 1147{
1150 GNUNET_assert (stat_connection_count < UINT_MAX); 1148 GNUNET_assert (stat_connection_count < UINT_MAX);
1151 stat_connection_count++; 1149 stat_connection_count++;
@@ -1181,17 +1179,15 @@ handler_disconnect (void *cls,
1181 * @param cls closure (always NULL) 1179 * @param cls closure (always NULL)
1182 * @param peer the peer sending the message 1180 * @param peer the peer sending the message
1183 * @param message the actual message 1181 * @param message the actual message
1184 * @param latency latency 1182 * @param atsi performance data
1185 * @param distance distance
1186 * @return GNUNET_OK to keep the connection open, 1183 * @return GNUNET_OK to keep the connection open,
1187 * GNUNET_SYSERR to close it (signal serious error) 1184 * GNUNET_SYSERR to close it (signal serious error)
1188 */ 1185 */
1189static int 1186static int
1190handler_advertisement (void *cls, 1187handler_advertisement (void *cls,
1191 const struct GNUNET_PeerIdentity * peer, 1188 const struct GNUNET_PeerIdentity * peer,
1192 const struct GNUNET_MessageHeader * message, 1189 const struct GNUNET_MessageHeader * message,
1193 struct GNUNET_TIME_Relative latency, 1190 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1194 uint32_t distance)
1195{ 1191{
1196 size_t size; 1192 size_t size;
1197 size_t uri_size; 1193 size_t uri_size;
diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c
index 1c85f8f75..95272a555 100644
--- a/src/hostlist/hostlist-server.c
+++ b/src/hostlist/hostlist-server.c
@@ -376,15 +376,13 @@ adv_transmit_ready ( void *cls, size_t size, void *buf)
376 * 376 *
377 * @param cls closure 377 * @param cls closure
378 * @param peer peer identity this notification is about 378 * @param peer peer identity this notification is about
379 * @param latency reported latency of the connection with 'other' 379 * @param atsi performance data
380 * @param distance reported distance (DV) to 'other'
381 */ 380 */
382static void 381static void
383connect_handler (void *cls, 382connect_handler (void *cls,
384 const struct 383 const struct
385 GNUNET_PeerIdentity * peer, 384 GNUNET_PeerIdentity * peer,
386 struct GNUNET_TIME_Relative latency, 385 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
387 uint32_t distance)
388{ 386{
389 size_t size; 387 size_t size;
390 388
diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
index d64fdf587..c780c128b 100644
--- a/src/hostlist/test_gnunet_daemon_hostlist_learning.c
+++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c
@@ -283,11 +283,11 @@ check_statistics (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
283/** 283/**
284 * Core handler for p2p hostlist advertisements 284 * Core handler for p2p hostlist advertisements
285 */ 285 */
286static int ad_arrive_handler (void *cls, 286static int
287 const struct GNUNET_PeerIdentity * peer, 287ad_arrive_handler (void *cls,
288 const struct GNUNET_MessageHeader * message, 288 const struct GNUNET_PeerIdentity * peer,
289 struct GNUNET_TIME_Relative latency, 289 const struct GNUNET_MessageHeader * message,
290 uint32_t distance) 290 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
291{ 291{
292 char *hostname; 292 char *hostname;
293 char *expected_uri; 293 char *expected_uri;
@@ -371,7 +371,6 @@ setup_learn_peer (struct PeerContext *p, const char *cfgname)
371 371
372 p->core = GNUNET_CORE_connect (p->cfg, 372 p->core = GNUNET_CORE_connect (p->cfg,
373 1, 373 1,
374 GNUNET_TIME_UNIT_FOREVER_REL,
375 NULL, 374 NULL,
376 NULL, 375 NULL,
377 NULL, NULL, NULL, 376 NULL, NULL, NULL,
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
index 9c102988b..abfcd1d3b 100644
--- a/src/include/gnunet_core_service.h
+++ b/src/include/gnunet_core_service.h
@@ -37,6 +37,7 @@ extern "C"
37#endif 37#endif
38 38
39#include "gnunet_util_lib.h" 39#include "gnunet_util_lib.h"
40#include "gnunet_transport_service.h"
40 41
41/** 42/**
42 * Version number of GNUnet-core API. 43 * Version number of GNUnet-core API.
@@ -55,35 +56,32 @@ struct GNUNET_CORE_Handle;
55 * 56 *
56 * @param cls closure 57 * @param cls closure
57 * @param peer peer identity this notification is about 58 * @param peer peer identity this notification is about
58 * @param latency reported latency of the connection with 'other' 59 * @param atsi performance data for the connection
59 * @param distance reported distance (DV) to 'other'
60 */ 60 */
61typedef void (*GNUNET_CORE_ConnectEventHandler) (void *cls, 61typedef void (*GNUNET_CORE_ConnectEventHandler) (void *cls,
62 const struct 62 const struct
63 GNUNET_PeerIdentity * peer, 63 GNUNET_PeerIdentity *peer,
64 struct GNUNET_TIME_Relative latency, 64 const struct GNUNET_TRANSPORT_ATS_Information *atsi);
65 uint32_t distance); 65
66 66
67/** 67/**
68 * Method called whenever a given peer has a status change. 68 * Method called whenever a given peer has a status change.
69 * 69 *
70 * @param cls closure 70 * @param cls closure
71 * @param peer peer identity this notification is about 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 72 * @param timeout absolute time when this peer will time out
77 * unless we see some further activity from it 73 * unless we see some further activity from it
74 * @param bandwidth_in available amount of inbound bandwidth
75 * @param bandwidth_out available amount of outbound bandwidth
76 * @param atsi performance data for the connection
78 */ 77 */
79typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls, 78typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls,
80 const struct 79 const struct
81 GNUNET_PeerIdentity * peer, 80 GNUNET_PeerIdentity * peer,
82 struct GNUNET_TIME_Relative latency,
83 uint32_t distance,
84 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 81 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
85 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 82 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
86 struct GNUNET_TIME_Absolute timeout); 83 struct GNUNET_TIME_Absolute timeout,
84 const struct GNUNET_TRANSPORT_ATS_Information *atsi);
87 85
88 86
89/** 87/**
@@ -94,29 +92,26 @@ typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls,
94 */ 92 */
95typedef void (*GNUNET_CORE_DisconnectEventHandler) (void *cls, 93typedef void (*GNUNET_CORE_DisconnectEventHandler) (void *cls,
96 const struct 94 const struct
97 GNUNET_PeerIdentity * peer); 95 GNUNET_PeerIdentity *peer);
98 96
99 97
100/** 98/**
101 * Functions with this signature are called whenever a message is 99 * Functions with this signature are called whenever a message is
102 * received or transmitted. 100 * received or transmitted.
103 * 101 *
104 * @param cls closure 102 * @param cls closure (set from GNUNET_CORE_connect)
105 * @param peer the other peer involved (sender or receiver, NULL 103 * @param peer the other peer involved (sender or receiver, NULL
106 * for loopback messages where we are both sender and receiver) 104 * for loopback messages where we are both sender and receiver)
107 * @param message the actual message 105 * @param message the actual message
108 * @param latency reported latency of the connection with 'other' 106 * @param atsi performance data for the connection
109 * @param distance reported distance (DV) to 'other'
110 * @return GNUNET_OK to keep the connection open, 107 * @return GNUNET_OK to keep the connection open,
111 * GNUNET_SYSERR to close it (signal serious error) 108 * GNUNET_SYSERR to close it (signal serious error)
112 */ 109 */
113typedef int 110typedef int
114 (*GNUNET_CORE_MessageCallback) (void *cls, 111 (*GNUNET_CORE_MessageCallback) (void *cls,
115 const struct GNUNET_PeerIdentity * other, 112 const struct GNUNET_PeerIdentity *other,
116 const struct GNUNET_MessageHeader * 113 const struct GNUNET_MessageHeader *message,
117 message, 114 const struct GNUNET_TRANSPORT_ATS_Information *atsi);
118 struct GNUNET_TIME_Relative latency,
119 uint32_t distance);
120 115
121 116
122/** 117/**
@@ -180,7 +175,6 @@ typedef void
180 * 175 *
181 * @param cfg configuration to use 176 * @param cfg configuration to use
182 * @param queue_size size of the per-peer message queue 177 * @param queue_size size of the per-peer message queue
183 * @param timeout after how long should we give up trying to connect to the core service?
184 * @param cls closure for the various callbacks that follow (including handlers in the handlers array) 178 * @param cls closure for the various callbacks that follow (including handlers in the handlers array)
185 * @param init callback to call on timeout or once we have successfully 179 * @param init callback to call on timeout or once we have successfully
186 * connected to the core service; note that timeout is only meaningful if init is not NULL 180 * connected to the core service; note that timeout is only meaningful if init is not NULL
@@ -217,7 +211,6 @@ typedef void
217struct GNUNET_CORE_Handle * 211struct GNUNET_CORE_Handle *
218GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 212GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
219 unsigned int queue_size, 213 unsigned int queue_size,
220 struct GNUNET_TIME_Relative timeout,
221 void *cls, 214 void *cls,
222 GNUNET_CORE_StartupCallback init, 215 GNUNET_CORE_StartupCallback init,
223 GNUNET_CORE_ConnectEventHandler connects, 216 GNUNET_CORE_ConnectEventHandler connects,
@@ -231,7 +224,9 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
231 224
232 225
233/** 226/**
234 * Disconnect from the core service. 227 * Disconnect from the core service. This function can only
228 * be called *after* all pending 'GNUNET_CORE_notify_transmit_ready'
229 * requests have been explicitly cancelled.
235 * 230 *
236 * @param handle connection to core to disconnect 231 * @param handle connection to core to disconnect
237 */ 232 */
@@ -257,7 +252,7 @@ struct GNUNET_CORE_PeerRequestHandle;
257 * to our connection attempt within the given time frame, 'cont' will 252 * to our connection attempt within the given time frame, 'cont' will
258 * be called with the TIMEOUT reason code. 253 * be called with the TIMEOUT reason code.
259 * 254 *
260 * @param cfg configuration to use 255 * @param h core handle
261 * @param timeout how long to try to talk to core 256 * @param timeout how long to try to talk to core
262 * @param peer who should we connect to 257 * @param peer who should we connect to
263 * @param cont function to call once the request has been completed (or timed out) 258 * @param cont function to call once the request has been completed (or timed out)
@@ -265,7 +260,7 @@ struct GNUNET_CORE_PeerRequestHandle;
265 * @return NULL on error (cont will not be called), otherwise handle for cancellation 260 * @return NULL on error (cont will not be called), otherwise handle for cancellation
266 */ 261 */
267struct GNUNET_CORE_PeerRequestHandle * 262struct GNUNET_CORE_PeerRequestHandle *
268GNUNET_CORE_peer_request_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 263GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
269 struct GNUNET_TIME_Relative timeout, 264 struct GNUNET_TIME_Relative timeout,
270 const struct GNUNET_PeerIdentity * peer, 265 const struct GNUNET_PeerIdentity * peer,
271 GNUNET_SCHEDULER_Task cont, 266 GNUNET_SCHEDULER_Task cont,
@@ -283,14 +278,11 @@ GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *r
283 278
284 279
285/** 280/**
286 * Function called with statistics about the given peer. 281 * Function called with perference change information about the given peer.
287 * 282 *
288 * @param cls closure 283 * @param cls closure
289 * @param peer identifies the peer 284 * @param peer identifies the peer
290 * @param bpm_in set to the current bandwidth limit (receiving) for this peer 285 * @param bandwidth_out available amount of outbound bandwidth
291 * @param bpm_out set to the current bandwidth limit (sending) for this peer
292 * @param latency current latency estimate, "FOREVER" if we have been
293 * disconnected
294 * @param amount set to the amount that was actually reserved or unreserved; 286 * @param amount set to the amount that was actually reserved or unreserved;
295 * either the full requested amount or zero (no partial reservations) 287 * either the full requested amount or zero (no partial reservations)
296 * @param preference current traffic preference for the given peer 288 * @param preference current traffic preference for the given peer
@@ -299,8 +291,7 @@ typedef void
299 (*GNUNET_CORE_PeerConfigurationInfoCallback) (void *cls, 291 (*GNUNET_CORE_PeerConfigurationInfoCallback) (void *cls,
300 const struct 292 const struct
301 GNUNET_PeerIdentity * peer, 293 GNUNET_PeerIdentity * peer,
302 struct GNUNET_BANDWIDTH_Value32NBO bpm_in, 294 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
303 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
304 int amount, 295 int amount,
305 uint64_t preference); 296 uint64_t preference);
306 297
@@ -314,8 +305,9 @@ struct GNUNET_CORE_InformationRequestContext;
314 305
315/** 306/**
316 * Obtain statistics and/or change preferences for the given peer. 307 * Obtain statistics and/or change preferences for the given peer.
308 * You can only have one such pending request per peer.
317 * 309 *
318 * @param cfg configuration to use 310 * @param h core handle
319 * @param peer identifies the peer 311 * @param peer identifies the peer
320 * @param timeout after how long should we give up (and call "info" with NULL 312 * @param timeout after how long should we give up (and call "info" with NULL
321 * for "peer" to signal an error)? 313 * for "peer" to signal an error)?
@@ -337,7 +329,7 @@ struct GNUNET_CORE_InformationRequestContext;
337 * @return NULL on error 329 * @return NULL on error
338 */ 330 */
339struct GNUNET_CORE_InformationRequestContext * 331struct GNUNET_CORE_InformationRequestContext *
340GNUNET_CORE_peer_change_preference (const struct GNUNET_CONFIGURATION_Handle *cfg, 332GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
341 const struct GNUNET_PeerIdentity *peer, 333 const struct GNUNET_PeerIdentity *peer,
342 struct GNUNET_TIME_Relative timeout, 334 struct GNUNET_TIME_Relative timeout,
343 struct GNUNET_BANDWIDTH_Value32NBO bw_out, 335 struct GNUNET_BANDWIDTH_Value32NBO bw_out,
@@ -349,25 +341,33 @@ GNUNET_CORE_peer_change_preference (const struct GNUNET_CONFIGURATION_Handle *cf
349 341
350/** 342/**
351 * Cancel request for getting information about a peer. 343 * Cancel request for getting information about a peer.
344 * Note that an eventual change in preference, trust or bandwidth
345 * assignment MAY have already been committed at the time,
346 * so cancelling a request is NOT sure to undo the original
347 * request. The original request may or may not still commit.
348 * The only thing cancellation ensures is that the callback
349 * from the original request will no longer be called.
352 * 350 *
353 * @param irc context returned by the original GNUNET_CORE_peer_get_info call 351 * @param irc context returned by the original GNUNET_CORE_peer_get_info call
354 */ 352 */
355void 353void
356GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc); 354GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc);
357 355
356
358/** 357/**
359 * Obtain statistics and/or change preferences for the given peer. 358 * Iterate over all connected peers.
360 * 359 *
361 * @param cfg configuration to use 360 * @param h core handle
362 * @param peer_cb function to call with the peer information 361 * @param peer_cb function to call with the peer information
363 * @param cb_cls closure for peer_cb 362 * @param cb_cls closure for peer_cb
364 * @return GNUNET_OK if iterating, GNUNET_SYSERR on error 363 * @return GNUNET_OK on success, GNUNET_SYSERR on errors
365 */ 364 */
366int 365int
367GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, 366GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h,
368 GNUNET_CORE_ConnectEventHandler peer_cb, 367 GNUNET_CORE_ConnectEventHandler peer_cb,
369 void *cb_cls); 368 void *cb_cls);
370 369
370
371/** 371/**
372 * Handle for a transmission request. 372 * Handle for a transmission request.
373 */ 373 */
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 0bcd59838..4d9fec4ca 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -357,19 +357,26 @@ extern "C"
357#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 73 357#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 73
358 358
359/** 359/**
360 * Request from client with message to transmit. 360 * Request from client to transmit message.
361 */ 361 */
362#define GNUNET_MESSAGE_TYPE_CORE_SEND 74 362#define GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST 74
363 363
364/** 364/**
365 * Request from client asking to connect to a peer. 365 * Confirmation from core that message can now be sent
366 */
367#define GNUNET_MESSAGE_TYPE_CORE_SEND_READY 75
368
369/**
370 * Client with message to transmit (after SEND_READY confirmation
371 * was received).
366 */ 372 */
367#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 75 373#define GNUNET_MESSAGE_TYPE_CORE_SEND 76
368 374
369/** 375/**
370 * Request from client asking to call back with all connected peers. 376 * Request from client asking to connect to a peer.
371 */ 377 */
372#define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS 76 378#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 77
379
373 380
374/** 381/**
375 * Session key exchange between peers. 382 * Session key exchange between peers.
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h
index 97bc36a79..2e8a04594 100644
--- a/src/include/gnunet_testing_lib.h
+++ b/src/include/gnunet_testing_lib.h
@@ -395,8 +395,6 @@ typedef void (*GNUNET_TESTING_NotifyConnection)(void *cls,
395typedef void (*GNUNET_TESTING_NotifyTopology)(void *cls, 395typedef void (*GNUNET_TESTING_NotifyTopology)(void *cls,
396 const struct GNUNET_PeerIdentity *first, 396 const struct GNUNET_PeerIdentity *first,
397 const struct GNUNET_PeerIdentity *second, 397 const struct GNUNET_PeerIdentity *second,
398 struct GNUNET_TIME_Relative latency,
399 uint32_t distance,
400 const char *emsg); 398 const char *emsg);
401 399
402/** 400/**
diff --git a/src/include/gnunet_transport_plugin.h b/src/include/gnunet_transport_plugin.h
index d367779e1..31138e8f5 100644
--- a/src/include/gnunet_transport_plugin.h
+++ b/src/include/gnunet_transport_plugin.h
@@ -36,341 +36,6 @@
36#include "gnunet_statistics_service.h" 36#include "gnunet_statistics_service.h"
37#include "gnunet_transport_service.h" 37#include "gnunet_transport_service.h"
38 38
39
40/**
41 * The structs defined here are used by the transport plugin to tell ATS about
42 * the transport's properties like cost and quality and on the other side
43 * the structs are used by highlevel components to communicate the constraints
44 * they have for a transport to ATS
45 *
46 * +---+
47 * +-----------+ Constraints | | Plugin properties +---------+
48 * | Highlevel |------------> |ATS| <------------------|Transport|
49 * | Component | ATS struct | | ATS struct | Plugin |
50 * +-----------+ | | +---------+
51 * +---+
52 *
53 */
54
55#define GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR 0
56
57/**
58 * Enum defining all known property types for ATS
59 * Enum values are used in the GNUNET_TRANSPORT_ATS_Information struct as (key,value)-pair
60 *
61 * Cost are always stored in uint32_t, so all units used to define costs
62 * have to be normalized to fit in uint32_t [0 .. 4.294.967.295]
63 *
64 * To keep the elements ordered
65 * 1..1024 : Values with a relation to cost
66 * 1025..2048 : Values with a relation to quality
67 * 2049..3072 : Values with a relation to availability
68 *
69 */
70enum GNUNET_TRANSPORT_ATS_Property
71{
72
73 /* Cost related values */
74 /* =================== */
75
76 /**
77 * Volume based cost in financial units to transmit data
78 *
79 * Note: This value is not bound to a specific currency or unit and only
80 * used locally.
81 * "cent" just refers the smallest amount of money in the respective
82 * currency.
83 *
84 * Unit: [cent/MB]
85 *
86 * Interpretation: less is better
87 *
88 * Examples:
89 * LAN: 0 [cent/MB]
90 * 2G : 10 [cent/MB]
91 */
92 GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_VOLUME = 1,
93
94 /**
95 * Time based cost in financial units to transmit data
96 *
97 * Note: This value is not bound to a specific currency or unit and only
98 * used locally.
99 * "cent" just refers the smallest amount of money in the respective
100 * currency.
101 *
102 * Unit: [cent/h]
103 *
104 * Interpretation: less is better
105 *
106 * Examples:
107 * LAN : 0 [cent/h]
108 * Dialup: 10 [cent/h]
109 */
110 GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_TIME = 2,
111
112 /**
113 * Computational costs
114 *
115 * Effort of preparing data to be sent with this transport
116 * Includes encoding, encryption and conversion of data
117 * Partial values can be summed up: c_sum = c_enc + c_enc + c_conv
118 * Resulting values depend on local system properties, e.g. CPU
119 *
120 * Unit: [ms/GB]
121 *
122 * Interpretation: less is better
123 *
124 * Examples:
125 *
126 * HTTPS with AES CBC-256: 7,382
127 * HTTPS with AES CBC-128: 5,279
128 * HTTPS with RC4-1024: 2,652
129 */
130 GNUNET_TRANSPORT_ATS_COST_COMPUTATIONAL = 3,
131
132 /**
133 * Energy consumption
134 *
135 * Energy consumption using this transport when sending with a certain
136 * power at a certain bitrate. This is only an approximation based on:
137 * Energy consumption E = P / D
138 *
139 * with:
140 * Power P in Watt (J/s)
141 * Datarate D in MBit/s
142 *
143 * Conversion between power P and dBm used by WLAN in radiotap's dBm TX power:
144 *
145 * Lp(dbm) = 10 log10 (P/ 1mW)
146 *
147 * => P = 1 mW * 10^(Lp(dbm)/10)
148 *
149 * Unit: [mJ/MB]
150 *
151 * Interpretation: less is better
152 *
153 * Examples:
154 *
155 * LAN: 0
156 * WLAN: 89 (600 mW @ 802.11g /w 54 MBit/s)
157 * Bluetooth: 267 (100 mW @ BT2.0 EDR /w 3 MBit/s)
158 */
159 GNUNET_TRANSPORT_ATS_COST_ENERGY_CONSUMPTION = 4,
160
161 /**
162 * Connect cost
163 * How many bytes are transmitted to initiate a new connection using
164 * this transport?
165 *
166 * Unit: [bytes]
167 *
168 * Interpretation: less is better
169 *
170 * Examples:
171 *
172 * UDP (No connection) :
173 * 0 bytes
174 * TCP (TCP 3-Way handshake):
175 * 220 bytes Ethernet, 172 bytes TCP/IP, 122 bytes TCP
176 * HTTP (TCP + Header) :
177 * 477 bytes Ethernet, 429 bytes TCP/IP, 374 bytes TCP, 278 bytes HTTP
178 * HTTPS HTTP+TLS Handshake:
179 * 2129 bytes Ethernet, 1975 bytes TCP/IP, 1755 bytes TCP, 1403 bytes HTTPS
180 *
181 * */
182 GNUNET_TRANSPORT_ATS_COST_CONNECT = 5,
183
184 /**
185 * Bandwidth cost
186 *
187 * How many bandwidth is available to consume?
188 * Used to calculate which impact sending data with this transport has
189 *
190 * Unit: [kB/s]
191 *
192 * Interpretation: more is better
193 *
194 * Examples:
195 * LAN: 12,800 (100 MBit/s)
196 * WLAN: 6,912 (54 MBit/s)
197 * Dial-up: 8 (64 Kbit/s)
198 *
199 */
200 GNUNET_TRANSPORT_ATS_COST_BANDWITH_AVAILABLE = 6,
201
202 /**
203 * Network overhead
204 *
205 * How many bytes are sent over the wire when 1 kilobyte (1024 bytes)
206 * of application data is transmitted?
207 * A factor used with connect cost, bandwidth cost and energy cost
208 * to describe the overhead produced by the transport protocol
209 *
210 * Unit: [bytes/kb]
211 *
212 * Interpretation: less is better
213 *
214 * Examples:
215 *
216 * TCP/IPv4 over Ethernet: 1024 + 38 + 20 + 20 = 1102 [bytes/kb]
217 * TCP/IPv6 over Ethernet: 1024 + 38 + 20 + 40 = 1122 [bytes/kb]
218 * UDP/IPv4 over Ethernet: 1024 + 38 + 20 + 8 = 1090 [bytes/kb]
219 * UDP/IPv6 over Ethernet: 1024 + 38 + 40 + 8 = 1110 [bytes/kb]
220 */
221 GNUNET_TRANSPORT_ATS_COST_NETWORK_OVERHEAD = 7,
222
223
224 /* Quality related values */
225 /* ====================== */
226
227 /* Physical layer quality properties */
228
229 /**
230 * Signal strength on physical layer
231 *
232 * Unit: [dBm]
233 */
234 GNUNET_TRANSPORT_ATS_QUALITY_PHY_SIGNAL_STRENGTH = 1025,
235
236 /**
237 * Collision rate on physical layer
238 *
239 * Unit: [B/s]
240 */
241 GNUNET_TRANSPORT_ATS_QUALITY_PHY_COLLISION_RATE = 1026,
242
243 /**
244 * Error rate on physical layer
245 *
246 * Unit: [B/s]
247 */
248 GNUNET_TRANSPORT_ATS_QUALITY_PHY_ERROR_RATE = 1027,
249
250 /* Network layer quality properties */
251
252 /**
253 * Delay
254 * Time between when the time packet is sent and the packet arrives
255 *
256 * Unit: [μs]
257 *
258 * Examples:
259 *
260 * LAN : 180
261 * Dialup: 4000
262 * WLAN : 7000
263 */
264 GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY = 1028,
265
266 /**
267 * Jitter
268 * Time variations of the delay
269 * 1st derivative of a delay function
270 *
271 * Unit: [μs]
272 */
273 GNUNET_TRANSPORT_ATS_QUALITY_NET_JITTER = 1029,
274
275 /**
276 * Error rate on network layer
277 *
278 * Unit: [B/s]
279 *
280 * Examples:
281 *
282 * LAN : 0
283 * WLAN : 400
284 * Bluetooth : 100
285 * Note: This numbers are just assumptions as an example, not
286 * measured or somehow determined
287 */
288 GNUNET_TRANSPORT_ATS_QUALITY_NET_ERRORRATE = 1030,
289
290 /**
291 * Drop rate on network layer
292 * Bytes actively dismissed by a network component during transmission
293 * Reasons for dropped data can be full queues, congestion, quota violations...
294 *
295 * Unit: [B/s]
296 *
297 * Examples:
298 *
299 * LAN : 0
300 * WLAN : 400
301 * Bluetooth : 100
302 * Note: This numbers are just assumptions as an example, not
303 * measured or somehow determined
304 */
305 GNUNET_TRANSPORT_ATS_QUALITY_NET_DROPRATE = 1031,
306
307 /**
308 * Loss rate on network layer
309 * Bytes lost during transmission
310 * Reasons can be collisions, ...
311 *
312 * Unit: [B/s]
313 *
314 * Examples:
315 *
316 * LAN : 0
317 * WLAN : 40
318 * Bluetooth : 10
319 * Note: This numbers are just assumptions as an example, not measured
320 * or somehow determined
321 */
322 GNUNET_TRANSPORT_ATS_QUALITY_NET_LOSSRATE = 1032,
323
324 /**
325 * Throughput on network layer
326 *
327 * Unit: [kB/s]
328 *
329 * Examples:
330 *
331 * LAN : 3400
332 * WLAN : 1200
333 * Dialup: 4
334 *
335 */
336 GNUNET_TRANSPORT_ATS_QUALITY_NET_THROUGHPUT = 1033,
337
338 /* Availability related values */
339 /* =========================== */
340
341 /**
342 * Is a peer reachable?
343 */
344 GNUNET_TRANSPORT_ATS_AVAILABILITY_REACHABLE = 2048,
345
346 /**
347 * Is there a connection established to a peer using this transport
348 */
349 GNUNET_TRANSPORT_ATS_AVAILABILITY_CONNECTED = 2049
350};
351
352/**
353 * This structure will be used by plugins to communicate costs to ATS or by
354 * higher level components to tell ATS their constraints.
355 * Always a pair of (GNUNET_TRANSPORT_ATS_Property, uint32_t value).
356 * Value is always uint32_t, so all units used to define costs have to
357 * be normalized to fit uint32_t.
358 */
359struct GNUNET_TRANSPORT_ATS_Information
360{
361 /**
362 * ATS property type
363 */
364 uint32_t type;
365
366 /**
367 * ATS property value
368 */
369 uint32_t value;
370};
371
372
373
374/** 39/**
375 * Opaque pointer that plugins can use to distinguish specific 40 * Opaque pointer that plugins can use to distinguish specific
376 * connections to a given peer. Typically used by stateful plugins to 41 * connections to a given peer. Typically used by stateful plugins to
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index eddd8f8af..fcd91e6ec 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -47,6 +47,344 @@ extern "C"
47 */ 47 */
48#define GNUNET_TRANSPORT_VERSION 0x00000000 48#define GNUNET_TRANSPORT_VERSION 0x00000000
49 49
50
51/**
52 * Enum defining all known property types for ATS Enum values are used
53 * in the GNUNET_TRANSPORT_ATS_Information struct as
54 * (key,value)-pairs.
55 *
56 * Cost are always stored in uint32_t, so all units used to define costs
57 * have to be normalized to fit in uint32_t [0 .. 4.294.967.295]
58 *
59 * To keep the elements ordered
60 * 1..1024 : Values with a relation to cost
61 * 1025..2048 : Values with a relation to quality
62 * 2049..3072 : Values with a relation to availability
63 *
64 */
65enum GNUNET_TRANSPORT_ATS_Property
66{
67
68 /**
69 * End of the array.
70 */
71 GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR = 0,
72
73 /* Cost related values */
74 /* =================== */
75
76 /**
77 * Volume based cost in financial units to transmit data
78 *
79 * Note: This value is not bound to a specific currency or unit and only
80 * used locally.
81 * "cent" just refers the smallest amount of money in the respective
82 * currency.
83 *
84 * Unit: [cent/MB]
85 *
86 * Interpretation: less is better
87 *
88 * Examples:
89 * LAN: 0 [cent/MB]
90 * 2G : 10 [cent/MB]
91 */
92 GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_VOLUME = 1,
93
94 /**
95 * Time based cost in financial units to transmit data
96 *
97 * Note: This value is not bound to a specific currency or unit and only
98 * used locally.
99 * "cent" just refers the smallest amount of money in the respective
100 * currency.
101 *
102 * Unit: [cent/h]
103 *
104 * Interpretation: less is better
105 *
106 * Examples:
107 * LAN : 0 [cent/h]
108 * Dialup: 10 [cent/h]
109 */
110 GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_TIME = 2,
111
112 /**
113 * Computational costs
114 *
115 * Effort of preparing data to be sent with this transport
116 * Includes encoding, encryption and conversion of data
117 * Partial values can be summed up: c_sum = c_enc + c_enc + c_conv
118 * Resulting values depend on local system properties, e.g. CPU
119 *
120 * Unit: [ms/GB]
121 *
122 * Interpretation: less is better
123 *
124 * Examples:
125 *
126 * HTTPS with AES CBC-256: 7,382
127 * HTTPS with AES CBC-128: 5,279
128 * HTTPS with RC4-1024: 2,652
129 */
130 GNUNET_TRANSPORT_ATS_COST_COMPUTATIONAL = 3,
131
132 /**
133 * Energy consumption
134 *
135 * Energy consumption using this transport when sending with a certain
136 * power at a certain bitrate. This is only an approximation based on:
137 * Energy consumption E = P / D
138 *
139 * with:
140 * Power P in Watt (J/s)
141 * Datarate D in MBit/s
142 *
143 * Conversion between power P and dBm used by WLAN in radiotap's dBm TX power:
144 *
145 * Lp(dbm) = 10 log10 (P/ 1mW)
146 *
147 * => P = 1 mW * 10^(Lp(dbm)/10)
148 *
149 * Unit: [mJ/MB]
150 *
151 * Interpretation: less is better
152 *
153 * Examples:
154 *
155 * LAN: 0
156 * WLAN: 89 (600 mW @ 802.11g /w 54 MBit/s)
157 * Bluetooth: 267 (100 mW @ BT2.0 EDR /w 3 MBit/s)
158 */
159 GNUNET_TRANSPORT_ATS_COST_ENERGY_CONSUMPTION = 4,
160
161 /**
162 * Connect cost
163 * How many bytes are transmitted to initiate a new connection using
164 * this transport?
165 *
166 * Unit: [bytes]
167 *
168 * Interpretation: less is better
169 *
170 * Examples:
171 *
172 * UDP (No connection) :
173 * 0 bytes
174 * TCP (TCP 3-Way handshake):
175 * 220 bytes Ethernet, 172 bytes TCP/IP, 122 bytes TCP
176 * HTTP (TCP + Header) :
177 * 477 bytes Ethernet, 429 bytes TCP/IP, 374 bytes TCP, 278 bytes HTTP
178 * HTTPS HTTP+TLS Handshake:
179 * 2129 bytes Ethernet, 1975 bytes TCP/IP, 1755 bytes TCP, 1403 bytes HTTPS
180 *
181 * */
182 GNUNET_TRANSPORT_ATS_COST_CONNECT = 5,
183
184 /**
185 * Bandwidth cost
186 *
187 * How many bandwidth is available to consume?
188 * Used to calculate which impact sending data with this transport has
189 *
190 * Unit: [kB/s]
191 *
192 * Interpretation: more is better
193 *
194 * Examples:
195 * LAN: 12,800 (100 MBit/s)
196 * WLAN: 6,912 (54 MBit/s)
197 * Dial-up: 8 (64 Kbit/s)
198 *
199 */
200 GNUNET_TRANSPORT_ATS_COST_BANDWITH_AVAILABLE = 6,
201
202 /**
203 * Network overhead
204 *
205 * How many bytes are sent over the wire when 1 kilobyte (1024 bytes)
206 * of application data is transmitted?
207 * A factor used with connect cost, bandwidth cost and energy cost
208 * to describe the overhead produced by the transport protocol
209 *
210 * Unit: [bytes/kb]
211 *
212 * Interpretation: less is better
213 *
214 * Examples:
215 *
216 * TCP/IPv4 over Ethernet: 1024 + 38 + 20 + 20 = 1102 [bytes/kb]
217 * TCP/IPv6 over Ethernet: 1024 + 38 + 20 + 40 = 1122 [bytes/kb]
218 * UDP/IPv4 over Ethernet: 1024 + 38 + 20 + 8 = 1090 [bytes/kb]
219 * UDP/IPv6 over Ethernet: 1024 + 38 + 40 + 8 = 1110 [bytes/kb]
220 */
221 GNUNET_TRANSPORT_ATS_COST_NETWORK_OVERHEAD = 7,
222
223
224 /* Quality related values */
225 /* ====================== */
226
227 /* Physical layer quality properties */
228
229 /**
230 * Signal strength on physical layer
231 *
232 * Unit: [dBm]
233 */
234 GNUNET_TRANSPORT_ATS_QUALITY_PHY_SIGNAL_STRENGTH = 1025,
235
236 /**
237 * Collision rate on physical layer
238 *
239 * Unit: [B/s]
240 */
241 GNUNET_TRANSPORT_ATS_QUALITY_PHY_COLLISION_RATE = 1026,
242
243 /**
244 * Error rate on physical layer
245 *
246 * Unit: [B/s]
247 */
248 GNUNET_TRANSPORT_ATS_QUALITY_PHY_ERROR_RATE = 1027,
249
250 /* Network layer quality properties */
251
252 /**
253 * Delay
254 * Time between when the time packet is sent and the packet arrives
255 *
256 * Unit: [μs]
257 *
258 * Examples:
259 *
260 * LAN : 180
261 * Dialup: 4000
262 * WLAN : 7000
263 */
264 GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY = 1028,
265
266 /**
267 * Jitter
268 * Time variations of the delay
269 * 1st derivative of a delay function
270 *
271 * Unit: [μs]
272 */
273 GNUNET_TRANSPORT_ATS_QUALITY_NET_JITTER = 1029,
274
275 /**
276 * Error rate on network layer
277 *
278 * Unit: [B/s]
279 *
280 * Examples:
281 *
282 * LAN : 0
283 * WLAN : 400
284 * Bluetooth : 100
285 * Note: This numbers are just assumptions as an example, not
286 * measured or somehow determined
287 */
288 GNUNET_TRANSPORT_ATS_QUALITY_NET_ERRORRATE = 1030,
289
290 /**
291 * Drop rate on network layer
292 * Bytes actively dismissed by a network component during transmission
293 * Reasons for dropped data can be full queues, congestion, quota violations...
294 *
295 * Unit: [B/s]
296 *
297 * Examples:
298 *
299 * LAN : 0
300 * WLAN : 400
301 * Bluetooth : 100
302 * Note: This numbers are just assumptions as an example, not
303 * measured or somehow determined
304 */
305 GNUNET_TRANSPORT_ATS_QUALITY_NET_DROPRATE = 1031,
306
307 /**
308 * Loss rate on network layer
309 * Bytes lost during transmission
310 * Reasons can be collisions, ...
311 *
312 * Unit: [B/s]
313 *
314 * Examples:
315 *
316 * LAN : 0
317 * WLAN : 40
318 * Bluetooth : 10
319 * Note: This numbers are just assumptions as an example, not measured
320 * or somehow determined
321 */
322 GNUNET_TRANSPORT_ATS_QUALITY_NET_LOSSRATE = 1032,
323
324 /**
325 * Throughput on network layer
326 *
327 * Unit: [kB/s]
328 *
329 * Examples:
330 *
331 * LAN : 3400
332 * WLAN : 1200
333 * Dialup: 4
334 *
335 */
336 GNUNET_TRANSPORT_ATS_QUALITY_NET_THROUGHPUT = 1033,
337
338 /* Availability related values */
339 /* =========================== */
340
341 /**
342 * Is a peer reachable?
343 */
344 GNUNET_TRANSPORT_ATS_AVAILABILITY_REACHABLE = 2048,
345
346 /**
347 * Is there a connection established to a peer using this transport
348 */
349 GNUNET_TRANSPORT_ATS_AVAILABILITY_CONNECTED = 2049
350
351};
352
353
354/**
355 * struct used to communicate the transport's properties like cost and
356 * quality of service as well as high-level constraints on resource
357 * consumption.
358 *
359 * +---+
360 * +-----------+ Constraints | | Plugin properties +---------+
361 * | Highlevel |------------> |ATS| <------------------|Transport|
362 * | Component | ATS struct | | ATS struct | Plugin |
363 * +-----------+ | | +---------+
364 * +---+
365 *
366 * This structure will be used by transport plugins to communicate
367 * costs to ATS or by higher level components to tell ATS their
368 * constraints. Always a pair of (GNUNET_TRANSPORT_ATS_Property,
369 * uint32_t value). Value is always uint32_t, so all units used to
370 * define costs have to be normalized to fit uint32_t.
371 */
372struct GNUNET_TRANSPORT_ATS_Information
373{
374 /**
375 * ATS property type, in network byte order.
376 */
377 uint32_t type;
378
379 /**
380 * ATS property value, in network byte order.
381 */
382 uint32_t value;
383};
384
385
386
387
50/** 388/**
51 * Function called by the transport for each received message. 389 * Function called by the transport for each received message.
52 * 390 *
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c
index 87f90f80f..62fbc07e0 100644
--- a/src/testing/test_testing_topology.c
+++ b/src/testing/test_testing_topology.c
@@ -298,8 +298,6 @@ static int stats_print (void *cls,
298static void topology_cb (void *cls, 298static void topology_cb (void *cls,
299 const struct GNUNET_PeerIdentity *first, 299 const struct GNUNET_PeerIdentity *first,
300 const struct GNUNET_PeerIdentity *second, 300 const struct GNUNET_PeerIdentity *second,
301 struct GNUNET_TIME_Relative latency,
302 uint32_t distance,
303 const char *emsg) 301 const char *emsg)
304{ 302{
305 FILE *outfile = cls; 303 FILE *outfile = cls;
@@ -329,8 +327,7 @@ static int
329process_mtype (void *cls, 327process_mtype (void *cls,
330 const struct GNUNET_PeerIdentity *peer, 328 const struct GNUNET_PeerIdentity *peer,
331 const struct GNUNET_MessageHeader *message, 329 const struct GNUNET_MessageHeader *message,
332 struct GNUNET_TIME_Relative latency, 330 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
333 uint32_t distance)
334{ 331{
335 char *dotOutFileNameFinished; 332 char *dotOutFileNameFinished;
336 FILE *dotOutFileFinished; 333 FILE *dotOutFileFinished;
@@ -522,7 +519,6 @@ init_notify_peer1 (void *cls,
522 */ 519 */
523 pos->peer2handle = GNUNET_CORE_connect (pos->peer2->cfg, 520 pos->peer2handle = GNUNET_CORE_connect (pos->peer2->cfg,
524 1, 521 1,
525 TIMEOUT,
526 pos, 522 pos,
527 &init_notify_peer2, 523 &init_notify_peer2,
528 NULL, 524 NULL,
@@ -564,7 +560,6 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
564 */ 560 */
565 pos->peer1handle = GNUNET_CORE_connect (pos->peer1->cfg, 561 pos->peer1handle = GNUNET_CORE_connect (pos->peer1->cfg,
566 1, 562 1,
567 TIMEOUT,
568 pos, 563 pos,
569 &init_notify_peer1, 564 &init_notify_peer1,
570 NULL, NULL, 565 NULL, NULL,
diff --git a/src/testing/testing.c b/src/testing/testing.c
index d178995e0..fed3d87df 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -545,7 +545,9 @@ start_fsm (void *cls,
545 d->phase = SP_START_CORE; 545 d->phase = SP_START_CORE;
546 d->server = GNUNET_CORE_connect (d->cfg, 546 d->server = GNUNET_CORE_connect (d->cfg,
547 1, 547 1,
548#if NO_MORE_TIMEOUT_FIXME
548 ARM_START_WAIT, 549 ARM_START_WAIT,
550#endif
549 d, 551 d,
550 &testing_init, 552 &testing_init,
551 NULL, NULL, NULL, 553 NULL, NULL, NULL,
@@ -1347,8 +1349,15 @@ notify_connect_result (void *cls,
1347 { 1349 {
1348 if (ctx->cb != NULL) 1350 if (ctx->cb != NULL)
1349 { 1351 {
1350 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->distance, ctx->d1->cfg, 1352 ctx->cb (ctx->cb_cls,
1351 ctx->d2->cfg, ctx->d1, ctx->d2, NULL); 1353 &ctx->d1->id,
1354 &ctx->d2->id,
1355 ctx->distance,
1356 ctx->d1->cfg,
1357 ctx->d2->cfg,
1358 ctx->d1,
1359 ctx->d2,
1360 NULL);
1352 } 1361 }
1353 } 1362 }
1354 else if (remaining.rel_value > 0) 1363 else if (remaining.rel_value > 0)
@@ -1397,25 +1406,24 @@ notify_connect_result (void *cls,
1397 * 1406 *
1398 * @param cls our "struct ConnectContext" 1407 * @param cls our "struct ConnectContext"
1399 * @param peer identity of the peer that has connected 1408 * @param peer identity of the peer that has connected
1400 * @param latency the round trip latency of the connection to this peer 1409 * @param atsi performance information
1401 * @param distance distance the transport level distance to this peer
1402 * 1410 *
1403 */ 1411 */
1404static void 1412static void
1405connect_notify (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNET_TIME_Relative latency, 1413connect_notify (void *cls,
1406 uint32_t distance) 1414 const struct GNUNET_PeerIdentity * peer,
1415 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1407{ 1416{
1408 struct ConnectContext *ctx = cls; 1417 struct ConnectContext *ctx = cls;
1409 1418
1410 if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0) 1419 if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
1411 { 1420 {
1412 ctx->connected = GNUNET_YES; 1421 ctx->connected = GNUNET_YES;
1413 ctx->distance = distance; 1422 ctx->distance = 0; /* FIXME: distance */
1414 GNUNET_SCHEDULER_cancel(ctx->timeout_task); 1423 GNUNET_SCHEDULER_cancel(ctx->timeout_task);
1415 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result, 1424 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result,
1416 ctx); 1425 ctx);
1417 } 1426 }
1418
1419} 1427}
1420 1428
1421#if CONNECT_CORE2 1429#if CONNECT_CORE2
@@ -1424,20 +1432,20 @@ connect_notify (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNE
1424 * 1432 *
1425 * @param cls our "struct ConnectContext" 1433 * @param cls our "struct ConnectContext"
1426 * @param peer identity of the peer that has connected 1434 * @param peer identity of the peer that has connected
1427 * @param latency the round trip latency of the connection to this peer 1435 * @param atsi performance information
1428 * @param distance distance the transport level distance to this peer
1429 * 1436 *
1430 */ 1437 */
1431static void 1438static void
1432connect_notify_core2 (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNET_TIME_Relative latency, 1439connect_notify_core2 (void *cls,
1433 uint32_t distance) 1440 const struct GNUNET_PeerIdentity * peer,
1441 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1434{ 1442{
1435 struct ConnectContext *ctx = cls; 1443 struct ConnectContext *ctx = cls;
1436 1444
1437 if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0) 1445 if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
1438 { 1446 {
1439 ctx->connected = GNUNET_YES; 1447 ctx->connected = GNUNET_YES;
1440 ctx->distance = distance; 1448 ctx->distance = 0; /* FIXME: distance */
1441 GNUNET_SCHEDULER_cancel(ctx->timeout_task); 1449 GNUNET_SCHEDULER_cancel(ctx->timeout_task);
1442 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result, 1450 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result,
1443 ctx); 1451 ctx);
@@ -1477,7 +1485,7 @@ send_hello(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1477 GNUNET_assert(hello != NULL); 1485 GNUNET_assert(hello != NULL);
1478 GNUNET_TRANSPORT_offer_hello (ctx->d2th, hello); 1486 GNUNET_TRANSPORT_offer_hello (ctx->d2th, hello);
1479 1487
1480 ctx->connect_request_handle = GNUNET_CORE_peer_request_connect (ctx->d2->cfg, 1488 ctx->connect_request_handle = GNUNET_CORE_peer_request_connect (ctx->d2->server,
1481 GNUNET_TIME_relative_divide(ctx->relative_timeout, 1489 GNUNET_TIME_relative_divide(ctx->relative_timeout,
1482 ctx->max_connect_attempts + 1), 1490 ctx->max_connect_attempts + 1),
1483 &ctx->d1->id, 1491 &ctx->d1->id,
@@ -1539,7 +1547,9 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1539 1547
1540 ctx->d1core = GNUNET_CORE_connect (d1->cfg, 1548 ctx->d1core = GNUNET_CORE_connect (d1->cfg,
1541 1, 1549 1,
1550#if NO_MORE_TIMEOUT_FIXME
1542 timeout, 1551 timeout,
1552#endif
1543 ctx, 1553 ctx,
1544 NULL, 1554 NULL,
1545 &connect_notify, NULL, NULL, 1555 &connect_notify, NULL, NULL,
@@ -1557,7 +1567,9 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1557#if CONNECT_CORE2 1567#if CONNECT_CORE2
1558 ctx->d2core = GNUNET_CORE_connect (d2->cfg, 1568 ctx->d2core = GNUNET_CORE_connect (d2->cfg,
1559 1, 1569 1,
1570#if NO_MORE_TIMEOUT_FIXME
1560 timeout, 1571 timeout,
1572#endif
1561 ctx, 1573 ctx,
1562 NULL, 1574 NULL,
1563 NULL, NULL, NULL, 1575 NULL, NULL, NULL,
@@ -1620,7 +1632,9 @@ reattempt_daemons_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext
1620 1632
1621 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg, 1633 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg,
1622 1, 1634 1,
1635#if NO_MORE_TIMEOUT_FIXME
1623 GNUNET_TIME_absolute_get_remaining(ctx->timeout), 1636 GNUNET_TIME_absolute_get_remaining(ctx->timeout),
1637#endif
1624 ctx, 1638 ctx,
1625 NULL, 1639 NULL,
1626 &connect_notify, NULL, NULL, 1640 &connect_notify, NULL, NULL,
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index d5a43fd37..a243a7d7c 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -3104,7 +3104,7 @@ perform_dfs (struct GNUNET_TESTING_PeerGroup *pg, unsigned int num)
3104static void 3104static void
3105internal_topology_callback(void *cls, 3105internal_topology_callback(void *cls,
3106 const struct GNUNET_PeerIdentity *peer, 3106 const struct GNUNET_PeerIdentity *peer,
3107 struct GNUNET_TIME_Relative latency, uint32_t distance) 3107 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
3108{ 3108{
3109 struct CoreContext *core_ctx = cls; 3109 struct CoreContext *core_ctx = cls;
3110 struct TopologyIterateContext *iter_ctx = core_ctx->iter_context; 3110 struct TopologyIterateContext *iter_ctx = core_ctx->iter_context;
@@ -3118,12 +3118,14 @@ internal_topology_callback(void *cls,
3118 } 3118 }
3119 else 3119 else
3120 { 3120 {
3121 iter_ctx->topology_cb(iter_ctx->cls, &core_ctx->daemon->id, peer, latency, distance, NULL); 3121 iter_ctx->topology_cb(iter_ctx->cls, &core_ctx->daemon->id,
3122 peer, NULL);
3122 } 3123 }
3123 3124
3124 if (iter_ctx->completed == iter_ctx->total) 3125 if (iter_ctx->completed == iter_ctx->total)
3125 { 3126 {
3126 iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, NULL); 3127 iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL,
3128 NULL);
3127 /* Once all are done, free the iteration context */ 3129 /* Once all are done, free the iteration context */
3128 GNUNET_free(iter_ctx); 3130 GNUNET_free(iter_ctx);
3129 } 3131 }
@@ -3157,8 +3159,8 @@ schedule_get_topology(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3157 _("Creating connection, outstanding_connections is %d\n"), outstanding_connects); 3159 _("Creating connection, outstanding_connections is %d\n"), outstanding_connects);
3158#endif 3160#endif
3159 topology_context->connected++; 3161 topology_context->connected++;
3160 if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->cfg, &internal_topology_callback, core_context)) 3162 if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->server, &internal_topology_callback, core_context))
3161 internal_topology_callback(core_context, NULL, GNUNET_TIME_relative_get_zero(), 0); 3163 internal_topology_callback(core_context, NULL, NULL);
3162 3164
3163 } 3165 }
3164} 3166}
@@ -3195,7 +3197,7 @@ GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING
3195 } 3197 }
3196 if (total_count == 0) 3198 if (total_count == 0)
3197 { 3199 {
3198 cb(cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, "Cannot iterate over topology, no running peers!"); 3200 cb(cls, NULL, NULL, "Cannot iterate over topology, no running peers!");
3199 GNUNET_free(topology_context); 3201 GNUNET_free(topology_context);
3200 } 3202 }
3201 else 3203 else
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index 49f460658..ef6a81882 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -413,7 +413,7 @@ attempt_connect (struct Peer *pos)
413 gettext_noop ("# connect requests issued to core"), 413 gettext_noop ("# connect requests issued to core"),
414 1, 414 1,
415 GNUNET_NO); 415 GNUNET_NO);
416 pos->connect_req = GNUNET_CORE_peer_request_connect (cfg, 416 pos->connect_req = GNUNET_CORE_peer_request_connect (handle,
417 GNUNET_TIME_UNIT_MINUTES, 417 GNUNET_TIME_UNIT_MINUTES,
418 &pos->pid, 418 &pos->pid,
419 &connect_completed_callback, 419 &connect_completed_callback,
@@ -689,15 +689,13 @@ reschedule_hellos (void *cls,
689 * 689 *
690 * @param cls closure 690 * @param cls closure
691 * @param peer peer identity this notification is about 691 * @param peer peer identity this notification is about
692 * @param latency reported latency of the connection with 'other' 692 * @param atsi performance data
693 * @param distance reported distance (DV) to 'other'
694 */ 693 */
695static void 694static void
696connect_notify (void *cls, 695connect_notify (void *cls,
697 const struct 696 const struct
698 GNUNET_PeerIdentity * peer, 697 GNUNET_PeerIdentity * peer,
699 struct GNUNET_TIME_Relative latency, 698 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
700 uint32_t distance)
701{ 699{
702 struct Peer *pos; 700 struct Peer *pos;
703 701
@@ -1167,8 +1165,7 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
1167 * @param other the other peer involved (sender or receiver, NULL 1165 * @param other the other peer involved (sender or receiver, NULL
1168 * for loopback messages where we are both sender and receiver) 1166 * for loopback messages where we are both sender and receiver)
1169 * @param message the actual HELLO message 1167 * @param message the actual HELLO message
1170 * @param latency reported latency of the connection with 'other' 1168 * @param atsi performance data
1171 * @param distance reported distance (DV) to 'other'
1172 * @return GNUNET_OK to keep the connection open, 1169 * @return GNUNET_OK to keep the connection open,
1173 * GNUNET_SYSERR to close it (signal serious error) 1170 * GNUNET_SYSERR to close it (signal serious error)
1174 */ 1171 */
@@ -1177,8 +1174,7 @@ handle_encrypted_hello (void *cls,
1177 const struct GNUNET_PeerIdentity * other, 1174 const struct GNUNET_PeerIdentity * other,
1178 const struct GNUNET_MessageHeader * 1175 const struct GNUNET_MessageHeader *
1179 message, 1176 message,
1180 struct GNUNET_TIME_Relative latency, 1177 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1181 uint32_t distance)
1182{ 1178{
1183 struct Peer *peer; 1179 struct Peer *peer;
1184 struct GNUNET_PeerIdentity pid; 1180 struct GNUNET_PeerIdentity pid;
@@ -1379,7 +1375,6 @@ run (void *cls,
1379 NULL); 1375 NULL);
1380 handle = GNUNET_CORE_connect (cfg, 1376 handle = GNUNET_CORE_connect (cfg,
1381 1, 1377 1,
1382 GNUNET_TIME_UNIT_FOREVER_REL,
1383 NULL, 1378 NULL,
1384 &core_init, 1379 &core_init,
1385 &connect_notify, 1380 &connect_notify,