diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:53:18 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:53:18 +0100 |
commit | bcf3298c5eb79dd98bfc8ccf58793703aac70f49 (patch) | |
tree | 2bc59b82d74596c65b3caab68f6102da516dfc46 /src/cadet/gnunet-service-cadet_channel.c | |
parent | cd3d159df3150d46a6de7d39bcefb16f03ed5d3b (diff) | |
download | gnunet-bcf3298c5eb79dd98bfc8ccf58793703aac70f49.tar.gz gnunet-bcf3298c5eb79dd98bfc8ccf58793703aac70f49.zip |
remove old CADET service code
Diffstat (limited to 'src/cadet/gnunet-service-cadet_channel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.c | 2562 |
1 files changed, 0 insertions, 2562 deletions
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c deleted file mode 100644 index 7b7c6e57c..000000000 --- a/src/cadet/gnunet-service-cadet_channel.c +++ /dev/null | |||
@@ -1,2562 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
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., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | #include "platform.h" | ||
23 | #include "gnunet_util_lib.h" | ||
24 | |||
25 | #include "gnunet_statistics_service.h" | ||
26 | |||
27 | #include "cadet.h" | ||
28 | #include "cadet_protocol.h" | ||
29 | |||
30 | #include "gnunet-service-cadet_channel.h" | ||
31 | #include "gnunet-service-cadet_local.h" | ||
32 | #include "gnunet-service-cadet_tunnel.h" | ||
33 | #include "gnunet-service-cadet_peer.h" | ||
34 | |||
35 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-chn",__VA_ARGS__) | ||
36 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__) | ||
37 | |||
38 | #define CADET_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(\ | ||
39 | GNUNET_TIME_UNIT_MILLISECONDS, 250) | ||
40 | #define CADET_RETRANSMIT_MARGIN 4 | ||
41 | |||
42 | |||
43 | /** | ||
44 | * All the states a connection can be in. | ||
45 | */ | ||
46 | enum CadetChannelState | ||
47 | { | ||
48 | /** | ||
49 | * Uninitialized status, should never appear in operation. | ||
50 | */ | ||
51 | CADET_CHANNEL_NEW, | ||
52 | |||
53 | /** | ||
54 | * Connection create message sent, waiting for ACK. | ||
55 | */ | ||
56 | CADET_CHANNEL_SENT, | ||
57 | |||
58 | /** | ||
59 | * Connection confirmed, ready to carry traffic. | ||
60 | */ | ||
61 | CADET_CHANNEL_READY | ||
62 | }; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Info holder for channel messages in queues. | ||
67 | */ | ||
68 | struct CadetChannelQueue | ||
69 | { | ||
70 | /** | ||
71 | * Tunnel Queue. | ||
72 | */ | ||
73 | struct CadetTunnelQueue *tq; | ||
74 | |||
75 | /** | ||
76 | * Message type (DATA/DATA_ACK) | ||
77 | */ | ||
78 | uint16_t type; | ||
79 | |||
80 | /** | ||
81 | * Message copy (for DATAs, to start retransmission timer) | ||
82 | */ | ||
83 | struct CadetReliableMessage *copy; | ||
84 | |||
85 | /** | ||
86 | * Reliability (for DATA_ACKs, to access rel->ack_q) | ||
87 | */ | ||
88 | struct CadetChannelReliability *rel; | ||
89 | }; | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Info needed to retry a message in case it gets lost. | ||
94 | */ | ||
95 | struct CadetReliableMessage | ||
96 | { | ||
97 | /** | ||
98 | * Double linked list, FIFO style | ||
99 | */ | ||
100 | struct CadetReliableMessage *next; | ||
101 | struct CadetReliableMessage *prev; | ||
102 | |||
103 | /** | ||
104 | * Type of message (payload, channel management). | ||
105 | */ | ||
106 | int16_t type; | ||
107 | |||
108 | /** | ||
109 | * Tunnel Reliability queue this message is in. | ||
110 | */ | ||
111 | struct CadetChannelReliability *rel; | ||
112 | |||
113 | /** | ||
114 | * ID of the message (ACK needed to free) | ||
115 | */ | ||
116 | uint32_t mid; | ||
117 | |||
118 | /** | ||
119 | * Tunnel Queue. | ||
120 | */ | ||
121 | struct CadetChannelQueue *chq; | ||
122 | |||
123 | /** | ||
124 | * When was this message issued (to calculate ACK delay) | ||
125 | */ | ||
126 | struct GNUNET_TIME_Absolute timestamp; | ||
127 | |||
128 | /* struct GNUNET_CADET_ChannelAppDataMessage with payload */ | ||
129 | }; | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Info about the traffic state for a client in a channel. | ||
134 | */ | ||
135 | struct CadetChannelReliability | ||
136 | { | ||
137 | /** | ||
138 | * Channel this is about. | ||
139 | */ | ||
140 | struct CadetChannel *ch; | ||
141 | |||
142 | /** | ||
143 | * DLL of messages sent and not yet ACK'd. | ||
144 | */ | ||
145 | struct CadetReliableMessage *head_sent; | ||
146 | struct CadetReliableMessage *tail_sent; | ||
147 | |||
148 | /** | ||
149 | * DLL of messages received out of order. | ||
150 | */ | ||
151 | struct CadetReliableMessage *head_recv; | ||
152 | struct CadetReliableMessage *tail_recv; | ||
153 | |||
154 | /** | ||
155 | * Messages received. | ||
156 | */ | ||
157 | unsigned int n_recv; | ||
158 | |||
159 | /** | ||
160 | * Next MID to use for outgoing traffic. | ||
161 | */ | ||
162 | uint32_t mid_send; | ||
163 | |||
164 | /** | ||
165 | * Next MID expected for incoming traffic. | ||
166 | */ | ||
167 | uint32_t mid_recv; | ||
168 | |||
169 | /** | ||
170 | * Handle for queued unique data CREATE, DATA_ACK. | ||
171 | */ | ||
172 | struct CadetChannelQueue *uniq; | ||
173 | |||
174 | /** | ||
175 | * Can we send data to the client? | ||
176 | */ | ||
177 | int client_ready; | ||
178 | |||
179 | /** | ||
180 | * Can the client send data to us? | ||
181 | */ | ||
182 | int client_allowed; | ||
183 | |||
184 | /** | ||
185 | * Task to resend/poll in case no ACK is received. | ||
186 | */ | ||
187 | struct GNUNET_SCHEDULER_Task * retry_task; | ||
188 | |||
189 | /** | ||
190 | * Counter for exponential backoff. | ||
191 | */ | ||
192 | struct GNUNET_TIME_Relative retry_timer; | ||
193 | |||
194 | /** | ||
195 | * How long does it usually take to get an ACK. | ||
196 | */ | ||
197 | struct GNUNET_TIME_Relative expected_delay; | ||
198 | }; | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Struct containing all information regarding a channel to a remote client. | ||
203 | */ | ||
204 | struct CadetChannel | ||
205 | { | ||
206 | /** | ||
207 | * Tunnel this channel is in. | ||
208 | */ | ||
209 | struct CadetTunnel *t; | ||
210 | |||
211 | /** | ||
212 | * Destination port of the channel. | ||
213 | */ | ||
214 | struct GNUNET_HashCode port; | ||
215 | |||
216 | /** | ||
217 | * Global channel number ( < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
218 | */ | ||
219 | struct GNUNET_CADET_ChannelTunnelNumber gid; | ||
220 | |||
221 | /** | ||
222 | * Local tunnel number for root (owner) client. | ||
223 | * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 ) | ||
224 | */ | ||
225 | struct GNUNET_CADET_ClientChannelNumber lid_root; | ||
226 | |||
227 | /** | ||
228 | * Local tunnel number for local destination clients (incoming number) | ||
229 | * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV or 0). | ||
230 | */ | ||
231 | struct GNUNET_CADET_ClientChannelNumber lid_dest; | ||
232 | |||
233 | /** | ||
234 | * Channel state. | ||
235 | */ | ||
236 | enum CadetChannelState state; | ||
237 | |||
238 | /** | ||
239 | * Is the tunnel bufferless (minimum latency)? | ||
240 | */ | ||
241 | int nobuffer; | ||
242 | |||
243 | /** | ||
244 | * Is the tunnel reliable? | ||
245 | */ | ||
246 | int reliable; | ||
247 | |||
248 | /** | ||
249 | * Last time the channel was used | ||
250 | */ | ||
251 | struct GNUNET_TIME_Absolute timestamp; | ||
252 | |||
253 | /** | ||
254 | * Client owner of the tunnel, if any | ||
255 | */ | ||
256 | struct CadetClient *root; | ||
257 | |||
258 | /** | ||
259 | * Client destination of the tunnel, if any. | ||
260 | */ | ||
261 | struct CadetClient *dest; | ||
262 | |||
263 | /** | ||
264 | * Flag to signal the destruction of the channel. | ||
265 | * If this is set to #GNUNET_YES the channel will be destroyed | ||
266 | * when the queue is empty. | ||
267 | */ | ||
268 | int destroy; | ||
269 | |||
270 | /** | ||
271 | * Total (reliable) messages pending ACK for this channel. | ||
272 | */ | ||
273 | unsigned int pending_messages; | ||
274 | |||
275 | /** | ||
276 | * Reliability data. | ||
277 | * Only present (non-NULL) at the owner of a tunnel. | ||
278 | */ | ||
279 | struct CadetChannelReliability *root_rel; | ||
280 | |||
281 | /** | ||
282 | * Reliability data. | ||
283 | * Only present (non-NULL) at the destination of a tunnel. | ||
284 | */ | ||
285 | struct CadetChannelReliability *dest_rel; | ||
286 | |||
287 | }; | ||
288 | |||
289 | |||
290 | /******************************************************************************/ | ||
291 | /******************************* GLOBALS ***********************************/ | ||
292 | /******************************************************************************/ | ||
293 | |||
294 | /** | ||
295 | * Global handle to the statistics service. | ||
296 | */ | ||
297 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
298 | |||
299 | /** | ||
300 | * Local peer own ID (memory efficient handle). | ||
301 | */ | ||
302 | extern GNUNET_PEER_Id myid; | ||
303 | |||
304 | |||
305 | /******************************************************************************/ | ||
306 | /******************************** STATIC ***********************************/ | ||
307 | /******************************************************************************/ | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Destroy a reliable message after it has been acknowledged, either by | ||
312 | * direct mid ACK or bitfield. Updates the appropriate data structures and | ||
313 | * timers and frees all memory. | ||
314 | * | ||
315 | * @param copy Message that is no longer needed: remote peer got it. | ||
316 | * @param update_time Is the timing information relevant? | ||
317 | * If this message is ACK in a batch the timing information | ||
318 | * is skewed by the retransmission, count only for the | ||
319 | * retransmitted message. | ||
320 | * | ||
321 | * @return #GNUNET_YES if channel was destroyed as a result of the call, | ||
322 | * #GNUNET_NO otherwise. | ||
323 | */ | ||
324 | static int | ||
325 | rel_message_free (struct CadetReliableMessage *copy, int update_time); | ||
326 | |||
327 | /** | ||
328 | * send a channel create message. | ||
329 | * | ||
330 | * @param ch Channel for which to send. | ||
331 | */ | ||
332 | static void | ||
333 | send_create (struct CadetChannel *ch); | ||
334 | |||
335 | /** | ||
336 | * Confirm we got a channel create, FWD ack. | ||
337 | * | ||
338 | * @param ch The channel to confirm. | ||
339 | * @param fwd Should we send a FWD ACK? (going dest->root) | ||
340 | */ | ||
341 | static void | ||
342 | send_ack (struct CadetChannel *ch, int fwd); | ||
343 | |||
344 | |||
345 | |||
346 | /** | ||
347 | * Test if the channel is loopback: both root and dest are on the local peer. | ||
348 | * | ||
349 | * @param ch Channel to test. | ||
350 | * | ||
351 | * @return #GNUNET_YES if channel is loopback, #GNUNET_NO otherwise. | ||
352 | */ | ||
353 | static int | ||
354 | is_loopback (const struct CadetChannel *ch) | ||
355 | { | ||
356 | if (NULL != ch->t) | ||
357 | return GCT_is_loopback (ch->t); | ||
358 | |||
359 | return (NULL != ch->root && NULL != ch->dest); | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Save a copy of the data message for later retransmission. | ||
365 | * | ||
366 | * @param msg Message to copy. | ||
367 | * @param mid Message ID. | ||
368 | * @param rel Reliability data for retransmission. | ||
369 | */ | ||
370 | static struct CadetReliableMessage * | ||
371 | copy_message (const struct GNUNET_CADET_ChannelAppDataMessage *msg, uint32_t mid, | ||
372 | struct CadetChannelReliability *rel) | ||
373 | { | ||
374 | struct CadetReliableMessage *copy; | ||
375 | uint16_t size; | ||
376 | |||
377 | size = ntohs (msg->header.size); | ||
378 | copy = GNUNET_malloc (sizeof (*copy) + size); | ||
379 | copy->mid = mid; | ||
380 | copy->rel = rel; | ||
381 | copy->type = GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA; | ||
382 | GNUNET_memcpy (©[1], msg, size); | ||
383 | |||
384 | return copy; | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * We have received a message out of order, or the client is not ready. | ||
389 | * Buffer it until we receive an ACK from the client or the missing | ||
390 | * message from the channel. | ||
391 | * | ||
392 | * @param msg Message to buffer (MUST be of type CADET_DATA). | ||
393 | * @param rel Reliability data to the corresponding direction. | ||
394 | */ | ||
395 | static void | ||
396 | add_buffered_data (const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
397 | struct CadetChannelReliability *rel) | ||
398 | { | ||
399 | struct CadetReliableMessage *copy; | ||
400 | struct CadetReliableMessage *prev; | ||
401 | uint32_t mid; | ||
402 | |||
403 | mid = ntohl (msg->mid); | ||
404 | |||
405 | LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data MID %u (%u)\n", | ||
406 | mid, rel->n_recv); | ||
407 | |||
408 | rel->n_recv++; | ||
409 | |||
410 | // FIXME do something better than O(n), although n < 64... | ||
411 | // FIXME start from the end (most messages are the latest ones) | ||
412 | for (prev = rel->head_recv; NULL != prev; prev = prev->next) | ||
413 | { | ||
414 | LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid); | ||
415 | if (prev->mid == mid) | ||
416 | { | ||
417 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already there!\n"); | ||
418 | rel->n_recv--; | ||
419 | return; | ||
420 | } | ||
421 | else if (GC_is_pid_bigger (prev->mid, mid)) | ||
422 | { | ||
423 | LOG (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n"); | ||
424 | copy = copy_message (msg, mid, rel); | ||
425 | GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv, | ||
426 | prev, copy); | ||
427 | return; | ||
428 | } | ||
429 | } | ||
430 | copy = copy_message (msg, mid, rel); | ||
431 | LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail! (now: %u)\n", rel->n_recv); | ||
432 | GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy); | ||
433 | LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n"); | ||
434 | } | ||
435 | |||
436 | |||
437 | /** | ||
438 | * Add a destination client to a channel, initializing all data structures | ||
439 | * in the channel and the client. | ||
440 | * | ||
441 | * @param ch Channel to which add the destination. | ||
442 | * @param c Client which to add to the channel. | ||
443 | */ | ||
444 | static void | ||
445 | add_destination (struct CadetChannel *ch, struct CadetClient *c) | ||
446 | { | ||
447 | if (NULL != ch->dest) | ||
448 | { | ||
449 | GNUNET_break (0); | ||
450 | return; | ||
451 | } | ||
452 | |||
453 | /* Assign local id as destination */ | ||
454 | ch->lid_dest = GML_get_next_ccn (c); | ||
455 | |||
456 | /* Store in client's hashmap */ | ||
457 | GML_channel_add (c, ch->lid_dest, ch); | ||
458 | |||
459 | GNUNET_break (NULL == ch->dest_rel); | ||
460 | ch->dest_rel = GNUNET_new (struct CadetChannelReliability); | ||
461 | ch->dest_rel->ch = ch; | ||
462 | ch->dest_rel->expected_delay.rel_value_us = 0; | ||
463 | ch->dest_rel->retry_timer = CADET_RETRANSMIT_TIME; | ||
464 | |||
465 | ch->dest = c; | ||
466 | } | ||
467 | |||
468 | |||
469 | /** | ||
470 | * Set options in a channel, extracted from a bit flag field. | ||
471 | * | ||
472 | * @param ch Channel to set options to. | ||
473 | * @param options Bit array in host byte order. | ||
474 | */ | ||
475 | static void | ||
476 | channel_set_options (struct CadetChannel *ch, uint32_t options) | ||
477 | { | ||
478 | ch->nobuffer = (options & GNUNET_CADET_OPTION_NOBUFFER) != 0 ? | ||
479 | GNUNET_YES : GNUNET_NO; | ||
480 | ch->reliable = (options & GNUNET_CADET_OPTION_RELIABLE) != 0 ? | ||
481 | GNUNET_YES : GNUNET_NO; | ||
482 | } | ||
483 | |||
484 | |||
485 | /** | ||
486 | * Get a bit flag field with the options of a channel. | ||
487 | * | ||
488 | * @param ch Channel to get options from. | ||
489 | * | ||
490 | * @return Bit array in host byte order. | ||
491 | */ | ||
492 | static uint32_t | ||
493 | channel_get_options (struct CadetChannel *ch) | ||
494 | { | ||
495 | uint32_t options; | ||
496 | |||
497 | options = 0; | ||
498 | if (ch->nobuffer) | ||
499 | options |= GNUNET_CADET_OPTION_NOBUFFER; | ||
500 | if (ch->reliable) | ||
501 | options |= GNUNET_CADET_OPTION_RELIABLE; | ||
502 | |||
503 | return options; | ||
504 | } | ||
505 | |||
506 | |||
507 | /** | ||
508 | * Notify a client that the channel is no longer valid. | ||
509 | * | ||
510 | * @param ch Channel that is destroyed. | ||
511 | * @param local_only Should we avoid sending it to other peers? | ||
512 | */ | ||
513 | static void | ||
514 | send_destroy (struct CadetChannel *ch, int local_only) | ||
515 | { | ||
516 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
517 | |||
518 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
519 | msg.header.size = htons (sizeof (msg)); | ||
520 | msg.ctn = ch->gid; | ||
521 | |||
522 | /* If root is not NULL, notify. | ||
523 | * If it's NULL, check lid_root. When a local destroy comes in, root | ||
524 | * is set to NULL but lid_root is left untouched. In this case, do nothing, | ||
525 | * the client is the one who requested the channel to be destroyed. | ||
526 | */ | ||
527 | if (NULL != ch->root) | ||
528 | GML_send_channel_destroy (ch->root, ch->lid_root); | ||
529 | else if (0 == ch->lid_root.channel_of_client && GNUNET_NO == local_only) | ||
530 | GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL); | ||
531 | |||
532 | if (NULL != ch->dest) | ||
533 | GML_send_channel_destroy (ch->dest, ch->lid_dest); | ||
534 | else if (0 == ch->lid_dest.channel_of_client && GNUNET_NO == local_only) | ||
535 | GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES, NULL); | ||
536 | } | ||
537 | |||
538 | |||
539 | /** | ||
540 | * Notify the destination client that a new incoming channel was created. | ||
541 | * | ||
542 | * @param ch Channel that was created. | ||
543 | */ | ||
544 | static void | ||
545 | send_client_create (struct CadetChannel *ch) | ||
546 | { | ||
547 | uint32_t opt; | ||
548 | |||
549 | if (NULL == ch->dest) | ||
550 | return; | ||
551 | |||
552 | opt = 0; | ||
553 | opt |= GNUNET_YES == ch->reliable ? GNUNET_CADET_OPTION_RELIABLE : 0; | ||
554 | opt |= GNUNET_YES == ch->nobuffer ? GNUNET_CADET_OPTION_NOBUFFER : 0; | ||
555 | GML_send_channel_create (ch->dest, | ||
556 | ch->lid_dest, | ||
557 | &ch->port, | ||
558 | opt, | ||
559 | GCT_get_destination (ch->t)); | ||
560 | |||
561 | } | ||
562 | |||
563 | |||
564 | /** | ||
565 | * Send data to a client. | ||
566 | * | ||
567 | * If the client is ready, send directly, otherwise buffer while listening | ||
568 | * for a local ACK. | ||
569 | * | ||
570 | * @param ch Channel | ||
571 | * @param msg Message. | ||
572 | * @param fwd Is this a fwd (root->dest) message? | ||
573 | */ | ||
574 | static void | ||
575 | send_client_data (struct CadetChannel *ch, | ||
576 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
577 | int fwd) | ||
578 | { | ||
579 | if (fwd) | ||
580 | { | ||
581 | if (ch->dest_rel->client_ready) | ||
582 | { | ||
583 | GML_send_data (ch->dest, msg, ch->lid_dest); | ||
584 | ch->dest_rel->client_ready = GNUNET_NO; | ||
585 | ch->dest_rel->mid_recv++; | ||
586 | } | ||
587 | else | ||
588 | add_buffered_data (msg, ch->dest_rel); | ||
589 | } | ||
590 | else | ||
591 | { | ||
592 | if (ch->root_rel->client_ready) | ||
593 | { | ||
594 | GML_send_data (ch->root, msg, ch->lid_root); | ||
595 | ch->root_rel->client_ready = GNUNET_NO; | ||
596 | ch->root_rel->mid_recv++; | ||
597 | } | ||
598 | else | ||
599 | add_buffered_data (msg, ch->root_rel); | ||
600 | } | ||
601 | } | ||
602 | |||
603 | |||
604 | /** | ||
605 | * Send a buffered message to the client, for in order delivery or | ||
606 | * as result of client ACK. | ||
607 | * | ||
608 | * @param ch Channel on which to empty the message buffer. | ||
609 | * @param c Client to send to. | ||
610 | * @param fwd Is this to send FWD data?. | ||
611 | */ | ||
612 | static void | ||
613 | send_client_buffered_data (struct CadetChannel *ch, | ||
614 | struct CadetClient *c, | ||
615 | int fwd) | ||
616 | { | ||
617 | struct CadetReliableMessage *copy; | ||
618 | struct CadetChannelReliability *rel; | ||
619 | |||
620 | LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n"); | ||
621 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
622 | if (GNUNET_NO == rel->client_ready) | ||
623 | { | ||
624 | LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n"); | ||
625 | return; | ||
626 | } | ||
627 | |||
628 | copy = rel->head_recv; | ||
629 | /* We never buffer channel management messages */ | ||
630 | if (NULL != copy) | ||
631 | { | ||
632 | if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable) | ||
633 | { | ||
634 | struct GNUNET_CADET_ChannelAppDataMessage *msg = (struct GNUNET_CADET_ChannelAppDataMessage *) ©[1]; | ||
635 | |||
636 | LOG (GNUNET_ERROR_TYPE_DEBUG, " have %u! now expecting %u\n", | ||
637 | copy->mid, rel->mid_recv + 1); | ||
638 | send_client_data (ch, msg, fwd); | ||
639 | rel->n_recv--; | ||
640 | GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy); | ||
641 | LOG (GNUNET_ERROR_TYPE_DEBUG, " free copy recv MID %u (%p), %u left\n", | ||
642 | copy->mid, copy, rel->n_recv); | ||
643 | GNUNET_free (copy); | ||
644 | GCCH_send_data_ack (ch, fwd); | ||
645 | } | ||
646 | else | ||
647 | { | ||
648 | LOG (GNUNET_ERROR_TYPE_DEBUG, " reliable && don't have %u, next is %u\n", | ||
649 | rel->mid_recv, copy->mid); | ||
650 | if (GNUNET_YES == ch->destroy) | ||
651 | { | ||
652 | /* We don't have the next data piece and the remote peer has closed the | ||
653 | * channel. We won't receive it anymore, so just destroy the channel. | ||
654 | * FIXME: wait some time to allow other connections to | ||
655 | * deliver missing messages | ||
656 | */ | ||
657 | send_destroy (ch, GNUNET_YES); | ||
658 | GCCH_destroy (ch); | ||
659 | } | ||
660 | } | ||
661 | } | ||
662 | LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n"); | ||
663 | } | ||
664 | |||
665 | |||
666 | /** | ||
667 | * Allow a client to send more data. | ||
668 | * | ||
669 | * In case the client was already allowed to send data, do nothing. | ||
670 | * | ||
671 | * @param ch Channel. | ||
672 | * @param fwd Is this a FWD ACK? (FWD ACKs are sent to root) | ||
673 | */ | ||
674 | static void | ||
675 | send_client_ack (struct CadetChannel *ch, int fwd) | ||
676 | { | ||
677 | struct CadetChannelReliability *rel = fwd ? ch->root_rel : ch->dest_rel; | ||
678 | struct CadetClient *c = fwd ? ch->root : ch->dest; | ||
679 | |||
680 | if (NULL == c) | ||
681 | { | ||
682 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
683 | return; | ||
684 | } | ||
685 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
686 | " sending %s ack to client on channel %s\n", | ||
687 | GC_f2s (fwd), GCCH_2s (ch)); | ||
688 | |||
689 | if (NULL == rel) | ||
690 | { | ||
691 | GNUNET_break (0); | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | if (GNUNET_YES == rel->client_allowed) | ||
696 | { | ||
697 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already allowed\n"); | ||
698 | return; | ||
699 | } | ||
700 | rel->client_allowed = GNUNET_YES; | ||
701 | |||
702 | GML_send_ack (c, fwd ? ch->lid_root : ch->lid_dest); | ||
703 | } | ||
704 | |||
705 | |||
706 | /** | ||
707 | * Notify the root that the destination rejected the channel. | ||
708 | * | ||
709 | * @param ch Rejected channel. | ||
710 | */ | ||
711 | static void | ||
712 | send_client_nack (struct CadetChannel *ch) | ||
713 | { | ||
714 | if (NULL == ch->root) | ||
715 | { | ||
716 | GNUNET_break (0); | ||
717 | return; | ||
718 | } | ||
719 | GML_send_channel_nack (ch->root, ch->lid_root); | ||
720 | } | ||
721 | |||
722 | |||
723 | /** | ||
724 | * We haven't received an ACK after a certain time: restransmit the message. | ||
725 | * | ||
726 | * @param cls Closure (CadetChannelReliability with the message to restransmit) | ||
727 | */ | ||
728 | static void | ||
729 | channel_retransmit_message (void *cls) | ||
730 | { | ||
731 | struct CadetChannelReliability *rel = cls; | ||
732 | struct CadetReliableMessage *copy; | ||
733 | struct CadetChannel *ch; | ||
734 | struct GNUNET_CADET_ChannelAppDataMessage *payload; | ||
735 | int fwd; | ||
736 | |||
737 | rel->retry_task = NULL; | ||
738 | ch = rel->ch; | ||
739 | copy = rel->head_sent; | ||
740 | if (NULL == copy) | ||
741 | { | ||
742 | GNUNET_break (0); // FIXME tripped in rps testcase | ||
743 | return; | ||
744 | } | ||
745 | |||
746 | payload = (struct GNUNET_CADET_ChannelAppDataMessage *) ©[1]; | ||
747 | fwd = (rel == ch->root_rel); | ||
748 | |||
749 | /* Message not found in the queue that we are going to use. */ | ||
750 | LOG (GNUNET_ERROR_TYPE_DEBUG, "RETRANSMIT MID %u\n", copy->mid); | ||
751 | |||
752 | GCCH_send_prebuilt_message (&payload->header, ch, fwd, copy); | ||
753 | GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO); | ||
754 | } | ||
755 | |||
756 | |||
757 | /** | ||
758 | * We haven't received an Channel ACK after a certain time: resend the CREATE. | ||
759 | * | ||
760 | * @param cls Closure (CadetChannelReliability of the channel to recreate) | ||
761 | */ | ||
762 | static void | ||
763 | channel_recreate (void *cls) | ||
764 | { | ||
765 | struct CadetChannelReliability *rel = cls; | ||
766 | |||
767 | rel->retry_task = NULL; | ||
768 | LOG (GNUNET_ERROR_TYPE_DEBUG, "RE-CREATE\n"); | ||
769 | GNUNET_STATISTICS_update (stats, | ||
770 | "# data retransmitted", 1, GNUNET_NO); | ||
771 | |||
772 | if (rel == rel->ch->root_rel) | ||
773 | { | ||
774 | send_create (rel->ch); | ||
775 | } | ||
776 | else if (rel == rel->ch->dest_rel) | ||
777 | { | ||
778 | send_ack (rel->ch, GNUNET_YES); | ||
779 | } | ||
780 | else | ||
781 | { | ||
782 | GNUNET_break (0); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | |||
787 | /** | ||
788 | * Message has been sent: start retransmission timer. | ||
789 | * | ||
790 | * @param cls Closure (queue structure). | ||
791 | * @param t Tunnel. | ||
792 | * @param q Queue handler (no longer valid). | ||
793 | * @param type Type of message. | ||
794 | * @param size Size of the message. | ||
795 | */ | ||
796 | static void | ||
797 | ch_message_sent (void *cls, | ||
798 | struct CadetTunnel *t, | ||
799 | struct CadetTunnelQueue *q, | ||
800 | uint16_t type, size_t size) | ||
801 | { | ||
802 | struct CadetChannelQueue *chq = cls; | ||
803 | struct CadetReliableMessage *copy = chq->copy; | ||
804 | struct CadetChannelReliability *rel; | ||
805 | |||
806 | LOG (GNUNET_ERROR_TYPE_DEBUG, "channel_message_sent callback %s\n", | ||
807 | GC_m2s (chq->type)); | ||
808 | |||
809 | switch (chq->type) | ||
810 | { | ||
811 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
812 | LOG (GNUNET_ERROR_TYPE_DEBUG, "data MID %u sent\n", copy->mid); | ||
813 | GNUNET_assert (chq == copy->chq); | ||
814 | copy->timestamp = GNUNET_TIME_absolute_get (); | ||
815 | rel = copy->rel; | ||
816 | if (NULL == rel->retry_task) | ||
817 | { | ||
818 | LOG (GNUNET_ERROR_TYPE_DEBUG, " scheduling retry in %d * %s\n", | ||
819 | CADET_RETRANSMIT_MARGIN, | ||
820 | GNUNET_STRINGS_relative_time_to_string (rel->expected_delay, | ||
821 | GNUNET_YES)); | ||
822 | if (0 != rel->expected_delay.rel_value_us) | ||
823 | { | ||
824 | rel->retry_timer = | ||
825 | GNUNET_TIME_relative_saturating_multiply (rel->expected_delay, | ||
826 | CADET_RETRANSMIT_MARGIN); | ||
827 | } | ||
828 | else | ||
829 | { | ||
830 | rel->retry_timer = CADET_RETRANSMIT_TIME; | ||
831 | } | ||
832 | LOG (GNUNET_ERROR_TYPE_DEBUG, " using delay %s\n", | ||
833 | GNUNET_STRINGS_relative_time_to_string (rel->retry_timer, | ||
834 | GNUNET_NO)); | ||
835 | rel->retry_task = | ||
836 | GNUNET_SCHEDULER_add_delayed (rel->retry_timer, | ||
837 | &channel_retransmit_message, rel); | ||
838 | } | ||
839 | else | ||
840 | { | ||
841 | LOG (GNUNET_ERROR_TYPE_DEBUG, "retry running %p\n", rel->retry_task); | ||
842 | } | ||
843 | copy->chq = NULL; | ||
844 | break; | ||
845 | |||
846 | |||
847 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | ||
848 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | ||
849 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | ||
850 | LOG (GNUNET_ERROR_TYPE_DEBUG, "sent %s\n", GC_m2s (chq->type)); | ||
851 | rel = chq->rel; | ||
852 | GNUNET_assert (rel->uniq == chq); | ||
853 | rel->uniq = NULL; | ||
854 | |||
855 | if (CADET_CHANNEL_READY != rel->ch->state | ||
856 | && GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK != type | ||
857 | && GNUNET_NO == rel->ch->destroy) | ||
858 | { | ||
859 | GNUNET_assert (NULL == rel->retry_task); | ||
860 | LOG (GNUNET_ERROR_TYPE_DEBUG, "STD BACKOFF %s\n", | ||
861 | GNUNET_STRINGS_relative_time_to_string (rel->retry_timer, | ||
862 | GNUNET_NO)); | ||
863 | rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer); | ||
864 | rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer, | ||
865 | &channel_recreate, rel); | ||
866 | } | ||
867 | break; | ||
868 | |||
869 | default: | ||
870 | GNUNET_break (0); | ||
871 | } | ||
872 | |||
873 | GNUNET_free (chq); | ||
874 | } | ||
875 | |||
876 | |||
877 | /** | ||
878 | * send a channel create message. | ||
879 | * | ||
880 | * @param ch Channel for which to send. | ||
881 | */ | ||
882 | static void | ||
883 | send_create (struct CadetChannel *ch) | ||
884 | { | ||
885 | struct GNUNET_CADET_ChannelOpenMessage msgcc; | ||
886 | |||
887 | msgcc.header.size = htons (sizeof (msgcc)); | ||
888 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | ||
889 | msgcc.ctn = ch->gid; | ||
890 | msgcc.port = ch->port; | ||
891 | msgcc.opt = htonl (channel_get_options (ch)); | ||
892 | |||
893 | GCCH_send_prebuilt_message (&msgcc.header, ch, GNUNET_YES, NULL); | ||
894 | } | ||
895 | |||
896 | |||
897 | /** | ||
898 | * Confirm we got a channel create or FWD ack. | ||
899 | * | ||
900 | * @param ch The channel to confirm. | ||
901 | * @param fwd Should we send a FWD ACK? (going dest->root) | ||
902 | */ | ||
903 | static void | ||
904 | send_ack (struct CadetChannel *ch, int fwd) | ||
905 | { | ||
906 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
907 | |||
908 | msg.header.size = htons (sizeof (msg)); | ||
909 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK); | ||
910 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
911 | " sending channel %s ack for channel %s\n", | ||
912 | GC_f2s (fwd), GCCH_2s (ch)); | ||
913 | |||
914 | msg.ctn =ch->gid; | ||
915 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); | ||
916 | } | ||
917 | |||
918 | |||
919 | /** | ||
920 | * Send a message and don't keep any info about it: we won't need to cancel it | ||
921 | * or resend it. | ||
922 | * | ||
923 | * @param msg Header of the message to fire away. | ||
924 | * @param ch Channel on which the message should go. | ||
925 | * @param force Is this a forced (undroppable) message? | ||
926 | */ | ||
927 | static void | ||
928 | fire_and_forget (const struct GNUNET_MessageHeader *msg, | ||
929 | struct CadetChannel *ch, | ||
930 | int force) | ||
931 | { | ||
932 | GNUNET_break (NULL == | ||
933 | GCT_send_prebuilt_message (msg, ch->t, NULL, | ||
934 | force, NULL, NULL)); | ||
935 | } | ||
936 | |||
937 | |||
938 | /** | ||
939 | * Notify that a channel create didn't succeed. | ||
940 | * | ||
941 | * @param ch The channel to reject. | ||
942 | */ | ||
943 | static void | ||
944 | send_nack (struct CadetChannel *ch) | ||
945 | { | ||
946 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
947 | |||
948 | msg.header.size = htons (sizeof (msg)); | ||
949 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED); | ||
950 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
951 | " sending channel NACK for channel %s\n", | ||
952 | GCCH_2s (ch)); | ||
953 | |||
954 | msg.ctn = ch->gid; | ||
955 | GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL); | ||
956 | } | ||
957 | |||
958 | |||
959 | /** | ||
960 | * Destroy all reliable messages queued for a channel, | ||
961 | * during a channel destruction. | ||
962 | * Frees the reliability structure itself. | ||
963 | * | ||
964 | * @param rel Reliability data for a channel. | ||
965 | */ | ||
966 | static void | ||
967 | channel_rel_free_all (struct CadetChannelReliability *rel) | ||
968 | { | ||
969 | struct CadetReliableMessage *copy; | ||
970 | struct CadetReliableMessage *next; | ||
971 | |||
972 | if (NULL == rel) | ||
973 | return; | ||
974 | |||
975 | for (copy = rel->head_recv; NULL != copy; copy = next) | ||
976 | { | ||
977 | next = copy->next; | ||
978 | GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy); | ||
979 | LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL RECV %p\n", copy); | ||
980 | GNUNET_break (NULL == copy->chq); | ||
981 | GNUNET_free (copy); | ||
982 | } | ||
983 | for (copy = rel->head_sent; NULL != copy; copy = next) | ||
984 | { | ||
985 | next = copy->next; | ||
986 | GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy); | ||
987 | LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL SEND %p\n", copy); | ||
988 | if (NULL != copy->chq) | ||
989 | { | ||
990 | if (NULL != copy->chq->tq) | ||
991 | { | ||
992 | GCT_cancel (copy->chq->tq); | ||
993 | /* ch_message_sent will free copy->q */ | ||
994 | } | ||
995 | else | ||
996 | { | ||
997 | GNUNET_free (copy->chq); | ||
998 | GNUNET_break (0); | ||
999 | } | ||
1000 | } | ||
1001 | GNUNET_free (copy); | ||
1002 | } | ||
1003 | if (NULL != rel->uniq && NULL != rel->uniq->tq) | ||
1004 | { | ||
1005 | GCT_cancel (rel->uniq->tq); | ||
1006 | /* ch_message_sent is called freeing uniq */ | ||
1007 | } | ||
1008 | if (NULL != rel->retry_task) | ||
1009 | { | ||
1010 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1011 | rel->retry_task = NULL; | ||
1012 | } | ||
1013 | GNUNET_free (rel); | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | /** | ||
1018 | * Mark future messages as ACK'd. | ||
1019 | * | ||
1020 | * @param rel Reliability data. | ||
1021 | * @param msg DataACK message with a bitfield of future ACK'd messages. | ||
1022 | * | ||
1023 | * @return How many messages have been freed. | ||
1024 | */ | ||
1025 | static unsigned int | ||
1026 | channel_rel_free_sent (struct CadetChannelReliability *rel, | ||
1027 | const struct GNUNET_CADET_ChannelDataAckMessage *msg) | ||
1028 | { | ||
1029 | struct CadetReliableMessage *copy; | ||
1030 | struct CadetReliableMessage *next; | ||
1031 | uint64_t bitfield; | ||
1032 | uint64_t mask; | ||
1033 | uint32_t mid; | ||
1034 | uint32_t target; | ||
1035 | unsigned int i; | ||
1036 | unsigned int r; | ||
1037 | |||
1038 | bitfield = msg->futures; | ||
1039 | mid = ntohl (msg->mid); | ||
1040 | LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable %u %lX\n", mid, bitfield); | ||
1041 | LOG (GNUNET_ERROR_TYPE_DEBUG, " rel %p, head %p\n", rel, rel->head_sent); | ||
1042 | for (i = 0, r = 0, copy = rel->head_sent; | ||
1043 | i < 64 && NULL != copy && 0 != bitfield; | ||
1044 | i++) | ||
1045 | { | ||
1046 | LOG (GNUNET_ERROR_TYPE_DEBUG, " trying bit %u (mid %u)\n", i, mid + i + 1); | ||
1047 | mask = 0x1LL << i; | ||
1048 | if (0 == (bitfield & mask)) | ||
1049 | continue; | ||
1050 | |||
1051 | LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n"); | ||
1052 | /* Bit was set, clear the bit from the bitfield */ | ||
1053 | bitfield &= ~mask; | ||
1054 | |||
1055 | /* The i-th bit was set. Do we have that copy? */ | ||
1056 | /* Skip copies with mid < target */ | ||
1057 | target = mid + i + 1; | ||
1058 | LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target); | ||
1059 | while (NULL != copy && GC_is_pid_bigger (target, copy->mid)) | ||
1060 | copy = copy->next; | ||
1061 | |||
1062 | /* Did we run out of copies? (previously freed, it's ok) */ | ||
1063 | if (NULL == copy) | ||
1064 | { | ||
1065 | LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n"); | ||
1066 | return r; | ||
1067 | } | ||
1068 | |||
1069 | /* Did we overshoot the target? (previously freed, it's ok) */ | ||
1070 | if (GC_is_pid_bigger (copy->mid, target)) | ||
1071 | { | ||
1072 | LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid); | ||
1073 | i += copy->mid - target - 1; /* MID: 90, t = 85, i += 4 (i++ later) */ | ||
1074 | mask = (0x1LL << (i + 1)) - 1; /* Mask = i-th bit and all before */ | ||
1075 | bitfield &= ~mask; /* Clear all bits up to MID - 1 */ | ||
1076 | continue; | ||
1077 | } | ||
1078 | |||
1079 | /* Now copy->mid == target, free it */ | ||
1080 | next = copy->next; | ||
1081 | GNUNET_break (GNUNET_YES != rel_message_free (copy, GNUNET_YES)); | ||
1082 | r++; | ||
1083 | copy = next; | ||
1084 | } | ||
1085 | LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n"); | ||
1086 | return r; | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | /** | ||
1091 | * Destroy a reliable message after it has been acknowledged, either by | ||
1092 | * direct mid ACK or bitfield. Updates the appropriate data structures and | ||
1093 | * timers and frees all memory. | ||
1094 | * | ||
1095 | * @param copy Message that is no longer needed: remote peer got it. | ||
1096 | * @param update_time Is the timing information relevant? | ||
1097 | * If this message is ACK in a batch the timing information | ||
1098 | * is skewed by the retransmission, count only for the | ||
1099 | * retransmitted message. | ||
1100 | * | ||
1101 | * @return #GNUNET_YES if channel was destroyed as a result of the call, | ||
1102 | * #GNUNET_NO otherwise. | ||
1103 | */ | ||
1104 | static int | ||
1105 | rel_message_free (struct CadetReliableMessage *copy, int update_time) | ||
1106 | { | ||
1107 | struct CadetChannelReliability *rel; | ||
1108 | struct GNUNET_TIME_Relative time; | ||
1109 | |||
1110 | rel = copy->rel; | ||
1111 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing %u\n", copy->mid); | ||
1112 | if (GNUNET_YES == update_time) | ||
1113 | { | ||
1114 | time = GNUNET_TIME_absolute_get_duration (copy->timestamp); | ||
1115 | if (0 == rel->expected_delay.rel_value_us) | ||
1116 | rel->expected_delay = time; | ||
1117 | else | ||
1118 | { | ||
1119 | rel->expected_delay.rel_value_us *= 7; | ||
1120 | rel->expected_delay.rel_value_us += time.rel_value_us; | ||
1121 | rel->expected_delay.rel_value_us /= 8; | ||
1122 | } | ||
1123 | LOG (GNUNET_ERROR_TYPE_DEBUG, " message time %12s\n", | ||
1124 | GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO)); | ||
1125 | LOG (GNUNET_ERROR_TYPE_DEBUG, " new delay %12s\n", | ||
1126 | GNUNET_STRINGS_relative_time_to_string (rel->expected_delay, | ||
1127 | GNUNET_NO)); | ||
1128 | rel->retry_timer = rel->expected_delay; | ||
1129 | } | ||
1130 | else | ||
1131 | { | ||
1132 | LOG (GNUNET_ERROR_TYPE_DEBUG, "batch free, ignoring timing\n"); | ||
1133 | } | ||
1134 | rel->ch->pending_messages--; | ||
1135 | if (NULL != copy->chq) | ||
1136 | { | ||
1137 | GCT_cancel (copy->chq->tq); | ||
1138 | /* copy->q is set to NULL by ch_message_sent */ | ||
1139 | } | ||
1140 | GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy); | ||
1141 | LOG (GNUNET_ERROR_TYPE_DEBUG, " free send copy MID %u at %p\n", | ||
1142 | copy->mid, copy); | ||
1143 | GNUNET_free (copy); | ||
1144 | |||
1145 | if (GNUNET_NO != rel->ch->destroy && 0 == rel->ch->pending_messages) | ||
1146 | { | ||
1147 | GCCH_destroy (rel->ch); | ||
1148 | return GNUNET_YES; | ||
1149 | } | ||
1150 | return GNUNET_NO; | ||
1151 | } | ||
1152 | |||
1153 | |||
1154 | /** | ||
1155 | * Channel was ACK'd by remote peer, mark as ready and cancel retransmission. | ||
1156 | * | ||
1157 | * @param ch Channel to mark as ready. | ||
1158 | * @param fwd Was the ACK message a FWD ACK? (dest->root, SYNACK) | ||
1159 | */ | ||
1160 | static void | ||
1161 | channel_confirm (struct CadetChannel *ch, int fwd) | ||
1162 | { | ||
1163 | struct CadetChannelReliability *rel; | ||
1164 | enum CadetChannelState oldstate; | ||
1165 | |||
1166 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1167 | if (NULL == rel) | ||
1168 | { | ||
1169 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1170 | return; | ||
1171 | } | ||
1172 | LOG (GNUNET_ERROR_TYPE_DEBUG, " channel confirm %s %s\n", | ||
1173 | GC_f2s (fwd), GCCH_2s (ch)); | ||
1174 | oldstate = ch->state; | ||
1175 | ch->state = CADET_CHANNEL_READY; | ||
1176 | |||
1177 | if (CADET_CHANNEL_READY != oldstate || GNUNET_YES == is_loopback (ch)) | ||
1178 | { | ||
1179 | rel->client_ready = GNUNET_YES; | ||
1180 | rel->expected_delay = rel->retry_timer; | ||
1181 | LOG (GNUNET_ERROR_TYPE_DEBUG, " confirm retry timer %s\n", | ||
1182 | GNUNET_STRINGS_relative_time_to_string (rel->retry_timer, GNUNET_NO)); | ||
1183 | if (GCT_get_connections_buffer (ch->t) > 0 || GCT_is_loopback (ch->t)) | ||
1184 | send_client_ack (ch, fwd); | ||
1185 | |||
1186 | if (NULL != rel->retry_task) | ||
1187 | { | ||
1188 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1189 | rel->retry_task = NULL; | ||
1190 | } | ||
1191 | else if (NULL != rel->uniq) | ||
1192 | { | ||
1193 | GCT_cancel (rel->uniq->tq); | ||
1194 | /* ch_message_sent will free and NULL uniq */ | ||
1195 | } | ||
1196 | else if (GNUNET_NO == is_loopback (ch)) | ||
1197 | { | ||
1198 | /* We SHOULD have been trying to retransmit this! */ | ||
1199 | GNUNET_break (0); | ||
1200 | } | ||
1201 | } | ||
1202 | |||
1203 | /* In case of a FWD ACK (SYNACK) send a BCK ACK (ACK). */ | ||
1204 | if (GNUNET_YES == fwd) | ||
1205 | send_ack (ch, GNUNET_NO); | ||
1206 | } | ||
1207 | |||
1208 | |||
1209 | /** | ||
1210 | * Save a copy to retransmit in case it gets lost. | ||
1211 | * | ||
1212 | * Initializes all needed callbacks and timers. | ||
1213 | * | ||
1214 | * @param ch Channel this message goes on. | ||
1215 | * @param msg Message to copy. | ||
1216 | * @param fwd Is this fwd traffic? | ||
1217 | */ | ||
1218 | static struct CadetReliableMessage * | ||
1219 | channel_save_copy (struct CadetChannel *ch, | ||
1220 | const struct GNUNET_MessageHeader *msg, | ||
1221 | int fwd) | ||
1222 | { | ||
1223 | struct CadetChannelReliability *rel; | ||
1224 | struct CadetReliableMessage *copy; | ||
1225 | uint32_t mid; | ||
1226 | uint16_t type; | ||
1227 | uint16_t size; | ||
1228 | |||
1229 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1230 | mid = rel->mid_send - 1; | ||
1231 | type = ntohs (msg->type); | ||
1232 | size = ntohs (msg->size); | ||
1233 | |||
1234 | LOG (GNUNET_ERROR_TYPE_DEBUG, "save MID %u %s\n", mid, GC_m2s (type)); | ||
1235 | copy = GNUNET_malloc (sizeof (struct CadetReliableMessage) + size); | ||
1236 | LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", copy); | ||
1237 | copy->mid = mid; | ||
1238 | copy->rel = rel; | ||
1239 | copy->type = type; | ||
1240 | GNUNET_memcpy (©[1], msg, size); | ||
1241 | GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy); | ||
1242 | ch->pending_messages++; | ||
1243 | |||
1244 | return copy; | ||
1245 | } | ||
1246 | |||
1247 | |||
1248 | /** | ||
1249 | * Create a new channel. | ||
1250 | * | ||
1251 | * @param t Tunnel this channel is in. | ||
1252 | * @param owner Client that owns the channel, NULL for foreign channels. | ||
1253 | * @param lid_root Local ID for root client. | ||
1254 | * | ||
1255 | * @return A new initialized channel. NULL on error. | ||
1256 | */ | ||
1257 | static struct CadetChannel * | ||
1258 | channel_new (struct CadetTunnel *t, | ||
1259 | struct CadetClient *owner, | ||
1260 | struct GNUNET_CADET_ClientChannelNumber lid_root) | ||
1261 | { | ||
1262 | struct CadetChannel *ch; | ||
1263 | |||
1264 | ch = GNUNET_new (struct CadetChannel); | ||
1265 | ch->root = owner; | ||
1266 | ch->lid_root = lid_root; | ||
1267 | ch->t = t; | ||
1268 | |||
1269 | GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO); | ||
1270 | |||
1271 | if (NULL != owner) | ||
1272 | { | ||
1273 | ch->gid = GCT_get_next_ctn (t); | ||
1274 | GML_channel_add (owner, lid_root, ch); | ||
1275 | } | ||
1276 | GCT_add_channel (t, ch); | ||
1277 | |||
1278 | return ch; | ||
1279 | } | ||
1280 | |||
1281 | |||
1282 | /** | ||
1283 | * Handle a loopback message: call the appropriate handler for the message type. | ||
1284 | * | ||
1285 | * @param ch Channel this message is on. | ||
1286 | * @param msgh Message header. | ||
1287 | * @param fwd Is this FWD traffic? | ||
1288 | */ | ||
1289 | void | ||
1290 | handle_loopback (struct CadetChannel *ch, | ||
1291 | const struct GNUNET_MessageHeader *msgh, | ||
1292 | int fwd) | ||
1293 | { | ||
1294 | uint16_t type; | ||
1295 | |||
1296 | type = ntohs (msgh->type); | ||
1297 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1298 | "Loopback %s %s message!\n", | ||
1299 | GC_f2s (fwd), GC_m2s (type)); | ||
1300 | |||
1301 | switch (type) | ||
1302 | { | ||
1303 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
1304 | /* Don't send hop ACK, wait for client to ACK */ | ||
1305 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SEND loopback %u (%u)\n", | ||
1306 | ntohl (((struct GNUNET_CADET_ChannelAppDataMessage *) msgh)->mid), ntohs (msgh->size)); | ||
1307 | GCCH_handle_data (ch, (struct GNUNET_CADET_ChannelAppDataMessage *) msgh, fwd); | ||
1308 | break; | ||
1309 | |||
1310 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | ||
1311 | GCCH_handle_data_ack (ch, | ||
1312 | (const struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd); | ||
1313 | break; | ||
1314 | |||
1315 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | ||
1316 | GCCH_handle_create (ch->t, | ||
1317 | (const struct GNUNET_CADET_ChannelOpenMessage *) msgh); | ||
1318 | break; | ||
1319 | |||
1320 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | ||
1321 | GCCH_handle_ack (ch, | ||
1322 | (const struct GNUNET_CADET_ChannelManageMessage *) msgh, | ||
1323 | fwd); | ||
1324 | break; | ||
1325 | |||
1326 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED: | ||
1327 | GCCH_handle_nack (ch); | ||
1328 | break; | ||
1329 | |||
1330 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
1331 | GCCH_handle_destroy (ch, | ||
1332 | (const struct GNUNET_CADET_ChannelManageMessage *) msgh, | ||
1333 | fwd); | ||
1334 | break; | ||
1335 | |||
1336 | default: | ||
1337 | GNUNET_break_op (0); | ||
1338 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1339 | "end-to-end message not known (%u)\n", | ||
1340 | ntohs (msgh->type)); | ||
1341 | } | ||
1342 | } | ||
1343 | |||
1344 | |||
1345 | |||
1346 | /******************************************************************************/ | ||
1347 | /******************************** API ***********************************/ | ||
1348 | /******************************************************************************/ | ||
1349 | |||
1350 | /** | ||
1351 | * Destroy a channel and free all resources. | ||
1352 | * | ||
1353 | * @param ch Channel to destroy. | ||
1354 | */ | ||
1355 | void | ||
1356 | GCCH_destroy (struct CadetChannel *ch) | ||
1357 | { | ||
1358 | struct CadetClient *c; | ||
1359 | struct CadetTunnel *t; | ||
1360 | |||
1361 | if (NULL == ch) | ||
1362 | return; | ||
1363 | if (2 == ch->destroy) | ||
1364 | return; /* recursive call */ | ||
1365 | ch->destroy = 2; | ||
1366 | |||
1367 | LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n", | ||
1368 | GCT_2s (ch->t), ch->gid); | ||
1369 | GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG); | ||
1370 | |||
1371 | c = ch->root; | ||
1372 | if (NULL != c) | ||
1373 | { | ||
1374 | GML_channel_remove (c, ch->lid_root, ch); | ||
1375 | } | ||
1376 | |||
1377 | c = ch->dest; | ||
1378 | if (NULL != c) | ||
1379 | { | ||
1380 | GML_channel_remove (c, ch->lid_dest, ch); | ||
1381 | } | ||
1382 | |||
1383 | channel_rel_free_all (ch->root_rel); | ||
1384 | channel_rel_free_all (ch->dest_rel); | ||
1385 | |||
1386 | t = ch->t; | ||
1387 | GCT_remove_channel (t, ch); | ||
1388 | GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO); | ||
1389 | |||
1390 | GNUNET_free (ch); | ||
1391 | GCT_destroy_if_empty (t); | ||
1392 | } | ||
1393 | |||
1394 | |||
1395 | /** | ||
1396 | * Get the channel's public ID. | ||
1397 | * | ||
1398 | * @param ch Channel. | ||
1399 | * | ||
1400 | * @return ID used to identify the channel with the remote peer. | ||
1401 | */ | ||
1402 | struct GNUNET_CADET_ChannelTunnelNumber | ||
1403 | GCCH_get_id (const struct CadetChannel *ch) | ||
1404 | { | ||
1405 | return ch->gid; | ||
1406 | } | ||
1407 | |||
1408 | |||
1409 | /** | ||
1410 | * Get the channel tunnel. | ||
1411 | * | ||
1412 | * @param ch Channel to get the tunnel from. | ||
1413 | * | ||
1414 | * @return tunnel of the channel. | ||
1415 | */ | ||
1416 | struct CadetTunnel * | ||
1417 | GCCH_get_tunnel (const struct CadetChannel *ch) | ||
1418 | { | ||
1419 | return ch->t; | ||
1420 | } | ||
1421 | |||
1422 | |||
1423 | /** | ||
1424 | * Get free buffer space towards the client on a specific channel. | ||
1425 | * | ||
1426 | * @param ch Channel. | ||
1427 | * @param fwd Is query about FWD traffic? | ||
1428 | * | ||
1429 | * @return Free buffer space [0 - 64] | ||
1430 | */ | ||
1431 | unsigned int | ||
1432 | GCCH_get_buffer (struct CadetChannel *ch, int fwd) | ||
1433 | { | ||
1434 | struct CadetChannelReliability *rel; | ||
1435 | |||
1436 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1437 | LOG (GNUNET_ERROR_TYPE_DEBUG, " get buffer, channel %s\n", GCCH_2s (ch)); | ||
1438 | GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG); | ||
1439 | /* If rel is NULL it means that the end is not yet created, | ||
1440 | * most probably is a loopback channel at the point of sending | ||
1441 | * the ChannelCreate to itself. | ||
1442 | */ | ||
1443 | if (NULL == rel) | ||
1444 | { | ||
1445 | LOG (GNUNET_ERROR_TYPE_DEBUG, " rel is NULL: max\n"); | ||
1446 | return 64; | ||
1447 | } | ||
1448 | |||
1449 | LOG (GNUNET_ERROR_TYPE_DEBUG, " n_recv %d\n", rel->n_recv); | ||
1450 | return (64 - rel->n_recv); | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | /** | ||
1455 | * Get flow control status of end point: is client allow to send? | ||
1456 | * | ||
1457 | * @param ch Channel. | ||
1458 | * @param fwd Is query about FWD traffic? (Request root status). | ||
1459 | * | ||
1460 | * @return #GNUNET_YES if client is allowed to send us data. | ||
1461 | */ | ||
1462 | int | ||
1463 | GCCH_get_allowed (struct CadetChannel *ch, int fwd) | ||
1464 | { | ||
1465 | struct CadetChannelReliability *rel; | ||
1466 | |||
1467 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1468 | |||
1469 | if (NULL == rel) | ||
1470 | { | ||
1471 | /* Probably shutting down: root/dest NULL'ed to mark disconnection */ | ||
1472 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1473 | return 0; | ||
1474 | } | ||
1475 | |||
1476 | return rel->client_allowed; | ||
1477 | } | ||
1478 | |||
1479 | |||
1480 | /** | ||
1481 | * Is the root client for this channel on this peer? | ||
1482 | * | ||
1483 | * @param ch Channel. | ||
1484 | * @param fwd Is this for fwd traffic? | ||
1485 | * | ||
1486 | * @return #GNUNET_YES in case it is. | ||
1487 | */ | ||
1488 | int | ||
1489 | GCCH_is_origin (struct CadetChannel *ch, int fwd) | ||
1490 | { | ||
1491 | struct CadetClient *c; | ||
1492 | |||
1493 | c = fwd ? ch->root : ch->dest; | ||
1494 | return NULL != c; | ||
1495 | } | ||
1496 | |||
1497 | |||
1498 | /** | ||
1499 | * Is the destination client for this channel on this peer? | ||
1500 | * | ||
1501 | * @param ch Channel. | ||
1502 | * @param fwd Is this for fwd traffic? | ||
1503 | * | ||
1504 | * @return #GNUNET_YES in case it is. | ||
1505 | */ | ||
1506 | int | ||
1507 | GCCH_is_terminal (struct CadetChannel *ch, int fwd) | ||
1508 | { | ||
1509 | struct CadetClient *c; | ||
1510 | |||
1511 | c = fwd ? ch->dest : ch->root; | ||
1512 | return NULL != c; | ||
1513 | } | ||
1514 | |||
1515 | |||
1516 | /** | ||
1517 | * Send an end-to-end ACK message for the most recent in-sequence payload. | ||
1518 | * | ||
1519 | * If channel is not reliable, do nothing. | ||
1520 | * | ||
1521 | * @param ch Channel this is about. | ||
1522 | * @param fwd Is for FWD traffic? (ACK dest->owner) | ||
1523 | */ | ||
1524 | void | ||
1525 | GCCH_send_data_ack (struct CadetChannel *ch, int fwd) | ||
1526 | { | ||
1527 | struct GNUNET_CADET_ChannelDataAckMessage msg; | ||
1528 | struct CadetChannelReliability *rel; | ||
1529 | struct CadetReliableMessage *copy; | ||
1530 | unsigned int delta; | ||
1531 | uint64_t mask; | ||
1532 | uint32_t ack; | ||
1533 | |||
1534 | if (GNUNET_NO == ch->reliable) | ||
1535 | return; | ||
1536 | |||
1537 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1538 | ack = rel->mid_recv - 1; | ||
1539 | |||
1540 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); | ||
1541 | msg.header.size = htons (sizeof (msg)); | ||
1542 | msg.ctn = ch->gid; | ||
1543 | msg.mid = htonl (ack); | ||
1544 | |||
1545 | msg.futures = 0LL; | ||
1546 | for (copy = rel->head_recv; NULL != copy; copy = copy->next) | ||
1547 | { | ||
1548 | if (copy->type != GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA) | ||
1549 | { | ||
1550 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Type %s, expected DATA\n", | ||
1551 | GC_m2s (copy->type)); | ||
1552 | continue; | ||
1553 | } | ||
1554 | GNUNET_assert (GC_is_pid_bigger(copy->mid, ack)); | ||
1555 | delta = copy->mid - (ack + 1); | ||
1556 | if (63 < delta) | ||
1557 | break; | ||
1558 | mask = 0x1LL << delta; | ||
1559 | msg.futures |= mask; | ||
1560 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1561 | " setting bit for %u (delta %u) (%lX) -> %lX\n", | ||
1562 | copy->mid, delta, mask, msg.futures); | ||
1563 | } | ||
1564 | |||
1565 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); | ||
1566 | LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n"); | ||
1567 | } | ||
1568 | |||
1569 | |||
1570 | /** | ||
1571 | * Allow a client to send us more data, in case it was choked. | ||
1572 | * | ||
1573 | * @param ch Channel. | ||
1574 | * @param fwd Is this about FWD traffic? (Root client). | ||
1575 | */ | ||
1576 | void | ||
1577 | GCCH_allow_client (struct CadetChannel *ch, int fwd) | ||
1578 | { | ||
1579 | struct CadetChannelReliability *rel; | ||
1580 | unsigned int buffer; | ||
1581 | |||
1582 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMCH allow\n"); | ||
1583 | |||
1584 | if (CADET_CHANNEL_READY != ch->state) | ||
1585 | { | ||
1586 | LOG (GNUNET_ERROR_TYPE_DEBUG, " channel not ready yet!\n"); | ||
1587 | return; | ||
1588 | } | ||
1589 | |||
1590 | if (GNUNET_YES == ch->reliable) | ||
1591 | { | ||
1592 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1593 | if (NULL == rel) | ||
1594 | { | ||
1595 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1596 | return; | ||
1597 | } | ||
1598 | if (NULL != rel->head_sent) | ||
1599 | { | ||
1600 | if (64 <= rel->mid_send - rel->head_sent->mid) | ||
1601 | { | ||
1602 | LOG (GNUNET_ERROR_TYPE_DEBUG, " too big MID gap! Wait for ACK.\n"); | ||
1603 | return; | ||
1604 | } | ||
1605 | else | ||
1606 | { | ||
1607 | LOG (GNUNET_ERROR_TYPE_DEBUG, " gap ok: %u - %u\n", | ||
1608 | rel->head_sent->mid, rel->mid_send); | ||
1609 | struct CadetReliableMessage *aux; | ||
1610 | for (aux = rel->head_sent; NULL != aux; aux = aux->next) | ||
1611 | { | ||
1612 | LOG (GNUNET_ERROR_TYPE_DEBUG, " - sent mid %u\n", aux->mid); | ||
1613 | } | ||
1614 | } | ||
1615 | } | ||
1616 | else | ||
1617 | { | ||
1618 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head sent is NULL\n"); | ||
1619 | } | ||
1620 | } | ||
1621 | |||
1622 | if (is_loopback (ch)) | ||
1623 | buffer = GCCH_get_buffer (ch, fwd); | ||
1624 | else | ||
1625 | buffer = GCT_get_connections_buffer (ch->t); | ||
1626 | |||
1627 | if (0 == buffer) | ||
1628 | { | ||
1629 | LOG (GNUNET_ERROR_TYPE_DEBUG, " no buffer space.\n"); | ||
1630 | return; | ||
1631 | } | ||
1632 | |||
1633 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space %u, allowing\n", buffer); | ||
1634 | send_client_ack (ch, fwd); | ||
1635 | } | ||
1636 | |||
1637 | |||
1638 | /** | ||
1639 | * Log channel info. | ||
1640 | * | ||
1641 | * @param ch Channel. | ||
1642 | * @param level Debug level to use. | ||
1643 | */ | ||
1644 | void | ||
1645 | GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level) | ||
1646 | { | ||
1647 | int do_log; | ||
1648 | |||
1649 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
1650 | "cadet-chn", | ||
1651 | __FILE__, __FUNCTION__, __LINE__); | ||
1652 | if (0 == do_log) | ||
1653 | return; | ||
1654 | |||
1655 | if (NULL == ch) | ||
1656 | { | ||
1657 | LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n"); | ||
1658 | return; | ||
1659 | } | ||
1660 | LOG2 (level, "CHN Channel %s:%X (%p)\n", GCT_2s (ch->t), ch->gid, ch); | ||
1661 | LOG2 (level, "CHN root %p/%p\n", ch->root, ch->root_rel); | ||
1662 | if (NULL != ch->root) | ||
1663 | { | ||
1664 | LOG2 (level, "CHN cli %s\n", GML_2s (ch->root)); | ||
1665 | LOG2 (level, "CHN ready %s\n", ch->root_rel->client_ready ? "YES" : "NO"); | ||
1666 | LOG2 (level, "CHN id %X\n", ch->lid_root.channel_of_client); | ||
1667 | LOG2 (level, "CHN recv %d\n", ch->root_rel->n_recv); | ||
1668 | LOG2 (level, "CHN MID r: %d, s: %d\n", | ||
1669 | ch->root_rel->mid_recv, ch->root_rel->mid_send); | ||
1670 | } | ||
1671 | LOG2 (level, "CHN dest %p/%p\n", | ||
1672 | ch->dest, ch->dest_rel); | ||
1673 | if (NULL != ch->dest) | ||
1674 | { | ||
1675 | LOG2 (level, "CHN cli %s\n", GML_2s (ch->dest)); | ||
1676 | LOG2 (level, "CHN ready %s\n", ch->dest_rel->client_ready ? "YES" : "NO"); | ||
1677 | LOG2 (level, "CHN id %X\n", ch->lid_dest); | ||
1678 | LOG2 (level, "CHN recv %d\n", ch->dest_rel->n_recv); | ||
1679 | LOG2 (level, "CHN MID r: %d, s: %d\n", | ||
1680 | ch->dest_rel->mid_recv, ch->dest_rel->mid_send); | ||
1681 | |||
1682 | } | ||
1683 | } | ||
1684 | |||
1685 | |||
1686 | /** | ||
1687 | * Handle an ACK given by a client. | ||
1688 | * | ||
1689 | * Mark client as ready and send him any buffered data we could have for him. | ||
1690 | * | ||
1691 | * @param ch Channel. | ||
1692 | * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by dest and go BCK) | ||
1693 | */ | ||
1694 | void | ||
1695 | GCCH_handle_local_ack (struct CadetChannel *ch, int fwd) | ||
1696 | { | ||
1697 | struct CadetChannelReliability *rel; | ||
1698 | struct CadetClient *c; | ||
1699 | |||
1700 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1701 | c = fwd ? ch->dest : ch->root; | ||
1702 | |||
1703 | rel->client_ready = GNUNET_YES; | ||
1704 | send_client_buffered_data (ch, c, fwd); | ||
1705 | |||
1706 | if (GNUNET_YES == ch->destroy && 0 == rel->n_recv) | ||
1707 | { | ||
1708 | send_destroy (ch, GNUNET_YES); | ||
1709 | GCCH_destroy (ch); | ||
1710 | return; | ||
1711 | } | ||
1712 | /* if loopback is marked for destruction, no need to ACK to the other peer, | ||
1713 | * it requested the destruction and is already gone, therefore, else if. | ||
1714 | */ | ||
1715 | else if (is_loopback (ch)) | ||
1716 | { | ||
1717 | unsigned int buffer; | ||
1718 | |||
1719 | buffer = GCCH_get_buffer (ch, fwd); | ||
1720 | if (0 < buffer) | ||
1721 | GCCH_allow_client (ch, fwd); | ||
1722 | |||
1723 | return; | ||
1724 | } | ||
1725 | GCT_send_connection_acks (ch->t); | ||
1726 | } | ||
1727 | |||
1728 | |||
1729 | /** | ||
1730 | * Handle data given by a client. | ||
1731 | * | ||
1732 | * Check whether the client is allowed to send in this tunnel, save if channel | ||
1733 | * is reliable and send an ACK to the client if there is still buffer space | ||
1734 | * in the tunnel. | ||
1735 | * | ||
1736 | * @param ch Channel. | ||
1737 | * @param c Client which sent the data. | ||
1738 | * @param fwd Is this a FWD data? | ||
1739 | * @param message Data message. | ||
1740 | * @param size Size of data. | ||
1741 | * | ||
1742 | * @return #GNUNET_OK if everything goes well, #GNUNET_SYSERR in case of en error. | ||
1743 | */ | ||
1744 | int | ||
1745 | GCCH_handle_local_data (struct CadetChannel *ch, | ||
1746 | struct CadetClient *c, | ||
1747 | int fwd, | ||
1748 | const struct GNUNET_MessageHeader *message, | ||
1749 | size_t size) | ||
1750 | { | ||
1751 | struct CadetChannelReliability *rel; | ||
1752 | struct GNUNET_CADET_ChannelAppDataMessage *payload; | ||
1753 | uint16_t p2p_size = sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + size; | ||
1754 | unsigned char cbuf[p2p_size]; | ||
1755 | unsigned char buffer; | ||
1756 | |||
1757 | /* Is the client in the channel? */ | ||
1758 | if ( !( (fwd && | ||
1759 | ch->root == c) | ||
1760 | || | ||
1761 | (!fwd && | ||
1762 | ch->dest == c) ) ) | ||
1763 | { | ||
1764 | GNUNET_break_op (0); | ||
1765 | return GNUNET_SYSERR; | ||
1766 | } | ||
1767 | |||
1768 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1769 | |||
1770 | if (GNUNET_NO == rel->client_allowed) | ||
1771 | { | ||
1772 | GNUNET_break_op (0); | ||
1773 | return GNUNET_SYSERR; | ||
1774 | } | ||
1775 | |||
1776 | rel->client_allowed = GNUNET_NO; | ||
1777 | |||
1778 | /* Ok, everything is correct, send the message. */ | ||
1779 | payload = (struct GNUNET_CADET_ChannelAppDataMessage *) cbuf; | ||
1780 | payload->mid = htonl (rel->mid_send); | ||
1781 | rel->mid_send++; | ||
1782 | GNUNET_memcpy (&payload[1], message, size); | ||
1783 | payload->header.size = htons (p2p_size); | ||
1784 | payload->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); | ||
1785 | payload->ctn = ch->gid; | ||
1786 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n"); | ||
1787 | GCCH_send_prebuilt_message (&payload->header, ch, fwd, NULL); | ||
1788 | |||
1789 | if (is_loopback (ch)) | ||
1790 | buffer = GCCH_get_buffer (ch, fwd); | ||
1791 | else | ||
1792 | buffer = GCT_get_connections_buffer (ch->t); | ||
1793 | |||
1794 | if (0 < buffer) | ||
1795 | GCCH_allow_client (ch, fwd); | ||
1796 | |||
1797 | return GNUNET_OK; | ||
1798 | } | ||
1799 | |||
1800 | |||
1801 | /** | ||
1802 | * Handle a channel destroy requested by a client. | ||
1803 | * | ||
1804 | * TODO: add "reason" field | ||
1805 | * | ||
1806 | * Destroy the channel and the tunnel in case this was the last channel. | ||
1807 | * | ||
1808 | * @param ch Channel. | ||
1809 | * @param c Client that requested the destruction (to avoid notifying him). | ||
1810 | * @param is_root Is the request coming from root? | ||
1811 | */ | ||
1812 | void | ||
1813 | GCCH_handle_local_destroy (struct CadetChannel *ch, | ||
1814 | struct CadetClient *c, | ||
1815 | int is_root) | ||
1816 | { | ||
1817 | ch->destroy = GNUNET_YES; | ||
1818 | /* Cleanup after the tunnel */ | ||
1819 | if (GNUNET_NO == is_root && c == ch->dest) | ||
1820 | { | ||
1821 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c)); | ||
1822 | GML_client_delete_channel (c, ch, ch->lid_dest); | ||
1823 | ch->dest = NULL; | ||
1824 | } | ||
1825 | if (GNUNET_YES == is_root && c == ch->root) | ||
1826 | { | ||
1827 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c)); | ||
1828 | GML_client_delete_channel (c, ch, ch->lid_root); | ||
1829 | ch->root = NULL; | ||
1830 | } | ||
1831 | |||
1832 | send_destroy (ch, GNUNET_NO); | ||
1833 | if (0 == ch->pending_messages) | ||
1834 | GCCH_destroy (ch); | ||
1835 | } | ||
1836 | |||
1837 | |||
1838 | /** | ||
1839 | * Handle a channel create requested by a client. | ||
1840 | * | ||
1841 | * Create the channel and the tunnel in case this was the first0 channel. | ||
1842 | * | ||
1843 | * @param c Client that requested the creation (will be the root). | ||
1844 | * @param msg Create Channel message. | ||
1845 | * | ||
1846 | * @return #GNUNET_OK if everything went fine, #GNUNET_SYSERR otherwise. | ||
1847 | */ | ||
1848 | int | ||
1849 | GCCH_handle_local_create (struct CadetClient *c, | ||
1850 | struct GNUNET_CADET_LocalChannelCreateMessage *msg) | ||
1851 | { | ||
1852 | struct CadetChannel *ch; | ||
1853 | struct CadetTunnel *t; | ||
1854 | struct CadetPeer *peer; | ||
1855 | struct GNUNET_CADET_ClientChannelNumber ccn; | ||
1856 | |||
1857 | LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n", | ||
1858 | GNUNET_i2s (&msg->peer), GNUNET_h2s (&msg->port)); | ||
1859 | ccn = msg->ccn; | ||
1860 | |||
1861 | /* Sanity check for duplicate channel IDs */ | ||
1862 | if (NULL != GML_channel_get (c, ccn)) | ||
1863 | { | ||
1864 | GNUNET_break (0); | ||
1865 | return GNUNET_SYSERR; | ||
1866 | } | ||
1867 | |||
1868 | peer = GCP_get (&msg->peer, GNUNET_YES); | ||
1869 | GCP_add_tunnel (peer); | ||
1870 | t = GCP_get_tunnel (peer); | ||
1871 | |||
1872 | if (GCP_get_short_id (peer) == myid) | ||
1873 | { | ||
1874 | GCT_change_cstate (t, CADET_TUNNEL_READY); | ||
1875 | } | ||
1876 | else | ||
1877 | { | ||
1878 | /* FIXME change to a tunnel API, eliminate ch <-> peer connection */ | ||
1879 | GCP_connect (peer); | ||
1880 | } | ||
1881 | |||
1882 | /* Create channel */ | ||
1883 | ch = channel_new (t, c, ccn); | ||
1884 | if (NULL == ch) | ||
1885 | { | ||
1886 | GNUNET_break (0); | ||
1887 | return GNUNET_SYSERR; | ||
1888 | } | ||
1889 | ch->port = msg->port; | ||
1890 | channel_set_options (ch, ntohl (msg->opt)); | ||
1891 | |||
1892 | /* In unreliable channels, we'll use the DLL to buffer BCK data */ | ||
1893 | ch->root_rel = GNUNET_new (struct CadetChannelReliability); | ||
1894 | ch->root_rel->ch = ch; | ||
1895 | ch->root_rel->retry_timer = CADET_RETRANSMIT_TIME; | ||
1896 | ch->root_rel->expected_delay.rel_value_us = 0; | ||
1897 | |||
1898 | LOG (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s\n", GCCH_2s (ch)); | ||
1899 | |||
1900 | send_create (ch); | ||
1901 | |||
1902 | return GNUNET_OK; | ||
1903 | } | ||
1904 | |||
1905 | |||
1906 | /** | ||
1907 | * Handler for cadet network payload traffic. | ||
1908 | * | ||
1909 | * @param ch Channel for the message. | ||
1910 | * @param msg Unencryted data message. | ||
1911 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
1912 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
1913 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
1914 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
1915 | */ | ||
1916 | void | ||
1917 | GCCH_handle_data (struct CadetChannel *ch, | ||
1918 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
1919 | int fwd) | ||
1920 | { | ||
1921 | struct CadetChannelReliability *rel; | ||
1922 | struct CadetClient *c; | ||
1923 | struct GNUNET_MessageHeader *payload_msg; | ||
1924 | uint32_t mid; | ||
1925 | uint16_t payload_type; | ||
1926 | uint16_t payload_size; | ||
1927 | |||
1928 | /* If this is a remote (non-loopback) channel, find 'fwd'. */ | ||
1929 | if (GNUNET_SYSERR == fwd) | ||
1930 | { | ||
1931 | if (is_loopback (ch)) | ||
1932 | { | ||
1933 | /* It is a loopback channel after all... */ | ||
1934 | GNUNET_break (0); | ||
1935 | return; | ||
1936 | } | ||
1937 | fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO; | ||
1938 | } | ||
1939 | |||
1940 | /* Initialize FWD/BCK data */ | ||
1941 | c = fwd ? ch->dest : ch->root; | ||
1942 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1943 | |||
1944 | if (NULL == c) | ||
1945 | { | ||
1946 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1947 | return; | ||
1948 | } | ||
1949 | |||
1950 | if (CADET_CHANNEL_READY != ch->state) | ||
1951 | { | ||
1952 | if (GNUNET_NO == fwd) | ||
1953 | { | ||
1954 | /* If we are the root, this means the other peer has sent traffic before | ||
1955 | * receiving our ACK. Even if the SYNACK goes missing, no traffic should | ||
1956 | * be sent before the ACK. | ||
1957 | */ | ||
1958 | GNUNET_break_op (0); | ||
1959 | return; | ||
1960 | } | ||
1961 | /* If we are the dest, this means that the SYNACK got to the root but | ||
1962 | * the ACK went missing. Treat this as an ACK. | ||
1963 | */ | ||
1964 | channel_confirm (ch, GNUNET_NO); | ||
1965 | } | ||
1966 | |||
1967 | payload_msg = (struct GNUNET_MessageHeader *) &msg[1]; | ||
1968 | payload_type = ntohs (payload_msg->type); | ||
1969 | payload_size = ntohs (payload_msg->size); | ||
1970 | |||
1971 | GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO); | ||
1972 | GNUNET_STATISTICS_update (stats, "# bytes received", payload_size, GNUNET_NO); | ||
1973 | |||
1974 | mid = ntohl (msg->mid); | ||
1975 | LOG (GNUNET_ERROR_TYPE_INFO, "<== %s (%s %4u) on chan %s (%p) %s [%5u]\n", | ||
1976 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA), GC_m2s (payload_type), mid, | ||
1977 | GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size)); | ||
1978 | |||
1979 | if ( (GNUNET_NO == ch->reliable) || | ||
1980 | ( (! GC_is_pid_bigger (rel->mid_recv, mid)) && | ||
1981 | GC_is_pid_bigger (rel->mid_recv + 64, mid) ) ) | ||
1982 | { | ||
1983 | if (GNUNET_YES == ch->reliable) | ||
1984 | { | ||
1985 | /* Is this the exact next expected messasge? */ | ||
1986 | if (mid == rel->mid_recv) | ||
1987 | { | ||
1988 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1989 | "as expected, sending to client\n"); | ||
1990 | send_client_data (ch, msg, fwd); | ||
1991 | } | ||
1992 | else | ||
1993 | { | ||
1994 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1995 | "save for later\n"); | ||
1996 | add_buffered_data (msg, rel); | ||
1997 | } | ||
1998 | } | ||
1999 | else | ||
2000 | { | ||
2001 | /* Tunnel is unreliable: send to clients directly */ | ||
2002 | /* FIXME: accept Out Of Order traffic */ | ||
2003 | rel->mid_recv = mid + 1; | ||
2004 | send_client_data (ch, msg, fwd); | ||
2005 | } | ||
2006 | } | ||
2007 | else | ||
2008 | { | ||
2009 | GNUNET_STATISTICS_update (stats, "# duplicate MID", 1, GNUNET_NO); | ||
2010 | if (GC_is_pid_bigger (rel->mid_recv, mid)) | ||
2011 | { | ||
2012 | GNUNET_break_op (0); | ||
2013 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2014 | "MID %u on channel %s not expected (window: %u - %u). Dropping!\n", | ||
2015 | mid, GCCH_2s (ch), rel->mid_recv, rel->mid_recv + 63); | ||
2016 | } | ||
2017 | else | ||
2018 | { | ||
2019 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2020 | "Duplicate MID %u, channel %s (expecting MID %u). Re-sending ACK!\n", | ||
2021 | mid, GCCH_2s (ch), rel->mid_recv); | ||
2022 | if (NULL != rel->uniq) | ||
2023 | { | ||
2024 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2025 | "We are trying to send an ACK, but don't seem have the " | ||
2026 | "bandwidth. Have you set enough [ats] QUOTA in your config?\n"); | ||
2027 | } | ||
2028 | |||
2029 | } | ||
2030 | } | ||
2031 | |||
2032 | GCCH_send_data_ack (ch, fwd); | ||
2033 | } | ||
2034 | |||
2035 | |||
2036 | /** | ||
2037 | * Handler for cadet network traffic end-to-end ACKs. | ||
2038 | * | ||
2039 | * @param ch Channel on which we got this message. | ||
2040 | * @param msg Data message. | ||
2041 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
2042 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
2043 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
2044 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
2045 | */ | ||
2046 | void | ||
2047 | GCCH_handle_data_ack (struct CadetChannel *ch, | ||
2048 | const struct GNUNET_CADET_ChannelDataAckMessage *msg, | ||
2049 | int fwd) | ||
2050 | { | ||
2051 | struct CadetChannelReliability *rel; | ||
2052 | struct CadetReliableMessage *copy; | ||
2053 | struct CadetReliableMessage *next; | ||
2054 | uint32_t ack; | ||
2055 | int work; | ||
2056 | |||
2057 | /* If this is a remote (non-loopback) channel, find 'fwd'. */ | ||
2058 | if (GNUNET_SYSERR == fwd) | ||
2059 | { | ||
2060 | if (is_loopback (ch)) | ||
2061 | { | ||
2062 | /* It is a loopback channel after all... */ | ||
2063 | GNUNET_break (0); | ||
2064 | return; | ||
2065 | } | ||
2066 | /* Inverted: if message came 'FWD' is a 'BCK ACK'. */ | ||
2067 | fwd = (NULL != ch->dest) ? GNUNET_NO : GNUNET_YES; | ||
2068 | } | ||
2069 | |||
2070 | ack = ntohl (msg->mid); | ||
2071 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2072 | "<== %s (0x%010lX %4u) on chan %s (%p) %s [%5u]\n", | ||
2073 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK), msg->futures, ack, | ||
2074 | GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size)); | ||
2075 | |||
2076 | if (GNUNET_YES == fwd) | ||
2077 | rel = ch->root_rel; | ||
2078 | else | ||
2079 | rel = ch->dest_rel; | ||
2080 | |||
2081 | if (NULL == rel) | ||
2082 | { | ||
2083 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
2084 | return; | ||
2085 | } | ||
2086 | |||
2087 | /* Free ACK'd copies: no need to retransmit those anymore FIXME refactor */ | ||
2088 | for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) | ||
2089 | { | ||
2090 | if (GC_is_pid_bigger (copy->mid, ack)) | ||
2091 | { | ||
2092 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head %u, out!\n", copy->mid); | ||
2093 | if (0 < channel_rel_free_sent (rel, msg)) | ||
2094 | work = GNUNET_YES; | ||
2095 | break; | ||
2096 | } | ||
2097 | work = GNUNET_YES; | ||
2098 | LOG (GNUNET_ERROR_TYPE_DEBUG, " id %u\n", copy->mid); | ||
2099 | next = copy->next; | ||
2100 | if (GNUNET_YES == rel_message_free (copy, GNUNET_YES)) | ||
2101 | { | ||
2102 | LOG (GNUNET_ERROR_TYPE_DEBUG, " channel destoyed\n"); | ||
2103 | return; | ||
2104 | } | ||
2105 | } | ||
2106 | |||
2107 | /* ACK client if needed and possible */ | ||
2108 | GCCH_allow_client (ch, fwd); | ||
2109 | |||
2110 | /* If some message was free'd, update the retransmission delay */ | ||
2111 | if (GNUNET_YES == work) | ||
2112 | { | ||
2113 | if (NULL != rel->retry_task) | ||
2114 | { | ||
2115 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
2116 | rel->retry_task = NULL; | ||
2117 | if (NULL != rel->head_sent && NULL == rel->head_sent->chq) | ||
2118 | { | ||
2119 | struct GNUNET_TIME_Absolute new_target; | ||
2120 | struct GNUNET_TIME_Relative delay; | ||
2121 | |||
2122 | delay = GNUNET_TIME_relative_saturating_multiply (rel->retry_timer, | ||
2123 | CADET_RETRANSMIT_MARGIN); | ||
2124 | new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp, | ||
2125 | delay); | ||
2126 | delay = GNUNET_TIME_absolute_get_remaining (new_target); | ||
2127 | rel->retry_task = | ||
2128 | GNUNET_SCHEDULER_add_delayed (delay, | ||
2129 | &channel_retransmit_message, | ||
2130 | rel); | ||
2131 | } | ||
2132 | } | ||
2133 | else | ||
2134 | { | ||
2135 | /* Work was done but no task was pending. | ||
2136 | * Task was cancelled by a retransmission that is sitting in the queue. | ||
2137 | */ | ||
2138 | // FIXME add test to make sure this is the case, probably add return | ||
2139 | // value to GCCH_send_prebuilt_message | ||
2140 | } | ||
2141 | } | ||
2142 | } | ||
2143 | |||
2144 | |||
2145 | /** | ||
2146 | * Handler for channel create messages. | ||
2147 | * | ||
2148 | * Does not have fwd parameter because it's always 'FWD': channel is incoming. | ||
2149 | * | ||
2150 | * @param t Tunnel this channel will be in. | ||
2151 | * @param msg Channel crate message. | ||
2152 | */ | ||
2153 | struct CadetChannel * | ||
2154 | GCCH_handle_create (struct CadetTunnel *t, | ||
2155 | const struct GNUNET_CADET_ChannelOpenMessage *msg) | ||
2156 | { | ||
2157 | struct GNUNET_CADET_ClientChannelNumber ccn; | ||
2158 | struct GNUNET_CADET_ChannelTunnelNumber gid; | ||
2159 | struct CadetChannel *ch; | ||
2160 | struct CadetClient *c; | ||
2161 | int new_channel; | ||
2162 | const struct GNUNET_HashCode *port; | ||
2163 | |||
2164 | gid = msg->ctn; | ||
2165 | ch = GCT_get_channel (t, gid); | ||
2166 | if (NULL == ch) | ||
2167 | { | ||
2168 | /* Create channel */ | ||
2169 | ccn.channel_of_client = htonl (0); | ||
2170 | ch = channel_new (t, NULL, ccn); | ||
2171 | ch->gid = gid; | ||
2172 | channel_set_options (ch, ntohl (msg->opt)); | ||
2173 | new_channel = GNUNET_YES; | ||
2174 | } | ||
2175 | else | ||
2176 | { | ||
2177 | new_channel = GNUNET_NO; | ||
2178 | } | ||
2179 | port = &msg->port; | ||
2180 | |||
2181 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2182 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", | ||
2183 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN), ccn, port, | ||
2184 | GCCH_2s (ch), ch, GC_f2s (GNUNET_YES), ntohs (msg->header.size)); | ||
2185 | |||
2186 | if (GNUNET_YES == new_channel || GCT_is_loopback (t)) | ||
2187 | { | ||
2188 | /* Find a destination client */ | ||
2189 | ch->port = *port; | ||
2190 | LOG (GNUNET_ERROR_TYPE_DEBUG, " port %s\n", GNUNET_h2s (port)); | ||
2191 | c = GML_client_get_by_port (port); | ||
2192 | if (NULL == c) | ||
2193 | { | ||
2194 | LOG (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n"); | ||
2195 | if (is_loopback (ch)) | ||
2196 | { | ||
2197 | LOG (GNUNET_ERROR_TYPE_DEBUG, " loopback: destroy on handler\n"); | ||
2198 | send_nack (ch); | ||
2199 | } | ||
2200 | else | ||
2201 | { | ||
2202 | LOG (GNUNET_ERROR_TYPE_DEBUG, " not loopback: destroy now\n"); | ||
2203 | send_nack (ch); | ||
2204 | GCCH_destroy (ch); | ||
2205 | } | ||
2206 | return NULL; | ||
2207 | } | ||
2208 | else | ||
2209 | { | ||
2210 | LOG (GNUNET_ERROR_TYPE_DEBUG, " client %p has port registered\n", c); | ||
2211 | } | ||
2212 | |||
2213 | add_destination (ch, c); | ||
2214 | if (GNUNET_YES == ch->reliable) | ||
2215 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Reliable\n"); | ||
2216 | else | ||
2217 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Not Reliable\n"); | ||
2218 | |||
2219 | send_client_create (ch); | ||
2220 | ch->state = CADET_CHANNEL_SENT; | ||
2221 | } | ||
2222 | else | ||
2223 | { | ||
2224 | LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate create channel\n"); | ||
2225 | if (NULL != ch->dest_rel->retry_task) | ||
2226 | { | ||
2227 | LOG (GNUNET_ERROR_TYPE_DEBUG, " clearing retry task\n"); | ||
2228 | /* we were waiting to re-send our 'SYNACK', wait no more! */ | ||
2229 | GNUNET_SCHEDULER_cancel (ch->dest_rel->retry_task); | ||
2230 | ch->dest_rel->retry_task = NULL; | ||
2231 | } | ||
2232 | else if (NULL != ch->dest_rel->uniq) | ||
2233 | { | ||
2234 | /* we are waiting to for our 'SYNACK' to leave the queue, all done! */ | ||
2235 | return ch; | ||
2236 | } | ||
2237 | } | ||
2238 | send_ack (ch, GNUNET_YES); | ||
2239 | |||
2240 | return ch; | ||
2241 | } | ||
2242 | |||
2243 | |||
2244 | /** | ||
2245 | * Handler for channel NACK messages. | ||
2246 | * | ||
2247 | * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter. | ||
2248 | * | ||
2249 | * @param ch Channel. | ||
2250 | */ | ||
2251 | void | ||
2252 | GCCH_handle_nack (struct CadetChannel *ch) | ||
2253 | { | ||
2254 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2255 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", | ||
2256 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED), ch->gid, 0, | ||
2257 | GCCH_2s (ch), ch, "---", 0); | ||
2258 | |||
2259 | send_client_nack (ch); | ||
2260 | GCCH_destroy (ch); | ||
2261 | } | ||
2262 | |||
2263 | |||
2264 | /** | ||
2265 | * Handler for channel ack messages. | ||
2266 | * | ||
2267 | * @param ch Channel. | ||
2268 | * @param msg Message. | ||
2269 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
2270 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
2271 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
2272 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
2273 | */ | ||
2274 | void | ||
2275 | GCCH_handle_ack (struct CadetChannel *ch, | ||
2276 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
2277 | int fwd) | ||
2278 | { | ||
2279 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2280 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", | ||
2281 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK), ch->gid, 0, | ||
2282 | GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size)); | ||
2283 | |||
2284 | /* If this is a remote (non-loopback) channel, find 'fwd'. */ | ||
2285 | if (GNUNET_SYSERR == fwd) | ||
2286 | { | ||
2287 | if (is_loopback (ch)) | ||
2288 | { | ||
2289 | /* It is a loopback channel after all... */ | ||
2290 | GNUNET_break (0); | ||
2291 | return; | ||
2292 | } | ||
2293 | fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO; | ||
2294 | } | ||
2295 | |||
2296 | channel_confirm (ch, !fwd); | ||
2297 | } | ||
2298 | |||
2299 | |||
2300 | /** | ||
2301 | * Handler for channel destroy messages. | ||
2302 | * | ||
2303 | * @param ch Channel to be destroyed of. | ||
2304 | * @param msg Message. | ||
2305 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
2306 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
2307 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
2308 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
2309 | */ | ||
2310 | void | ||
2311 | GCCH_handle_destroy (struct CadetChannel *ch, | ||
2312 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
2313 | int fwd) | ||
2314 | { | ||
2315 | struct CadetChannelReliability *rel; | ||
2316 | |||
2317 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2318 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", | ||
2319 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY), ch->gid, 0, | ||
2320 | GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size)); | ||
2321 | |||
2322 | /* If this is a remote (non-loopback) channel, find 'fwd'. */ | ||
2323 | if (GNUNET_SYSERR == fwd) | ||
2324 | { | ||
2325 | if (is_loopback (ch)) | ||
2326 | { | ||
2327 | /* It is a loopback channel after all... */ | ||
2328 | GNUNET_break (0); | ||
2329 | return; | ||
2330 | } | ||
2331 | fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO; | ||
2332 | } | ||
2333 | |||
2334 | GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG); | ||
2335 | if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) | ||
2336 | { | ||
2337 | /* Not for us (don't destroy twice a half-open loopback channel) */ | ||
2338 | return; | ||
2339 | } | ||
2340 | |||
2341 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
2342 | if (0 == rel->n_recv) | ||
2343 | { | ||
2344 | send_destroy (ch, GNUNET_YES); | ||
2345 | GCCH_destroy (ch); | ||
2346 | } | ||
2347 | else | ||
2348 | { | ||
2349 | ch->destroy = GNUNET_YES; | ||
2350 | } | ||
2351 | } | ||
2352 | |||
2353 | |||
2354 | /** | ||
2355 | * Sends an already built message on a channel. | ||
2356 | * | ||
2357 | * If the channel is on a loopback tunnel, notifies the appropriate destination | ||
2358 | * client locally. | ||
2359 | * | ||
2360 | * On a normal channel passes the message to the tunnel for encryption and | ||
2361 | * sending on a connection. | ||
2362 | * | ||
2363 | * This function DOES NOT save the message for retransmission. | ||
2364 | * | ||
2365 | * @param message Message to send. Function makes a copy of it. | ||
2366 | * @param ch Channel on which this message is transmitted. | ||
2367 | * @param fwd Is this a fwd message? | ||
2368 | * @param existing_copy This is a retransmission, don't save a copy. | ||
2369 | */ | ||
2370 | void | ||
2371 | GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
2372 | struct CadetChannel *ch, int fwd, | ||
2373 | void *existing_copy) | ||
2374 | { | ||
2375 | struct CadetChannelQueue *chq; | ||
2376 | uint32_t data_id; | ||
2377 | uint16_t type; | ||
2378 | uint16_t size; | ||
2379 | char info[32]; | ||
2380 | |||
2381 | type = ntohs (message->type); | ||
2382 | size = ntohs (message->size); | ||
2383 | |||
2384 | data_id = 0; | ||
2385 | switch (type) | ||
2386 | { | ||
2387 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
2388 | { | ||
2389 | struct GNUNET_CADET_ChannelAppDataMessage *data_msg; | ||
2390 | struct GNUNET_MessageHeader *payload_msg; | ||
2391 | uint16_t payload_type; | ||
2392 | |||
2393 | data_msg = (struct GNUNET_CADET_ChannelAppDataMessage *) message; | ||
2394 | data_id = ntohl (data_msg->mid); | ||
2395 | payload_msg = (struct GNUNET_MessageHeader *) &data_msg[1]; | ||
2396 | payload_type = ntohs (payload_msg->type); | ||
2397 | strncpy (info, GC_m2s (payload_type), 31); | ||
2398 | info[31] = '\0'; | ||
2399 | break; | ||
2400 | } | ||
2401 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | ||
2402 | { | ||
2403 | struct GNUNET_CADET_ChannelDataAckMessage *ack_msg; | ||
2404 | ack_msg = (struct GNUNET_CADET_ChannelDataAckMessage *) message; | ||
2405 | data_id = ntohl (ack_msg->mid); | ||
2406 | SPRINTF (info, "0x%010lX", | ||
2407 | (unsigned long int) ack_msg->futures); | ||
2408 | break; | ||
2409 | } | ||
2410 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | ||
2411 | { | ||
2412 | struct GNUNET_CADET_ChannelOpenMessage *cc_msg; | ||
2413 | cc_msg = (struct GNUNET_CADET_ChannelOpenMessage *) message; | ||
2414 | SPRINTF (info, " 0x%08X", ntohl (cc_msg->ctn.cn)); | ||
2415 | break; | ||
2416 | } | ||
2417 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | ||
2418 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED: | ||
2419 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
2420 | { | ||
2421 | struct GNUNET_CADET_ChannelManageMessage *m_msg; | ||
2422 | m_msg = (struct GNUNET_CADET_ChannelManageMessage *) message; | ||
2423 | SPRINTF (info, " 0x%08X", ntohl (m_msg->ctn.cn)); | ||
2424 | break; | ||
2425 | } | ||
2426 | default: | ||
2427 | info[0] = '\0'; | ||
2428 | } | ||
2429 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2430 | "==> %s (%12s %4u) on chan %s (%p) %s [%5u]\n", | ||
2431 | GC_m2s (type), info, data_id, | ||
2432 | GCCH_2s (ch), ch, GC_f2s (fwd), size); | ||
2433 | |||
2434 | if (GCT_is_loopback (ch->t)) | ||
2435 | { | ||
2436 | handle_loopback (ch, message, fwd); | ||
2437 | return; | ||
2438 | } | ||
2439 | |||
2440 | switch (type) | ||
2441 | { | ||
2442 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
2443 | if (GNUNET_YES == ch->reliable) | ||
2444 | { | ||
2445 | chq = GNUNET_new (struct CadetChannelQueue); | ||
2446 | chq->type = type; | ||
2447 | if (NULL == existing_copy) | ||
2448 | chq->copy = channel_save_copy (ch, message, fwd); | ||
2449 | else | ||
2450 | { | ||
2451 | chq->copy = (struct CadetReliableMessage *) existing_copy; | ||
2452 | if (NULL != chq->copy->chq) | ||
2453 | { | ||
2454 | /* Last retransmission was queued but not yet sent! | ||
2455 | * This retransmission was scheduled by a ch_message_sent which | ||
2456 | * followed a very fast RTT, so the tiny delay made the | ||
2457 | * retransmission function to execute before the previous | ||
2458 | * retransmitted message even had a chance to leave the peer. | ||
2459 | * Cancel this message and wait until the pending | ||
2460 | * retransmission leaves the peer and ch_message_sent starts | ||
2461 | * the timer for the next one. | ||
2462 | */ | ||
2463 | GNUNET_free (chq); | ||
2464 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2465 | " exisitng copy not yet transmitted!\n"); | ||
2466 | return; | ||
2467 | } | ||
2468 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2469 | " using existing copy: %p {r:%p q:%p t:%u}\n", | ||
2470 | existing_copy, | ||
2471 | chq->copy->rel, chq->copy->chq, chq->copy->type); | ||
2472 | } | ||
2473 | LOG (GNUNET_ERROR_TYPE_DEBUG, " new chq: %p\n", chq); | ||
2474 | chq->copy->chq = chq; | ||
2475 | chq->tq = GCT_send_prebuilt_message (message, ch->t, NULL, | ||
2476 | GNUNET_YES, | ||
2477 | &ch_message_sent, chq); | ||
2478 | /* q itself is stored in copy */ | ||
2479 | GNUNET_assert (NULL != chq->tq || GNUNET_NO != ch->destroy); | ||
2480 | } | ||
2481 | else | ||
2482 | { | ||
2483 | fire_and_forget (message, ch, GNUNET_NO); | ||
2484 | } | ||
2485 | break; | ||
2486 | |||
2487 | |||
2488 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | ||
2489 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | ||
2490 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | ||
2491 | chq = GNUNET_new (struct CadetChannelQueue); | ||
2492 | chq->type = type; | ||
2493 | chq->rel = fwd ? ch->root_rel : ch->dest_rel; | ||
2494 | if (NULL != chq->rel->uniq) | ||
2495 | { | ||
2496 | if (NULL != chq->rel->uniq->tq) | ||
2497 | { | ||
2498 | GCT_cancel (chq->rel->uniq->tq); | ||
2499 | /* ch_message_sent is called, freeing and NULLing uniq */ | ||
2500 | GNUNET_break (NULL == chq->rel->uniq); | ||
2501 | } | ||
2502 | else | ||
2503 | { | ||
2504 | GNUNET_break (0); | ||
2505 | GNUNET_free (chq->rel->uniq); | ||
2506 | } | ||
2507 | } | ||
2508 | |||
2509 | chq->rel->uniq = chq; | ||
2510 | chq->tq = GCT_send_prebuilt_message (message, ch->t, NULL, GNUNET_YES, | ||
2511 | &ch_message_sent, chq); | ||
2512 | if (NULL == chq->tq) | ||
2513 | { | ||
2514 | GNUNET_break (0); | ||
2515 | chq->rel->uniq = NULL; | ||
2516 | GCT_debug (ch->t, GNUNET_ERROR_TYPE_ERROR); | ||
2517 | GNUNET_free (chq); | ||
2518 | chq = NULL; | ||
2519 | return; | ||
2520 | } | ||
2521 | break; | ||
2522 | |||
2523 | |||
2524 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | ||
2525 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED: | ||
2526 | fire_and_forget (message, ch, GNUNET_YES); | ||
2527 | break; | ||
2528 | |||
2529 | |||
2530 | default: | ||
2531 | GNUNET_break (0); | ||
2532 | LOG (GNUNET_ERROR_TYPE_WARNING, "type %s unknown!\n", GC_m2s (type)); | ||
2533 | fire_and_forget (message, ch, GNUNET_YES); | ||
2534 | } | ||
2535 | } | ||
2536 | |||
2537 | |||
2538 | /** | ||
2539 | * Get the static string for identification of the channel. | ||
2540 | * | ||
2541 | * @param ch Channel. | ||
2542 | * | ||
2543 | * @return Static string with the channel IDs. | ||
2544 | */ | ||
2545 | const char * | ||
2546 | GCCH_2s (const struct CadetChannel *ch) | ||
2547 | { | ||
2548 | static char buf[64]; | ||
2549 | |||
2550 | if (NULL == ch) | ||
2551 | return "(NULL Channel)"; | ||
2552 | |||
2553 | SPRINTF (buf, | ||
2554 | "%s:%s gid:%X (%X / %X)", | ||
2555 | GCT_2s (ch->t), | ||
2556 | GNUNET_h2s (&ch->port), | ||
2557 | ntohl (ch->gid.cn), | ||
2558 | ntohl (ch->lid_root.channel_of_client), | ||
2559 | ntohl (ch->lid_dest.channel_of_client)); | ||
2560 | |||
2561 | return buf; | ||
2562 | } | ||