diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/Makefile.am | 5 | ||||
-rw-r--r-- | src/core/core.h | 143 | ||||
-rw-r--r-- | src/core/core_api.c | 1537 | ||||
-rw-r--r-- | src/core/core_api_iterate_peers.c | 169 | ||||
-rw-r--r-- | src/core/core_api_peer_get_info.c | 175 | ||||
-rw-r--r-- | src/core/core_api_peer_request.c | 179 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 364 | ||||
-rw-r--r-- | src/core/test_core_api.c | 19 | ||||
-rw-r--r-- | src/core/test_core_api_reliability.c | 14 | ||||
-rw-r--r-- | src/core/test_core_api_start_only.c | 17 | ||||
-rw-r--r-- | src/core/test_core_quota_compliance.c | 106 |
11 files changed, 1610 insertions, 1118 deletions
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 | ||
16 | libgnunetcore_la_SOURCES = \ | 16 | libgnunetcore_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 | ||
21 | libgnunetcore_la_LIBADD = \ | 18 | libgnunetcore_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 | */ | ||
353 | struct 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 | */ | ||
399 | struct 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 | */ |
328 | struct SendMessage | 431 | struct 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 | */ | ||
39 | struct 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 | */ | ||
122 | struct 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 | */ |
36 | struct GNUNET_CORE_Handle | 152 | struct 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 | */ | ||
348 | static void | ||
349 | reconnect (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 | */ | ||
358 | static void | ||
359 | reconnect_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 | */ | ||
235 | static void | 375 | static void |
236 | reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 376 | trigger_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 | */ |
248 | static size_t transmit_start (void *cls, size_t size, void *buf); | 386 | static void |
387 | transmission_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 | */ |
257 | static void | 397 | static void |
258 | reconnect (struct GNUNET_CORE_Handle *h) | 398 | mark_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 | 413 | static void |
273 | h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, | 414 | request_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 | */ |
289 | static void | 465 | static void |
290 | timeout_request (void *cls, | 466 | transmission_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 | */ |
316 | static size_t | 490 | static size_t |
317 | request_start (void *cls, size_t size, void *buf) | 491 | transmit_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 | */ |
358 | static void | 601 | static void |
359 | trigger_next_request (struct GNUNET_CORE_Handle *h) | 602 | trigger_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 | */ | ||
635 | static int | ||
636 | disconnect_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 | */ |
390 | static void | 694 | static void |
391 | main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 695 | main_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 | */ | ||
564 | static 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 | */ |
576 | static void | 1006 | static void |
577 | init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 1007 | init_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 | |||
632 | static void | ||
633 | reconnect_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 | */ |
650 | static size_t | 1037 | static void |
651 | transmit_start (void *cls, size_t size, void *buf) | 1038 | reconnect (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) | |||
750 | struct GNUNET_CORE_Handle * | 1129 | struct GNUNET_CORE_Handle * |
751 | GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1130 | GNUNET_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 | */ |
813 | void | 1176 | void |
814 | GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) | 1177 | GNUNET_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 | */ | ||
833 | static size_t | ||
834 | produce_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 | */ |
927 | struct GNUNET_CORE_TransmitHandle * | 1230 | struct GNUNET_CORE_TransmitHandle * |
928 | GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, | 1231 | GNUNET_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 | */ |
969 | void | 1328 | void |
970 | GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle | 1329 | GNUNET_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 | */ | ||
1374 | struct 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 | */ | ||
1409 | static void | ||
1410 | peer_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 | */ | ||
1439 | struct GNUNET_CORE_PeerRequestHandle * | ||
1440 | GNUNET_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 | */ | ||
1480 | void | ||
1481 | GNUNET_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 | |||
1497 | struct 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 | */ | ||
1533 | static void | ||
1534 | change_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 | */ | ||
1567 | struct GNUNET_CORE_InformationRequestContext * | ||
1568 | GNUNET_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 | */ | ||
1633 | void | ||
1634 | GNUNET_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 | */ | ||
1657 | struct 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 | */ | ||
1679 | static int | ||
1680 | iterate_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 | */ | ||
1702 | int | ||
1703 | GNUNET_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 | |||
32 | struct 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 | */ | ||
64 | static void | ||
65 | receive_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 | */ | ||
120 | static size_t | ||
121 | transmit_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 | */ | ||
142 | int | ||
143 | GNUNET_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 | |||
31 | struct 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 | */ | ||
58 | static void | ||
59 | receive_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 | */ | ||
123 | struct GNUNET_CORE_InformationRequestContext * | ||
124 | GNUNET_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 | */ | ||
168 | void | ||
169 | GNUNET_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 | */ | ||
36 | struct 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 | */ | ||
80 | static size_t | ||
81 | send_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 | */ | ||
135 | struct GNUNET_CORE_PeerRequestHandle * | ||
136 | GNUNET_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 | */ | ||
171 | void | ||
172 | GNUNET_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 | */ | ||
398 | struct ClientActiveRequest; | ||
399 | |||
400 | /** | ||
401 | * Data kept per neighbouring peer. | ||
402 | */ | ||
394 | struct Neighbour | 403 | struct 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 | */ | ||
666 | struct 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 | */ |
648 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; | 718 | static 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 | */ |
939 | static void | 1012 | static void |
940 | handle_client_iterate_peers (void *cls, | 1013 | schedule_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 | */ | ||
1064 | static void | ||
1065 | handle_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 | */ | ||
1234 | static int | ||
1235 | destroy_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 | |||
1221 | free_neighbour (struct Neighbour *n) | 1404 | free_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 | ||
48 | struct PeerContext | 43 | struct PeerContext |
@@ -103,8 +98,7 @@ terminate_task_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
103 | static void | 98 | static void |
104 | connect_notify (void *cls, | 99 | connect_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 | |||
130 | inbound_notify (void *cls, | 124 | inbound_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 | |||
143 | outbound_notify (void *cls, | 136 | outbound_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 | |||
160 | process_mtype (void *cls, | 152 | process_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) | |||
148 | static void | 148 | static void |
149 | connect_notify (void *cls, | 149 | connect_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 | |||
175 | inbound_notify (void *cls, | 174 | inbound_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 | |||
190 | outbound_notify (void *cls, | 188 | outbound_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 | |||
215 | process_mtype (void *cls, | 212 | process_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 | ||
46 | struct PeerContext | 40 | struct PeerContext |
@@ -71,8 +65,7 @@ static int ok; | |||
71 | static void | 65 | static void |
72 | connect_notify (void *cls, | 66 | connect_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 | |||
88 | inbound_notify (void *cls, | 81 | inbound_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 | |||
99 | outbound_notify (void *cls, | 91 | outbound_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 | |||
191 | inbound_notify (void *cls, | 191 | inbound_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 | |||
207 | outbound_notify (void *cls, | 206 | outbound_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 | |||
238 | measurement_end (void *cls, | 236 | measurement_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 | ||
275 | static size_t | 272 | static size_t |
@@ -279,17 +276,19 @@ static void | |||
279 | send_tsk (void *cls, | 276 | send_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 | ||
292 | static void measure (unsigned long long quota_p1, unsigned long long quota_p2 ) | 289 | |
290 | static void | ||
291 | measure (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 | ||
326 | static int tr_n; | 325 | static int tr_n; |
@@ -330,8 +329,7 @@ static int | |||
330 | process_mtype (void *cls, | 329 | process_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 |