diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-01-25 13:51:39 +0100 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-01-25 13:51:39 +0100 |
commit | 59d393a1124cfd1aaffdf994bf6f8a9baaac8361 (patch) | |
tree | 1c0d9204813ca26d6db0f35c9287f81c2a2efe74 | |
parent | 3cb90c74c5f591fd2541d154a8e7b05a1c2f4539 (diff) | |
parent | f27982470b7d56cd83f5abfc1befa69bc20d952b (diff) | |
download | gnunet-59d393a1124cfd1aaffdf994bf6f8a9baaac8361.tar.gz gnunet-59d393a1124cfd1aaffdf994bf6f8a9baaac8361.zip |
Merge remote-tracking branch 'origin/master' into credentials
53 files changed, 3930 insertions, 1889 deletions
diff --git a/src/ats-tests/.gitignore b/src/ats-tests/.gitignore index 800898bf9..5e15db496 100644 --- a/src/ats-tests/.gitignore +++ b/src/ats-tests/.gitignore | |||
@@ -6,3 +6,9 @@ perf_ats_proportional_core_none | |||
6 | perf_ats_proportional_transport_bandwidth | 6 | perf_ats_proportional_transport_bandwidth |
7 | perf_ats_proportional_transport_latency | 7 | perf_ats_proportional_transport_latency |
8 | perf_ats_proportional_transport_none | 8 | perf_ats_proportional_transport_none |
9 | perf_ats_mlp_core_bandwidth | ||
10 | perf_ats_mlp_core_latency | ||
11 | perf_ats_mlp_core_none | ||
12 | perf_ats_mlp_transport_bandwidth | ||
13 | perf_ats_mlp_transport_latency | ||
14 | perf_ats_mlp_transport_none | ||
diff --git a/src/cadet/cadet.conf.in b/src/cadet/cadet.conf.in index 88f49fde8..48fd03329 100644 --- a/src/cadet/cadet.conf.in +++ b/src/cadet/cadet.conf.in | |||
@@ -4,6 +4,7 @@ AUTOSTART = @AUTOSTART@ | |||
4 | @JAVAPORT@PORT = 2096 | 4 | @JAVAPORT@PORT = 2096 |
5 | HOSTNAME = localhost | 5 | HOSTNAME = localhost |
6 | BINARY = gnunet-service-cadet | 6 | BINARY = gnunet-service-cadet |
7 | # PREFIX = valgrind --leak-check=yes | ||
7 | ACCEPT_FROM = 127.0.0.1; | 8 | ACCEPT_FROM = 127.0.0.1; |
8 | ACCEPT_FROM6 = ::1; | 9 | ACCEPT_FROM6 = ::1; |
9 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock | 10 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock |
diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h index c16fb2917..451d1f354 100644 --- a/src/cadet/cadet.h +++ b/src/cadet/cadet.h | |||
@@ -68,7 +68,7 @@ extern "C" | |||
68 | /** | 68 | /** |
69 | * Minimum value for channel IDs of local clients. | 69 | * Minimum value for channel IDs of local clients. |
70 | */ | 70 | */ |
71 | #define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI 0x80000000 | 71 | #define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI 0x80000000U |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * FIXME. | 74 | * FIXME. |
@@ -135,10 +135,10 @@ struct GNUNET_CADET_PortMessage | |||
135 | /** | 135 | /** |
136 | * Message for a client to create channels. | 136 | * Message for a client to create channels. |
137 | */ | 137 | */ |
138 | struct GNUNET_CADET_ChannelOpenMessageMessage | 138 | struct GNUNET_CADET_LocalChannelCreateMessage |
139 | { | 139 | { |
140 | /** | 140 | /** |
141 | * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_TUNNEL_CREATE | 141 | * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE |
142 | * | 142 | * |
143 | * Size: sizeof(struct GNUNET_CADET_ChannelOpenMessageMessage) | 143 | * Size: sizeof(struct GNUNET_CADET_ChannelOpenMessageMessage) |
144 | */ | 144 | */ |
@@ -147,7 +147,7 @@ struct GNUNET_CADET_ChannelOpenMessageMessage | |||
147 | /** | 147 | /** |
148 | * ID of a channel controlled by this client. | 148 | * ID of a channel controlled by this client. |
149 | */ | 149 | */ |
150 | struct GNUNET_CADET_ClientChannelNumber channel_id; | 150 | struct GNUNET_CADET_ClientChannelNumber ccn; |
151 | 151 | ||
152 | /** | 152 | /** |
153 | * Channel's peer | 153 | * Channel's peer |
@@ -167,21 +167,19 @@ struct GNUNET_CADET_ChannelOpenMessageMessage | |||
167 | 167 | ||
168 | 168 | ||
169 | /** | 169 | /** |
170 | * Message for a client to destroy channels. | 170 | * Message for or to a client to destroy tunnel. |
171 | */ | 171 | */ |
172 | struct GNUNET_CADET_ChannelDestroyMessage | 172 | struct GNUNET_CADET_LocalChannelDestroyMessage |
173 | { | 173 | { |
174 | /** | 174 | /** |
175 | * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_TUNNEL_DESTROY | 175 | * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY |
176 | * | ||
177 | * Size: sizeof(struct GNUNET_CADET_ChannelDestroyMessage) | ||
178 | */ | 176 | */ |
179 | struct GNUNET_MessageHeader header; | 177 | struct GNUNET_MessageHeader header; |
180 | 178 | ||
181 | /** | 179 | /** |
182 | * ID of a channel controlled by this client. | 180 | * ID of a channel controlled by this client. |
183 | */ | 181 | */ |
184 | struct GNUNET_CADET_ClientChannelNumber channel_id; | 182 | struct GNUNET_CADET_ClientChannelNumber ccn; |
185 | }; | 183 | }; |
186 | 184 | ||
187 | 185 | ||
@@ -198,7 +196,7 @@ struct GNUNET_CADET_LocalData | |||
198 | /** | 196 | /** |
199 | * ID of the channel | 197 | * ID of the channel |
200 | */ | 198 | */ |
201 | struct GNUNET_CADET_ClientChannelNumber id; | 199 | struct GNUNET_CADET_ClientChannelNumber ccn; |
202 | 200 | ||
203 | /** | 201 | /** |
204 | * Payload follows | 202 | * Payload follows |
@@ -220,13 +218,15 @@ struct GNUNET_CADET_LocalAck | |||
220 | /** | 218 | /** |
221 | * ID of the channel allowed to send more data. | 219 | * ID of the channel allowed to send more data. |
222 | */ | 220 | */ |
223 | struct GNUNET_CADET_ClientChannelNumber channel_id; | 221 | struct GNUNET_CADET_ClientChannelNumber ccn; |
224 | 222 | ||
225 | }; | 223 | }; |
226 | 224 | ||
227 | 225 | ||
228 | /** | 226 | /** |
229 | * Message to inform the client about channels in the service. | 227 | * Message to inform the client about channels in the service. |
228 | * | ||
229 | * TODO: split into two messages! | ||
230 | */ | 230 | */ |
231 | struct GNUNET_CADET_LocalInfo | 231 | struct GNUNET_CADET_LocalInfo |
232 | { | 232 | { |
@@ -239,12 +239,7 @@ struct GNUNET_CADET_LocalInfo | |||
239 | /** | 239 | /** |
240 | * ID of the channel allowed to send more data. | 240 | * ID of the channel allowed to send more data. |
241 | */ | 241 | */ |
242 | struct GNUNET_CADET_ClientChannelNumber channel_id; | 242 | struct GNUNET_CADET_ClientChannelNumber ccn; |
243 | |||
244 | /** | ||
245 | * ID of the owner of the channel (can be local peer). | ||
246 | */ | ||
247 | // struct GNUNET_PeerIdentity owner; | ||
248 | 243 | ||
249 | /** | 244 | /** |
250 | * ID of the destination of the channel (can be local peer). | 245 | * ID of the destination of the channel (can be local peer). |
@@ -255,6 +250,8 @@ struct GNUNET_CADET_LocalInfo | |||
255 | 250 | ||
256 | /** | 251 | /** |
257 | * Message to inform the client about one of the peers in the service. | 252 | * Message to inform the client about one of the peers in the service. |
253 | * | ||
254 | * TODO: split into two messages! | ||
258 | */ | 255 | */ |
259 | struct GNUNET_CADET_LocalInfoPeer | 256 | struct GNUNET_CADET_LocalInfoPeer |
260 | { | 257 | { |
@@ -286,6 +283,8 @@ struct GNUNET_CADET_LocalInfoPeer | |||
286 | 283 | ||
287 | /** | 284 | /** |
288 | * Message to inform the client about one of the tunnels in the service. | 285 | * Message to inform the client about one of the tunnels in the service. |
286 | * | ||
287 | * TODO: split into two messages! | ||
289 | */ | 288 | */ |
290 | struct GNUNET_CADET_LocalInfoTunnel | 289 | struct GNUNET_CADET_LocalInfoTunnel |
291 | { | 290 | { |
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c index 8f1274d63..72b7b692d 100644 --- a/src/cadet/cadet_api.c +++ b/src/cadet/cadet_api.c | |||
@@ -169,7 +169,7 @@ struct GNUNET_CADET_Handle | |||
169 | /** | 169 | /** |
170 | * child of the next channel to create (to avoid reusing IDs often) | 170 | * child of the next channel to create (to avoid reusing IDs often) |
171 | */ | 171 | */ |
172 | struct GNUNET_CADET_ClientChannelNumber next_chid; | 172 | struct GNUNET_CADET_ClientChannelNumber next_ccn; |
173 | 173 | ||
174 | /** | 174 | /** |
175 | * Configuration given by the client, in case of reconnection | 175 | * Configuration given by the client, in case of reconnection |
@@ -238,7 +238,7 @@ struct GNUNET_CADET_Channel | |||
238 | /** | 238 | /** |
239 | * Local ID of the channel | 239 | * Local ID of the channel |
240 | */ | 240 | */ |
241 | struct GNUNET_CADET_ClientChannelNumber chid; | 241 | struct GNUNET_CADET_ClientChannelNumber ccn; |
242 | 242 | ||
243 | /** | 243 | /** |
244 | * Channel's port, if any. | 244 | * Channel's port, if any. |
@@ -256,11 +256,6 @@ struct GNUNET_CADET_Channel | |||
256 | void *ctx; | 256 | void *ctx; |
257 | 257 | ||
258 | /** | 258 | /** |
259 | * Size of packet queued in this channel | ||
260 | */ | ||
261 | unsigned int packet_size; | ||
262 | |||
263 | /** | ||
264 | * Channel options: reliability, etc. | 259 | * Channel options: reliability, etc. |
265 | */ | 260 | */ |
266 | enum GNUNET_CADET_ChannelOption options; | 261 | enum GNUNET_CADET_ChannelOption options; |
@@ -268,7 +263,7 @@ struct GNUNET_CADET_Channel | |||
268 | /** | 263 | /** |
269 | * Are we allowed to send to the service? | 264 | * Are we allowed to send to the service? |
270 | */ | 265 | */ |
271 | int allow_send; | 266 | unsigned int allow_send; |
272 | 267 | ||
273 | }; | 268 | }; |
274 | 269 | ||
@@ -361,17 +356,17 @@ find_port (const struct GNUNET_CADET_Handle *h, | |||
361 | * Get the channel handler for the channel specified by id from the given handle | 356 | * Get the channel handler for the channel specified by id from the given handle |
362 | * | 357 | * |
363 | * @param h Cadet handle | 358 | * @param h Cadet handle |
364 | * @param chid ID of the wanted channel | 359 | * @param ccn ID of the wanted channel |
365 | * @return handle to the required channel or NULL if not found | 360 | * @return handle to the required channel or NULL if not found |
366 | */ | 361 | */ |
367 | static struct GNUNET_CADET_Channel * | 362 | static struct GNUNET_CADET_Channel * |
368 | retrieve_channel (struct GNUNET_CADET_Handle *h, | 363 | retrieve_channel (struct GNUNET_CADET_Handle *h, |
369 | struct GNUNET_CADET_ClientChannelNumber chid) | 364 | struct GNUNET_CADET_ClientChannelNumber ccn) |
370 | { | 365 | { |
371 | struct GNUNET_CADET_Channel *ch; | 366 | struct GNUNET_CADET_Channel *ch; |
372 | 367 | ||
373 | for (ch = h->channels_head; NULL != ch; ch = ch->next) | 368 | for (ch = h->channels_head; NULL != ch; ch = ch->next) |
374 | if (ch->chid.channel_of_client == chid.channel_of_client) | 369 | if (ch->ccn.channel_of_client == ccn.channel_of_client) |
375 | return ch; | 370 | return ch; |
376 | return NULL; | 371 | return NULL; |
377 | } | 372 | } |
@@ -381,13 +376,13 @@ retrieve_channel (struct GNUNET_CADET_Handle *h, | |||
381 | * Create a new channel and insert it in the channel list of the cadet handle | 376 | * Create a new channel and insert it in the channel list of the cadet handle |
382 | * | 377 | * |
383 | * @param h Cadet handle | 378 | * @param h Cadet handle |
384 | * @param chid Desired chid of the channel, 0 to assign one automatically. | 379 | * @param ccn Desired ccn of the channel, 0 to assign one automatically. |
385 | * | 380 | * |
386 | * @return Handle to the created channel. | 381 | * @return Handle to the created channel. |
387 | */ | 382 | */ |
388 | static struct GNUNET_CADET_Channel * | 383 | static struct GNUNET_CADET_Channel * |
389 | create_channel (struct GNUNET_CADET_Handle *h, | 384 | create_channel (struct GNUNET_CADET_Handle *h, |
390 | struct GNUNET_CADET_ClientChannelNumber chid) | 385 | struct GNUNET_CADET_ClientChannelNumber ccn) |
391 | { | 386 | { |
392 | struct GNUNET_CADET_Channel *ch; | 387 | struct GNUNET_CADET_Channel *ch; |
393 | 388 | ||
@@ -396,24 +391,23 @@ create_channel (struct GNUNET_CADET_Handle *h, | |||
396 | h->channels_tail, | 391 | h->channels_tail, |
397 | ch); | 392 | ch); |
398 | ch->cadet = h; | 393 | ch->cadet = h; |
399 | if (0 == chid.channel_of_client) | 394 | if (0 == ccn.channel_of_client) |
400 | { | 395 | { |
401 | ch->chid = h->next_chid; | 396 | ch->ccn = h->next_ccn; |
402 | while (NULL != retrieve_channel (h, | 397 | while (NULL != retrieve_channel (h, |
403 | h->next_chid)) | 398 | h->next_ccn)) |
404 | { | 399 | { |
405 | h->next_chid.channel_of_client | 400 | h->next_ccn.channel_of_client |
406 | = htonl (1 + ntohl (h->next_chid.channel_of_client)); | 401 | = htonl (1 + ntohl (h->next_ccn.channel_of_client)); |
407 | if (0 == ntohl (h->next_chid.channel_of_client)) | 402 | if (0 == ntohl (h->next_ccn.channel_of_client)) |
408 | h->next_chid.channel_of_client | 403 | h->next_ccn.channel_of_client |
409 | = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | 404 | = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); |
410 | } | 405 | } |
411 | } | 406 | } |
412 | else | 407 | else |
413 | { | 408 | { |
414 | ch->chid = chid; | 409 | ch->ccn = ccn; |
415 | } | 410 | } |
416 | ch->allow_send = GNUNET_NO; | ||
417 | return ch; | 411 | return ch; |
418 | } | 412 | } |
419 | 413 | ||
@@ -432,29 +426,35 @@ create_channel (struct GNUNET_CADET_Handle *h, | |||
432 | */ | 426 | */ |
433 | // FIXME: simplify: call_cleaner is always #GNUNET_YES!!! | 427 | // FIXME: simplify: call_cleaner is always #GNUNET_YES!!! |
434 | static void | 428 | static void |
435 | destroy_channel (struct GNUNET_CADET_Channel *ch, int call_cleaner) | 429 | destroy_channel (struct GNUNET_CADET_Channel *ch, |
430 | int call_cleaner) | ||
436 | { | 431 | { |
437 | struct GNUNET_CADET_Handle *h; | 432 | struct GNUNET_CADET_Handle *h; |
438 | struct GNUNET_CADET_TransmitHandle *th; | 433 | struct GNUNET_CADET_TransmitHandle *th; |
439 | struct GNUNET_CADET_TransmitHandle *next; | 434 | struct GNUNET_CADET_TransmitHandle *next; |
440 | 435 | ||
441 | LOG (GNUNET_ERROR_TYPE_DEBUG, " destroy_channel %X\n", ch->chid); | ||
442 | |||
443 | if (NULL == ch) | 436 | if (NULL == ch) |
444 | { | 437 | { |
445 | GNUNET_break (0); | 438 | GNUNET_break (0); |
446 | return; | 439 | return; |
447 | } | 440 | } |
448 | h = ch->cadet; | 441 | h = ch->cadet; |
442 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
443 | " destroy_channel %X of %p\n", | ||
444 | ch->ccn, | ||
445 | h); | ||
449 | 446 | ||
450 | GNUNET_CONTAINER_DLL_remove (h->channels_head, | 447 | GNUNET_CONTAINER_DLL_remove (h->channels_head, |
451 | h->channels_tail, | 448 | h->channels_tail, |
452 | ch); | 449 | ch); |
453 | 450 | ||
454 | /* signal channel destruction */ | 451 | /* signal channel destruction */ |
455 | if ( (NULL != h->cleaner) && (0 != ch->peer) && (GNUNET_YES == call_cleaner) ) | 452 | if ( (NULL != h->cleaner) && |
453 | (0 != ch->peer) && | ||
454 | (GNUNET_YES == call_cleaner) ) | ||
456 | { | 455 | { |
457 | LOG (GNUNET_ERROR_TYPE_DEBUG, " calling cleaner\n"); | 456 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
457 | " calling cleaner\n"); | ||
458 | h->cleaner (h->cls, ch, ch->ctx); | 458 | h->cleaner (h->cls, ch, ch->ctx); |
459 | } | 459 | } |
460 | 460 | ||
@@ -475,7 +475,6 @@ destroy_channel (struct GNUNET_CADET_Channel *ch, int call_cleaner) | |||
475 | if (0 != ch->peer) | 475 | if (0 != ch->peer) |
476 | GNUNET_PEER_change_rc (ch->peer, -1); | 476 | GNUNET_PEER_change_rc (ch->peer, -1); |
477 | GNUNET_free (ch); | 477 | GNUNET_free (ch); |
478 | |||
479 | } | 478 | } |
480 | 479 | ||
481 | 480 | ||
@@ -490,7 +489,9 @@ static void | |||
490 | add_to_queue (struct GNUNET_CADET_Handle *h, | 489 | add_to_queue (struct GNUNET_CADET_Handle *h, |
491 | struct GNUNET_CADET_TransmitHandle *th) | 490 | struct GNUNET_CADET_TransmitHandle *th) |
492 | { | 491 | { |
493 | GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th); | 492 | GNUNET_CONTAINER_DLL_insert_tail (h->th_head, |
493 | h->th_tail, | ||
494 | th); | ||
494 | } | 495 | } |
495 | 496 | ||
496 | 497 | ||
@@ -514,29 +515,6 @@ remove_from_queue (struct GNUNET_CADET_TransmitHandle *th) | |||
514 | } | 515 | } |
515 | 516 | ||
516 | 517 | ||
517 | /** | ||
518 | * Send an ack on the channel to confirm the processing of a message. | ||
519 | * | ||
520 | * @param ch Channel on which to send the ACK. | ||
521 | */ | ||
522 | static void | ||
523 | send_ack (struct GNUNET_CADET_Channel *ch) | ||
524 | { | ||
525 | struct GNUNET_CADET_LocalAck *msg; | ||
526 | struct GNUNET_MQ_Envelope *env; | ||
527 | |||
528 | env = GNUNET_MQ_msg (msg, | ||
529 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); | ||
530 | |||
531 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
532 | "Sending ACK on channel %X\n", | ||
533 | ch->chid.channel_of_client); | ||
534 | msg->channel_id = ch->chid; | ||
535 | GNUNET_MQ_send (ch->cadet->mq, | ||
536 | env); | ||
537 | } | ||
538 | |||
539 | |||
540 | 518 | ||
541 | /******************************************************************************/ | 519 | /******************************************************************************/ |
542 | /*********************** RECEIVE HANDLERS ****************************/ | 520 | /*********************** RECEIVE HANDLERS ****************************/ |
@@ -558,22 +536,27 @@ request_data (void *cls) | |||
558 | struct GNUNET_MQ_Envelope *env; | 536 | struct GNUNET_MQ_Envelope *env; |
559 | size_t osize; | 537 | size_t osize; |
560 | 538 | ||
561 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting Data: %u bytes\n", th->size); | 539 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
562 | 540 | "Requesting Data: %u bytes (allow send is %u)\n", | |
563 | GNUNET_assert (GNUNET_YES == th->channel->allow_send); | 541 | th->size, |
564 | th->channel->allow_send = GNUNET_NO; | 542 | th->channel->allow_send); |
543 | |||
544 | GNUNET_assert (0 < th->channel->allow_send); | ||
545 | th->channel->allow_send--; | ||
546 | /* NOTE: we may be allowed to send another packet immediately, | ||
547 | albeit the current logic waits for the ACK. */ | ||
565 | th->request_data_task = NULL; | 548 | th->request_data_task = NULL; |
566 | th->channel->packet_size = 0; | ||
567 | remove_from_queue (th); | 549 | remove_from_queue (th); |
568 | 550 | ||
569 | env = GNUNET_MQ_msg_extra (msg, | 551 | env = GNUNET_MQ_msg_extra (msg, |
570 | th->size, | 552 | th->size, |
571 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); | 553 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); |
572 | msg->id = th->channel->chid; | 554 | msg->ccn = th->channel->ccn; |
573 | osize = th->notify (th->notify_cls, | 555 | osize = th->notify (th->notify_cls, |
574 | th->size, | 556 | th->size, |
575 | &msg[1]); | 557 | &msg[1]); |
576 | GNUNET_assert (osize == th->size); | 558 | GNUNET_assert (osize == th->size); |
559 | |||
577 | GNUNET_MQ_send (th->channel->cadet->mq, | 560 | GNUNET_MQ_send (th->channel->cadet->mq, |
578 | env); | 561 | env); |
579 | GNUNET_free (th); | 562 | GNUNET_free (th); |
@@ -588,55 +571,59 @@ request_data (void *cls) | |||
588 | */ | 571 | */ |
589 | static void | 572 | static void |
590 | handle_channel_created (void *cls, | 573 | handle_channel_created (void *cls, |
591 | const struct GNUNET_CADET_ChannelOpenMessageMessage *msg) | 574 | const struct GNUNET_CADET_LocalChannelCreateMessage *msg) |
592 | { | 575 | { |
593 | struct GNUNET_CADET_Handle *h = cls; | 576 | struct GNUNET_CADET_Handle *h = cls; |
594 | struct GNUNET_CADET_Channel *ch; | 577 | struct GNUNET_CADET_Channel *ch; |
595 | struct GNUNET_CADET_Port *port; | 578 | struct GNUNET_CADET_Port *port; |
596 | const struct GNUNET_HashCode *port_number; | 579 | const struct GNUNET_HashCode *port_number; |
597 | struct GNUNET_CADET_ClientChannelNumber chid; | 580 | struct GNUNET_CADET_ClientChannelNumber ccn; |
598 | 581 | ||
599 | chid = msg->channel_id; | 582 | ccn = msg->ccn; |
600 | port_number = &msg->port; | 583 | port_number = &msg->port; |
601 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 584 | if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
602 | "Creating incoming channel %X [%s]\n", | ||
603 | ntohl (chid.channel_of_client), | ||
604 | GNUNET_h2s (port_number)); | ||
605 | if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
606 | { | 585 | { |
607 | GNUNET_break (0); | 586 | GNUNET_break (0); |
608 | return; | 587 | return; |
609 | } | 588 | } |
610 | port = find_port (h, port_number); | 589 | port = find_port (h, port_number); |
611 | if (NULL != port) | 590 | if (NULL == port) |
612 | { | ||
613 | void *ctx; | ||
614 | |||
615 | ch = create_channel (h, chid); | ||
616 | ch->allow_send = GNUNET_NO; | ||
617 | ch->peer = GNUNET_PEER_intern (&msg->peer); | ||
618 | ch->cadet = h; | ||
619 | ch->chid = chid; | ||
620 | ch->port = port; | ||
621 | ch->options = ntohl (msg->opt); | ||
622 | |||
623 | LOG (GNUNET_ERROR_TYPE_DEBUG, " created channel %p\n", ch); | ||
624 | ctx = port->handler (port->cls, ch, &msg->peer, port->hash, ch->options); | ||
625 | if (NULL != ctx) | ||
626 | ch->ctx = ctx; | ||
627 | LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n"); | ||
628 | } | ||
629 | else | ||
630 | { | 591 | { |
631 | struct GNUNET_CADET_ChannelDestroyMessage *d_msg; | 592 | struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg; |
632 | struct GNUNET_MQ_Envelope *env; | 593 | struct GNUNET_MQ_Envelope *env; |
633 | 594 | ||
634 | LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming channels\n"); | 595 | GNUNET_break (0); |
635 | env = GNUNET_MQ_msg (d_msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | 596 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
636 | d_msg->channel_id = msg->channel_id; | 597 | "No handler for incoming channel %X [%s]\n", |
637 | GNUNET_MQ_send (h->mq, env); | 598 | ntohl (ccn.channel_of_client), |
599 | GNUNET_h2s (port_number)); | ||
600 | /* FIXME: should disconnect instead, this is a serious error! */ | ||
601 | env = GNUNET_MQ_msg (d_msg, | ||
602 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY); | ||
603 | d_msg->ccn = msg->ccn; | ||
604 | GNUNET_MQ_send (h->mq, | ||
605 | env); | ||
606 | return; | ||
638 | } | 607 | } |
639 | return; | 608 | |
609 | ch = create_channel (h, | ||
610 | ccn); | ||
611 | ch->peer = GNUNET_PEER_intern (&msg->peer); | ||
612 | ch->cadet = h; | ||
613 | ch->ccn = ccn; | ||
614 | ch->port = port; | ||
615 | ch->options = ntohl (msg->opt); | ||
616 | |||
617 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
618 | "Creating incoming channel %X [%s] %p\n", | ||
619 | ntohl (ccn.channel_of_client), | ||
620 | GNUNET_h2s (port_number), | ||
621 | ch); | ||
622 | ch->ctx = port->handler (port->cls, | ||
623 | ch, | ||
624 | &msg->peer, | ||
625 | port->hash, | ||
626 | ch->options); | ||
640 | } | 627 | } |
641 | 628 | ||
642 | 629 | ||
@@ -648,24 +635,24 @@ handle_channel_created (void *cls, | |||
648 | */ | 635 | */ |
649 | static void | 636 | static void |
650 | handle_channel_destroy (void *cls, | 637 | handle_channel_destroy (void *cls, |
651 | const struct GNUNET_CADET_ChannelDestroyMessage *msg) | 638 | const struct GNUNET_CADET_LocalChannelDestroyMessage *msg) |
652 | { | 639 | { |
653 | struct GNUNET_CADET_Handle *h = cls; | 640 | struct GNUNET_CADET_Handle *h = cls; |
654 | struct GNUNET_CADET_Channel *ch; | 641 | struct GNUNET_CADET_Channel *ch; |
655 | struct GNUNET_CADET_ClientChannelNumber chid; | 642 | struct GNUNET_CADET_ClientChannelNumber ccn; |
656 | 643 | ||
657 | chid = msg->channel_id; | 644 | ccn = msg->ccn; |
658 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 645 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
659 | "Channel %X Destroy from service\n", | 646 | "Channel %X Destroy from service\n", |
660 | ntohl (chid.channel_of_client)); | 647 | ntohl (ccn.channel_of_client)); |
661 | ch = retrieve_channel (h, | 648 | ch = retrieve_channel (h, |
662 | chid); | 649 | ccn); |
663 | 650 | ||
664 | if (NULL == ch) | 651 | if (NULL == ch) |
665 | { | 652 | { |
666 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 653 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
667 | "channel %X unknown\n", | 654 | "channel %X unknown\n", |
668 | ntohl (chid.channel_of_client)); | 655 | ntohl (ccn.channel_of_client)); |
669 | return; | 656 | return; |
670 | } | 657 | } |
671 | destroy_channel (ch, | 658 | destroy_channel (ch, |
@@ -697,7 +684,7 @@ check_local_data (void *cls, | |||
697 | } | 684 | } |
698 | 685 | ||
699 | ch = retrieve_channel (h, | 686 | ch = retrieve_channel (h, |
700 | message->id); | 687 | message->ccn); |
701 | if (NULL == ch) | 688 | if (NULL == ch) |
702 | { | 689 | { |
703 | GNUNET_break_op (0); | 690 | GNUNET_break_op (0); |
@@ -722,45 +709,44 @@ handle_local_data (void *cls, | |||
722 | const struct GNUNET_MessageHeader *payload; | 709 | const struct GNUNET_MessageHeader *payload; |
723 | const struct GNUNET_CADET_MessageHandler *handler; | 710 | const struct GNUNET_CADET_MessageHandler *handler; |
724 | struct GNUNET_CADET_Channel *ch; | 711 | struct GNUNET_CADET_Channel *ch; |
725 | unsigned int i; | ||
726 | uint16_t type; | 712 | uint16_t type; |
727 | 713 | ||
728 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 714 | ch = retrieve_channel (h, |
729 | "Got a data message!\n"); | 715 | message->ccn); |
730 | ch = retrieve_channel (h, message->id); | ||
731 | GNUNET_assert (NULL != ch); | 716 | GNUNET_assert (NULL != ch); |
732 | 717 | ||
733 | payload = (struct GNUNET_MessageHeader *) &message[1]; | 718 | payload = (struct GNUNET_MessageHeader *) &message[1]; |
734 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on channel %s [%X]\n", | 719 | type = ntohs (payload->type); |
735 | GC_f2s (ntohl (ch->chid.channel_of_client) >= | 720 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
721 | "Got a %s data on channel %s [%X] of type %s (%u)\n", | ||
722 | GC_f2s (ntohl (ch->ccn.channel_of_client) >= | ||
736 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI), | 723 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI), |
737 | GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), | 724 | GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), |
738 | ntohl (message->id.channel_of_client)); | 725 | ntohl (message->ccn.channel_of_client), |
739 | 726 | GC_m2s (type), | |
740 | type = ntohs (payload->type); | 727 | type); |
741 | LOG (GNUNET_ERROR_TYPE_DEBUG, " payload type %s\n", GC_m2s (type)); | 728 | for (unsigned i=0;i<h->n_handlers;i++) |
742 | for (i = 0; i < h->n_handlers; i++) | ||
743 | { | 729 | { |
744 | handler = &h->message_handlers[i]; | 730 | handler = &h->message_handlers[i]; |
745 | LOG (GNUNET_ERROR_TYPE_DEBUG, " checking handler for type %u\n", | ||
746 | handler->type); | ||
747 | if (handler->type == type) | 731 | if (handler->type == type) |
748 | { | 732 | { |
749 | if (GNUNET_OK != | 733 | if (GNUNET_OK != |
750 | handler->callback (h->cls, ch, &ch->ctx, payload)) | 734 | handler->callback (h->cls, |
751 | { | 735 | ch, |
752 | LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n"); | 736 | &ch->ctx, |
753 | GNUNET_CADET_channel_destroy (ch); | 737 | payload)) |
754 | break; | ||
755 | } | ||
756 | else | ||
757 | { | 738 | { |
758 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 739 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
759 | "callback completed successfully\n"); | 740 | "callback caused disconnection\n"); |
760 | break; | 741 | GNUNET_CADET_channel_destroy (ch); |
742 | return; | ||
761 | } | 743 | } |
744 | return; | ||
762 | } | 745 | } |
763 | } | 746 | } |
747 | /* Other peer sent message we do not comprehend. */ | ||
748 | GNUNET_break_op (0); | ||
749 | GNUNET_CADET_receive_done (ch); | ||
764 | } | 750 | } |
765 | 751 | ||
766 | 752 | ||
@@ -777,41 +763,33 @@ handle_local_ack (void *cls, | |||
777 | { | 763 | { |
778 | struct GNUNET_CADET_Handle *h = cls; | 764 | struct GNUNET_CADET_Handle *h = cls; |
779 | struct GNUNET_CADET_Channel *ch; | 765 | struct GNUNET_CADET_Channel *ch; |
780 | struct GNUNET_CADET_ClientChannelNumber chid; | 766 | struct GNUNET_CADET_ClientChannelNumber ccn; |
767 | struct GNUNET_CADET_TransmitHandle *th; | ||
781 | 768 | ||
782 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n"); | 769 | ccn = message->ccn; |
783 | chid = message->channel_id; | 770 | ch = retrieve_channel (h, ccn); |
784 | ch = retrieve_channel (h, chid); | ||
785 | if (NULL == ch) | 771 | if (NULL == ch) |
786 | { | 772 | { |
787 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 773 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
788 | "ACK on unknown channel %X\n", | 774 | "ACK on unknown channel %X\n", |
789 | ntohl (chid.channel_of_client)); | 775 | ntohl (ccn.channel_of_client)); |
790 | return; | 776 | return; |
791 | } | 777 | } |
778 | ch->allow_send++; | ||
792 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 779 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
793 | " on channel %X!\n", | 780 | "Got an ACK on channel %X, allow send now %u!\n", |
794 | ntohl (ch->chid.channel_of_client)); | 781 | ntohl (ch->ccn.channel_of_client), |
795 | ch->allow_send = GNUNET_YES; | 782 | ch->allow_send); |
796 | if (0 < ch->packet_size) | 783 | for (th = h->th_head; NULL != th; th = th->next) |
797 | { | 784 | { |
798 | struct GNUNET_CADET_TransmitHandle *th; | 785 | if ( (th->channel == ch) && |
799 | struct GNUNET_CADET_TransmitHandle *next; | 786 | (NULL == th->request_data_task) ) |
800 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
801 | " pending data, sending %u bytes!\n", | ||
802 | ch->packet_size); | ||
803 | for (th = h->th_head; NULL != th; th = next) | ||
804 | { | 787 | { |
805 | next = th->next; | 788 | th->request_data_task |
806 | if (th->channel == ch) | 789 | = GNUNET_SCHEDULER_add_now (&request_data, |
807 | { | 790 | th); |
808 | GNUNET_assert (NULL == th->request_data_task); | 791 | break; |
809 | th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th); | ||
810 | break; | ||
811 | } | ||
812 | } | 792 | } |
813 | /* Complain if we got thru all th without sending anything, ch was wrong */ | ||
814 | GNUNET_break (NULL != th); | ||
815 | } | 793 | } |
816 | } | 794 | } |
817 | 795 | ||
@@ -1273,20 +1251,19 @@ handle_get_tunnel (void *cls, | |||
1273 | * original state. | 1251 | * original state. |
1274 | * | 1252 | * |
1275 | * @param h handle to the cadet | 1253 | * @param h handle to the cadet |
1276 | * | 1254 | * @return #GNUNET_YES in case of success, #GNUNET_NO otherwise (service down...) |
1277 | * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...) | ||
1278 | */ | 1255 | */ |
1279 | static int | 1256 | static int |
1280 | do_reconnect (struct GNUNET_CADET_Handle *h) | 1257 | do_reconnect (struct GNUNET_CADET_Handle *h) |
1281 | { | 1258 | { |
1282 | struct GNUNET_MQ_MessageHandler handlers[] = { | 1259 | struct GNUNET_MQ_MessageHandler handlers[] = { |
1283 | GNUNET_MQ_hd_fixed_size (channel_created, | 1260 | GNUNET_MQ_hd_fixed_size (channel_created, |
1284 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | 1261 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE, |
1285 | struct GNUNET_CADET_ChannelOpenMessageMessage, | 1262 | struct GNUNET_CADET_LocalChannelCreateMessage, |
1286 | h), | 1263 | h), |
1287 | GNUNET_MQ_hd_fixed_size (channel_destroy, | 1264 | GNUNET_MQ_hd_fixed_size (channel_destroy, |
1288 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | 1265 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY, |
1289 | struct GNUNET_CADET_ChannelDestroyMessage, | 1266 | struct GNUNET_CADET_LocalChannelDestroyMessage, |
1290 | h), | 1267 | h), |
1291 | GNUNET_MQ_hd_var_size (local_data, | 1268 | GNUNET_MQ_hd_var_size (local_data, |
1292 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, | 1269 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, |
@@ -1370,7 +1347,7 @@ reconnect (struct GNUNET_CADET_Handle *h) | |||
1370 | 1347 | ||
1371 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1348 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1372 | "Requested RECONNECT, destroying all channels\n"); | 1349 | "Requested RECONNECT, destroying all channels\n"); |
1373 | for (ch = h->channels_head; NULL != ch; ch = h->channels_head) | 1350 | while (NULL != (ch = h->channels_head)) |
1374 | destroy_channel (ch, GNUNET_YES); | 1351 | destroy_channel (ch, GNUNET_YES); |
1375 | if (NULL == h->reconnect_task) | 1352 | if (NULL == h->reconnect_task) |
1376 | h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time, | 1353 | h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time, |
@@ -1390,9 +1367,10 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1390 | { | 1367 | { |
1391 | struct GNUNET_CADET_Handle *h; | 1368 | struct GNUNET_CADET_Handle *h; |
1392 | 1369 | ||
1393 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect()\n"); | ||
1394 | h = GNUNET_new (struct GNUNET_CADET_Handle); | 1370 | h = GNUNET_new (struct GNUNET_CADET_Handle); |
1395 | LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h); | 1371 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1372 | "GNUNET_CADET_connect() %p\n", | ||
1373 | h); | ||
1396 | h->cfg = cfg; | 1374 | h->cfg = cfg; |
1397 | h->cleaner = cleaner; | 1375 | h->cleaner = cleaner; |
1398 | h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES); | 1376 | h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES); |
@@ -1405,7 +1383,7 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1405 | } | 1383 | } |
1406 | h->cls = cls; | 1384 | h->cls = cls; |
1407 | h->message_handlers = handlers; | 1385 | h->message_handlers = handlers; |
1408 | h->next_chid.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | 1386 | h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); |
1409 | h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS; | 1387 | h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS; |
1410 | h->reconnect_task = NULL; | 1388 | h->reconnect_task = NULL; |
1411 | 1389 | ||
@@ -1413,11 +1391,18 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1413 | for (h->n_handlers = 0; | 1391 | for (h->n_handlers = 0; |
1414 | handlers && handlers[h->n_handlers].type; | 1392 | handlers && handlers[h->n_handlers].type; |
1415 | h->n_handlers++) ; | 1393 | h->n_handlers++) ; |
1416 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect() END\n"); | ||
1417 | return h; | 1394 | return h; |
1418 | } | 1395 | } |
1419 | 1396 | ||
1420 | 1397 | ||
1398 | /** | ||
1399 | * Disconnect from the cadet service. All channels will be destroyed. All channel | ||
1400 | * disconnect callbacks will be called on any still connected peers, notifying | ||
1401 | * about their disconnection. The registered inbound channel cleaner will be | ||
1402 | * called should any inbound channels still exist. | ||
1403 | * | ||
1404 | * @param handle connection to cadet to disconnect | ||
1405 | */ | ||
1421 | void | 1406 | void |
1422 | GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) | 1407 | GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) |
1423 | { | 1408 | { |
@@ -1431,12 +1416,12 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) | |||
1431 | while (NULL != ch) | 1416 | while (NULL != ch) |
1432 | { | 1417 | { |
1433 | aux = ch->next; | 1418 | aux = ch->next; |
1434 | if (ntohl (ch->chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 1419 | if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
1435 | { | 1420 | { |
1436 | GNUNET_break (0); | 1421 | GNUNET_break (0); |
1437 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1422 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1438 | "channel %X not destroyed\n", | 1423 | "channel %X not destroyed\n", |
1439 | ntohl (ch->chid.channel_of_client)); | 1424 | ntohl (ch->ccn.channel_of_client)); |
1440 | } | 1425 | } |
1441 | destroy_channel (ch, | 1426 | destroy_channel (ch, |
1442 | GNUNET_YES); | 1427 | GNUNET_YES); |
@@ -1497,7 +1482,6 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) | |||
1497 | * @param port Hash representing the port number. | 1482 | * @param port Hash representing the port number. |
1498 | * @param new_channel Function called when an channel is received. | 1483 | * @param new_channel Function called when an channel is received. |
1499 | * @param new_channel_cls Closure for @a new_channel. | 1484 | * @param new_channel_cls Closure for @a new_channel. |
1500 | * | ||
1501 | * @return Port handle. | 1485 | * @return Port handle. |
1502 | */ | 1486 | */ |
1503 | struct GNUNET_CADET_Port * | 1487 | struct GNUNET_CADET_Port * |
@@ -1565,7 +1549,6 @@ GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p) | |||
1565 | * @param peer peer identity the channel should go to | 1549 | * @param peer peer identity the channel should go to |
1566 | * @param port Port hash (port number). | 1550 | * @param port Port hash (port number). |
1567 | * @param options CadetOption flag field, with all desired option bits set to 1. | 1551 | * @param options CadetOption flag field, with all desired option bits set to 1. |
1568 | * | ||
1569 | * @return handle to the channel | 1552 | * @return handle to the channel |
1570 | */ | 1553 | */ |
1571 | struct GNUNET_CADET_Channel * | 1554 | struct GNUNET_CADET_Channel * |
@@ -1575,28 +1558,28 @@ GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h, | |||
1575 | const struct GNUNET_HashCode *port, | 1558 | const struct GNUNET_HashCode *port, |
1576 | enum GNUNET_CADET_ChannelOption options) | 1559 | enum GNUNET_CADET_ChannelOption options) |
1577 | { | 1560 | { |
1578 | struct GNUNET_CADET_ChannelOpenMessageMessage *msg; | 1561 | struct GNUNET_CADET_LocalChannelCreateMessage *msg; |
1579 | struct GNUNET_MQ_Envelope *env; | 1562 | struct GNUNET_MQ_Envelope *env; |
1580 | struct GNUNET_CADET_Channel *ch; | 1563 | struct GNUNET_CADET_Channel *ch; |
1581 | struct GNUNET_CADET_ClientChannelNumber chid; | 1564 | struct GNUNET_CADET_ClientChannelNumber ccn; |
1582 | 1565 | ||
1583 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1566 | ccn.channel_of_client = htonl (0); |
1584 | "Creating new channel to %s:%u\n", | 1567 | ch = create_channel (h, ccn); |
1585 | GNUNET_i2s (peer), port); | ||
1586 | chid.channel_of_client = htonl (0); | ||
1587 | ch = create_channel (h, chid); | ||
1588 | LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", ch); | ||
1589 | LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", | ||
1590 | ntohl (ch->chid.channel_of_client)); | ||
1591 | ch->ctx = channel_ctx; | 1568 | ch->ctx = channel_ctx; |
1592 | ch->peer = GNUNET_PEER_intern (peer); | 1569 | ch->peer = GNUNET_PEER_intern (peer); |
1593 | 1570 | ||
1594 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 1571 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1595 | msg->channel_id = ch->chid; | 1572 | "Creating new channel to %s:%u at %p number %X\n", |
1573 | GNUNET_i2s (peer), | ||
1574 | port, | ||
1575 | ch, | ||
1576 | ntohl (ch->ccn.channel_of_client)); | ||
1577 | env = GNUNET_MQ_msg (msg, | ||
1578 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); | ||
1579 | msg->ccn = ch->ccn; | ||
1596 | msg->port = *port; | 1580 | msg->port = *port; |
1597 | msg->peer = *peer; | 1581 | msg->peer = *peer; |
1598 | msg->opt = htonl (options); | 1582 | msg->opt = htonl (options); |
1599 | ch->allow_send = GNUNET_NO; | ||
1600 | GNUNET_MQ_send (h->mq, | 1583 | GNUNET_MQ_send (h->mq, |
1601 | env); | 1584 | env); |
1602 | return ch; | 1585 | return ch; |
@@ -1607,12 +1590,13 @@ void | |||
1607 | GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) | 1590 | GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) |
1608 | { | 1591 | { |
1609 | struct GNUNET_CADET_Handle *h; | 1592 | struct GNUNET_CADET_Handle *h; |
1610 | struct GNUNET_CADET_ChannelDestroyMessage *msg; | 1593 | struct GNUNET_CADET_LocalChannelDestroyMessage *msg; |
1611 | struct GNUNET_MQ_Envelope *env; | 1594 | struct GNUNET_MQ_Envelope *env; |
1612 | struct GNUNET_CADET_TransmitHandle *th; | 1595 | struct GNUNET_CADET_TransmitHandle *th; |
1613 | struct GNUNET_CADET_TransmitHandle *next; | 1596 | struct GNUNET_CADET_TransmitHandle *next; |
1614 | 1597 | ||
1615 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying channel\n"); | 1598 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1599 | "Destroying channel\n"); | ||
1616 | h = channel->cadet; | 1600 | h = channel->cadet; |
1617 | for (th = h->th_head; th != NULL; th = next) | 1601 | for (th = h->th_head; th != NULL; th = next) |
1618 | { | 1602 | { |
@@ -1629,18 +1613,24 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) | |||
1629 | } | 1613 | } |
1630 | else | 1614 | else |
1631 | { | 1615 | { |
1632 | LOG (GNUNET_ERROR_TYPE_WARNING, "no meta-traffic should be queued\n"); | 1616 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1617 | "no meta-traffic should be queued\n"); | ||
1633 | } | 1618 | } |
1634 | GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); | 1619 | GNUNET_CONTAINER_DLL_remove (h->th_head, |
1620 | h->th_tail, | ||
1621 | th); | ||
1635 | GNUNET_CADET_notify_transmit_ready_cancel (th); | 1622 | GNUNET_CADET_notify_transmit_ready_cancel (th); |
1636 | } | 1623 | } |
1637 | } | 1624 | } |
1638 | 1625 | ||
1639 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | 1626 | env = GNUNET_MQ_msg (msg, |
1640 | msg->channel_id = channel->chid; | 1627 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY); |
1641 | GNUNET_MQ_send (h->mq, env); | 1628 | msg->ccn = channel->ccn; |
1629 | GNUNET_MQ_send (h->mq, | ||
1630 | env); | ||
1642 | 1631 | ||
1643 | destroy_channel (channel, GNUNET_YES); | 1632 | destroy_channel (channel, |
1633 | GNUNET_YES); | ||
1644 | } | 1634 | } |
1645 | 1635 | ||
1646 | 1636 | ||
@@ -1694,19 +1684,17 @@ GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel, | |||
1694 | struct GNUNET_CADET_TransmitHandle *th; | 1684 | struct GNUNET_CADET_TransmitHandle *th; |
1695 | 1685 | ||
1696 | GNUNET_assert (NULL != channel); | 1686 | GNUNET_assert (NULL != channel); |
1697 | GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size); | ||
1698 | LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY\n"); | ||
1699 | LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", channel->chid); | ||
1700 | LOG (GNUNET_ERROR_TYPE_DEBUG, " allow_send %d\n", channel->allow_send); | ||
1701 | if (ntohl (channel->chid.channel_of_client) >= | ||
1702 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
1703 | LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n"); | ||
1704 | else | ||
1705 | LOG (GNUNET_ERROR_TYPE_DEBUG, " to destination\n"); | ||
1706 | LOG (GNUNET_ERROR_TYPE_DEBUG, " payload size %u\n", notify_size); | ||
1707 | GNUNET_assert (NULL != notify); | 1687 | GNUNET_assert (NULL != notify); |
1708 | GNUNET_assert (0 == channel->packet_size); // Only one data packet allowed | 1688 | GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size); |
1709 | 1689 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
1690 | "CADET NOTIFY TRANSMIT READY on channel %X allow_send is %u to %s with %u bytes\n", | ||
1691 | channel->ccn, | ||
1692 | channel->allow_send, | ||
1693 | (ntohl (channel->ccn.channel_of_client) >= | ||
1694 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
1695 | ? "origin" | ||
1696 | : "destination", | ||
1697 | (unsigned int) notify_size); | ||
1710 | if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us) | 1698 | if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us) |
1711 | { | 1699 | { |
1712 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1700 | LOG (GNUNET_ERROR_TYPE_WARNING, |
@@ -1716,16 +1704,15 @@ GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel, | |||
1716 | th = GNUNET_new (struct GNUNET_CADET_TransmitHandle); | 1704 | th = GNUNET_new (struct GNUNET_CADET_TransmitHandle); |
1717 | th->channel = channel; | 1705 | th->channel = channel; |
1718 | th->size = notify_size; | 1706 | th->size = notify_size; |
1719 | channel->packet_size = th->size; | ||
1720 | LOG (GNUNET_ERROR_TYPE_DEBUG, " total size %u\n", th->size); | ||
1721 | th->notify = notify; | 1707 | th->notify = notify; |
1722 | th->notify_cls = notify_cls; | 1708 | th->notify_cls = notify_cls; |
1723 | if (GNUNET_YES == channel->allow_send) | 1709 | if (0 != channel->allow_send) |
1724 | th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th); | 1710 | th->request_data_task |
1711 | = GNUNET_SCHEDULER_add_now (&request_data, | ||
1712 | th); | ||
1725 | else | 1713 | else |
1726 | add_to_queue (channel->cadet, th); | 1714 | add_to_queue (channel->cadet, |
1727 | 1715 | th); | |
1728 | LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY END\n"); | ||
1729 | return th; | 1716 | return th; |
1730 | } | 1717 | } |
1731 | 1718 | ||
@@ -1736,18 +1723,32 @@ GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *t | |||
1736 | if (NULL != th->request_data_task) | 1723 | if (NULL != th->request_data_task) |
1737 | { | 1724 | { |
1738 | GNUNET_SCHEDULER_cancel (th->request_data_task); | 1725 | GNUNET_SCHEDULER_cancel (th->request_data_task); |
1726 | th->request_data_task = NULL; | ||
1739 | } | 1727 | } |
1740 | th->request_data_task = NULL; | ||
1741 | |||
1742 | remove_from_queue (th); | 1728 | remove_from_queue (th); |
1743 | GNUNET_free (th); | 1729 | GNUNET_free (th); |
1744 | } | 1730 | } |
1745 | 1731 | ||
1746 | 1732 | ||
1733 | /** | ||
1734 | * Send an ack on the channel to confirm the processing of a message. | ||
1735 | * | ||
1736 | * @param ch Channel on which to send the ACK. | ||
1737 | */ | ||
1747 | void | 1738 | void |
1748 | GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel) | 1739 | GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel) |
1749 | { | 1740 | { |
1750 | send_ack (channel); | 1741 | struct GNUNET_CADET_LocalAck *msg; |
1742 | struct GNUNET_MQ_Envelope *env; | ||
1743 | |||
1744 | env = GNUNET_MQ_msg (msg, | ||
1745 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); | ||
1746 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1747 | "Sending ACK on channel %X\n", | ||
1748 | channel->ccn.channel_of_client); | ||
1749 | msg->ccn = channel->ccn; | ||
1750 | GNUNET_MQ_send (channel->cadet->mq, | ||
1751 | env); | ||
1751 | } | 1752 | } |
1752 | 1753 | ||
1753 | 1754 | ||
@@ -1994,7 +1995,7 @@ GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h, | |||
1994 | 1995 | ||
1995 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL); | 1996 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL); |
1996 | msg->peer = *initiator; | 1997 | msg->peer = *initiator; |
1997 | msg->channel_id.channel_of_client = htonl (channel_number); | 1998 | msg->ccn.channel_of_client = htonl (channel_number); |
1998 | GNUNET_MQ_send (h->mq, env); | 1999 | GNUNET_MQ_send (h->mq, env); |
1999 | 2000 | ||
2000 | h->info_cb.channel_cb = callback; | 2001 | h->info_cb.channel_cb = callback; |
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h index cf32e0d6d..5ec34f7d7 100644 --- a/src/cadet/cadet_protocol.h +++ b/src/cadet/cadet_protocol.h | |||
@@ -87,7 +87,7 @@ struct GNUNET_CADET_ConnectionCreateMessage | |||
87 | /** | 87 | /** |
88 | * Message for ack'ing a connection | 88 | * Message for ack'ing a connection |
89 | */ | 89 | */ |
90 | struct GNUNET_CADET_ConnectionCreateMessageAckMessage | 90 | struct GNUNET_CADET_ConnectionCreateAckMessage |
91 | { | 91 | { |
92 | /** | 92 | /** |
93 | * Type: #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK | 93 | * Type: #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK |
@@ -253,10 +253,17 @@ struct GNUNET_CADET_TunnelEncryptedMessage | |||
253 | */ | 253 | */ |
254 | struct GNUNET_MessageHeader header; | 254 | struct GNUNET_MessageHeader header; |
255 | 255 | ||
256 | #if NEW_CADET | ||
256 | /** | 257 | /** |
257 | * ID of the packet (hop by hop). | 258 | * Reserved, for alignment. |
259 | */ | ||
260 | uint32_t reserved GNUNET_PACKED; | ||
261 | #else | ||
262 | /** | ||
263 | * Maximum packet ID authorized. | ||
258 | */ | 264 | */ |
259 | struct CadetEncryptedMessageIdentifier cemi; | 265 | struct CadetEncryptedMessageIdentifier cemi; |
266 | #endif | ||
260 | 267 | ||
261 | /** | 268 | /** |
262 | * ID of the connection. | 269 | * ID of the connection. |
@@ -295,6 +302,8 @@ struct GNUNET_CADET_TunnelEncryptedMessage | |||
295 | }; | 302 | }; |
296 | 303 | ||
297 | 304 | ||
305 | #ifndef NEW_CADET | ||
306 | |||
298 | /** | 307 | /** |
299 | * Message to query a peer about its Flow Control status regarding a tunnel. | 308 | * Message to query a peer about its Flow Control status regarding a tunnel. |
300 | * | 309 | * |
@@ -337,7 +346,7 @@ struct GNUNET_CADET_ConnectionEncryptedAckMessage | |||
337 | /** | 346 | /** |
338 | * Maximum packet ID authorized. | 347 | * Maximum packet ID authorized. |
339 | */ | 348 | */ |
340 | struct CadetEncryptedMessageIdentifier cemi; | 349 | struct CadetEncryptedMessageIdentifier cemi_max; |
341 | 350 | ||
342 | /** | 351 | /** |
343 | * ID of the connection. | 352 | * ID of the connection. |
@@ -345,6 +354,8 @@ struct GNUNET_CADET_ConnectionEncryptedAckMessage | |||
345 | struct GNUNET_CADET_ConnectionTunnelIdentifier cid; | 354 | struct GNUNET_CADET_ConnectionTunnelIdentifier cid; |
346 | }; | 355 | }; |
347 | 356 | ||
357 | #endif | ||
358 | |||
348 | 359 | ||
349 | /******************************************************************************/ | 360 | /******************************************************************************/ |
350 | /******************************* CHANNEL ***********************************/ | 361 | /******************************* CHANNEL ***********************************/ |
@@ -374,17 +385,20 @@ struct GNUNET_CADET_ChannelOpenMessage | |||
374 | /** | 385 | /** |
375 | * ID of the channel within the tunnel. | 386 | * ID of the channel within the tunnel. |
376 | */ | 387 | */ |
377 | struct GNUNET_CADET_ChannelTunnelNumber chid; | 388 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
378 | }; | 389 | }; |
379 | 390 | ||
380 | 391 | ||
381 | /** | 392 | /** |
382 | * Message to manage a Channel (ACK, NACK, Destroy). | 393 | * Message to manage a Channel |
394 | * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, | ||
395 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY). | ||
383 | */ | 396 | */ |
384 | struct GNUNET_CADET_ChannelManageMessage | 397 | struct GNUNET_CADET_ChannelManageMessage |
385 | { | 398 | { |
386 | /** | 399 | /** |
387 | * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_{ACK|NACK|DESTROY} | 400 | * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK or |
401 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY | ||
388 | */ | 402 | */ |
389 | struct GNUNET_MessageHeader header; | 403 | struct GNUNET_MessageHeader header; |
390 | 404 | ||
@@ -398,7 +412,7 @@ struct GNUNET_CADET_ChannelManageMessage | |||
398 | /** | 412 | /** |
399 | * ID of the channel | 413 | * ID of the channel |
400 | */ | 414 | */ |
401 | struct GNUNET_CADET_ChannelTunnelNumber chid; | 415 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
402 | }; | 416 | }; |
403 | 417 | ||
404 | 418 | ||
@@ -424,7 +438,7 @@ struct GNUNET_CADET_ChannelAppDataMessage | |||
424 | /** | 438 | /** |
425 | * ID of the channel | 439 | * ID of the channel |
426 | */ | 440 | */ |
427 | struct GNUNET_CADET_ChannelTunnelNumber chid; | 441 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
428 | 442 | ||
429 | /** | 443 | /** |
430 | * Payload follows | 444 | * Payload follows |
@@ -445,7 +459,7 @@ struct GNUNET_CADET_ChannelDataAckMessage | |||
445 | /** | 459 | /** |
446 | * ID of the channel | 460 | * ID of the channel |
447 | */ | 461 | */ |
448 | struct GNUNET_CADET_ChannelTunnelNumber chid; | 462 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
449 | 463 | ||
450 | /** | 464 | /** |
451 | * Bitfield of already-received newer messages | 465 | * Bitfield of already-received newer messages |
@@ -482,8 +496,7 @@ struct ChannelMessageIdentifier | |||
482 | struct GNUNET_CADET_ChannelAppDataMessage | 496 | struct GNUNET_CADET_ChannelAppDataMessage |
483 | { | 497 | { |
484 | /** | 498 | /** |
485 | * Type: #GNUNET_MESSAGE_TYPE_CADET_UNICAST, | 499 | * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA. |
486 | * #GNUNET_MESSAGE_TYPE_CADET_TO_ORIGIN | ||
487 | */ | 500 | */ |
488 | struct GNUNET_MessageHeader header; | 501 | struct GNUNET_MessageHeader header; |
489 | 502 | ||
@@ -495,7 +508,7 @@ struct GNUNET_CADET_ChannelAppDataMessage | |||
495 | /** | 508 | /** |
496 | * ID of the channel | 509 | * ID of the channel |
497 | */ | 510 | */ |
498 | struct GNUNET_CADET_ChannelTunnelNumber gid; | 511 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
499 | 512 | ||
500 | /** | 513 | /** |
501 | * Payload follows | 514 | * Payload follows |
@@ -516,7 +529,7 @@ struct GNUNET_CADET_ChannelDataAckMessage | |||
516 | /** | 529 | /** |
517 | * ID of the channel | 530 | * ID of the channel |
518 | */ | 531 | */ |
519 | struct GNUNET_CADET_ChannelTunnelNumber gid; | 532 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
520 | 533 | ||
521 | /** | 534 | /** |
522 | * Bitfield of already-received messages past @e mid. | 535 | * Bitfield of already-received messages past @e mid. |
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c index 2f6cc7b11..97489f3fd 100644 --- a/src/cadet/gnunet-service-cadet-new.c +++ b/src/cadet/gnunet-service-cadet-new.c | |||
@@ -66,19 +66,10 @@ struct CadetClient | |||
66 | struct CadetClient *prev; | 66 | struct CadetClient *prev; |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Tunnels that belong to this client, indexed by local id | 69 | * Tunnels that belong to this client, indexed by local id, |
70 | * value is a `struct CadetChannel`. | ||
70 | */ | 71 | */ |
71 | struct GNUNET_CONTAINER_MultiHashMap32 *own_channels; | 72 | struct GNUNET_CONTAINER_MultiHashMap32 *channels; |
72 | |||
73 | /** | ||
74 | * Tunnels this client has accepted, indexed by incoming local id | ||
75 | */ | ||
76 | struct GNUNET_CONTAINER_MultiHashMap32 *incoming_channels; | ||
77 | |||
78 | /** | ||
79 | * Channel ID for the next incoming channel. | ||
80 | */ | ||
81 | struct GNUNET_CADET_ClientChannelNumber next_chid; | ||
82 | 73 | ||
83 | /** | 74 | /** |
84 | * Handle to communicate with the client | 75 | * Handle to communicate with the client |
@@ -97,13 +88,13 @@ struct CadetClient | |||
97 | struct GNUNET_CONTAINER_MultiHashMap *ports; | 88 | struct GNUNET_CONTAINER_MultiHashMap *ports; |
98 | 89 | ||
99 | /** | 90 | /** |
100 | * Whether the client is active or shutting down (don't send confirmations | 91 | * Channel ID to use for the next incoming channel for this client. |
101 | * to a client that is shutting down). | 92 | * Wraps around (in theory). |
102 | */ | 93 | */ |
103 | int shutting_down; | 94 | struct GNUNET_CADET_ClientChannelNumber next_ccn; |
104 | 95 | ||
105 | /** | 96 | /** |
106 | * ID of the client, mainly for debug messages | 97 | * ID of the client, mainly for debug messages. Purely internal to this file. |
107 | */ | 98 | */ |
108 | unsigned int id; | 99 | unsigned int id; |
109 | }; | 100 | }; |
@@ -115,6 +106,11 @@ struct CadetClient | |||
115 | /****************************** Global variables ******************************/ | 106 | /****************************** Global variables ******************************/ |
116 | 107 | ||
117 | /** | 108 | /** |
109 | * Handle to our configuration. | ||
110 | */ | ||
111 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
112 | |||
113 | /** | ||
118 | * Handle to the statistics service. | 114 | * Handle to the statistics service. |
119 | */ | 115 | */ |
120 | struct GNUNET_STATISTICS_Handle *stats; | 116 | struct GNUNET_STATISTICS_Handle *stats; |
@@ -135,7 +131,7 @@ struct GNUNET_PeerIdentity my_full_id; | |||
135 | struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; | 131 | struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; |
136 | 132 | ||
137 | /** | 133 | /** |
138 | * Signal that shutdown is happening: prevent recover measures. | 134 | * Signal that shutdown is happening: prevent recovery measures. |
139 | */ | 135 | */ |
140 | int shutting_down; | 136 | int shutting_down; |
141 | 137 | ||
@@ -188,7 +184,6 @@ unsigned long long ratchet_messages; | |||
188 | struct GNUNET_TIME_Relative ratchet_time; | 184 | struct GNUNET_TIME_Relative ratchet_time; |
189 | 185 | ||
190 | 186 | ||
191 | |||
192 | /** | 187 | /** |
193 | * Send a message to a client. | 188 | * Send a message to a client. |
194 | * | 189 | * |
@@ -215,8 +210,6 @@ GSC_2s (struct CadetClient *c) | |||
215 | { | 210 | { |
216 | static char buf[32]; | 211 | static char buf[32]; |
217 | 212 | ||
218 | if (NULL == c) | ||
219 | return "Client(NULL)"; | ||
220 | GNUNET_snprintf (buf, | 213 | GNUNET_snprintf (buf, |
221 | sizeof (buf), | 214 | sizeof (buf), |
222 | "Client(%u)", | 215 | "Client(%u)", |
@@ -226,20 +219,36 @@ GSC_2s (struct CadetClient *c) | |||
226 | 219 | ||
227 | 220 | ||
228 | /** | 221 | /** |
222 | * Lookup channel of client @a c by @a ccn. | ||
223 | * | ||
224 | * @param c client to look in | ||
225 | * @param ccn channel ID to look up | ||
226 | * @return NULL if no such channel exists | ||
227 | */ | ||
228 | static struct CadetChannel * | ||
229 | lookup_channel (struct CadetClient *c, | ||
230 | struct GNUNET_CADET_ClientChannelNumber ccn) | ||
231 | { | ||
232 | return GNUNET_CONTAINER_multihashmap32_get (c->channels, | ||
233 | ntohl (ccn.channel_of_client)); | ||
234 | } | ||
235 | |||
236 | |||
237 | /** | ||
229 | * Obtain the next LID to use for incoming connections to | 238 | * Obtain the next LID to use for incoming connections to |
230 | * the given client. | 239 | * the given client. |
231 | * | 240 | * |
232 | * @param c client handle | 241 | * @param c client handle |
233 | */ | 242 | */ |
234 | static struct GNUNET_CADET_ClientChannelNumber | 243 | static struct GNUNET_CADET_ClientChannelNumber |
235 | client_get_next_lid (struct CadetClient *c) | 244 | client_get_next_ccn (struct CadetClient *c) |
236 | { | 245 | { |
237 | struct GNUNET_CADET_ClientChannelNumber ccn = c->next_chid; | 246 | struct GNUNET_CADET_ClientChannelNumber ccn = c->next_ccn; |
238 | 247 | ||
239 | /* increment until we have a free one... */ | 248 | /* increment until we have a free one... */ |
240 | while (NULL != | 249 | while (NULL != |
241 | GNUNET_CONTAINER_multihashmap32_get (c->incoming_channels, | 250 | lookup_channel (c, |
242 | ntohl (ccn.channel_of_client))) | 251 | ccn)) |
243 | { | 252 | { |
244 | ccn.channel_of_client | 253 | ccn.channel_of_client |
245 | = htonl (1 + (ntohl (ccn.channel_of_client))); | 254 | = htonl (1 + (ntohl (ccn.channel_of_client))); |
@@ -247,15 +256,16 @@ client_get_next_lid (struct CadetClient *c) | |||
247 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 256 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
248 | ccn.channel_of_client = htonl (0); | 257 | ccn.channel_of_client = htonl (0); |
249 | } | 258 | } |
250 | c->next_chid.channel_of_client | 259 | c->next_ccn.channel_of_client |
251 | = htonl (1 + (ntohl (ccn.channel_of_client))); | 260 | = htonl (1 + (ntohl (ccn.channel_of_client))); |
252 | return ccn; | 261 | return ccn; |
253 | } | 262 | } |
254 | 263 | ||
255 | 264 | ||
256 | /** | 265 | /** |
257 | * Bind incoming channel to this client, and notify client | 266 | * Bind incoming channel to this client, and notify client about |
258 | * about incoming connection. | 267 | * incoming connection. Caller is responsible for notifying the other |
268 | * peer about our acceptance of the channel. | ||
259 | * | 269 | * |
260 | * @param c client to bind to | 270 | * @param c client to bind to |
261 | * @param ch channel to be bound | 271 | * @param ch channel to be bound |
@@ -272,45 +282,86 @@ GSC_bind (struct CadetClient *c, | |||
272 | uint32_t options) | 282 | uint32_t options) |
273 | { | 283 | { |
274 | struct GNUNET_MQ_Envelope *env; | 284 | struct GNUNET_MQ_Envelope *env; |
275 | struct GNUNET_CADET_ChannelOpenMessageMessage *msg; | 285 | struct GNUNET_CADET_LocalChannelCreateMessage *cm; |
276 | struct GNUNET_CADET_ClientChannelNumber lid; | 286 | struct GNUNET_CADET_ClientChannelNumber ccn; |
277 | 287 | ||
278 | lid = client_get_next_lid (c); | 288 | ccn = client_get_next_ccn (c); |
279 | GNUNET_assert (GNUNET_YES == | 289 | GNUNET_assert (GNUNET_YES == |
280 | GNUNET_CONTAINER_multihashmap32_put (c->incoming_channels, | 290 | GNUNET_CONTAINER_multihashmap32_put (c->channels, |
281 | ntohl (lid.channel_of_client), | 291 | ntohl (ccn.channel_of_client), |
282 | ch, | 292 | ch, |
283 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 293 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
284 | 294 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
295 | "Accepting incoming %s from %s on open port %s (%u), assigning ccn %X\n", | ||
296 | GCCH_2s (ch), | ||
297 | GCP_2s (dest), | ||
298 | GNUNET_h2s (port), | ||
299 | ntohl (options), | ||
300 | ntohl (ccn.channel_of_client)); | ||
285 | /* notify local client about incoming connection! */ | 301 | /* notify local client about incoming connection! */ |
286 | env = GNUNET_MQ_msg (msg, | 302 | env = GNUNET_MQ_msg (cm, |
287 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 303 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); |
288 | msg->channel_id = lid; | 304 | cm->ccn = ccn; |
289 | msg->port = *port; | 305 | cm->port = *port; |
290 | msg->opt = htonl (options); | 306 | cm->opt = htonl (options); |
291 | msg->peer = *GCP_get_id (dest); | 307 | cm->peer = *GCP_get_id (dest); |
292 | GSC_send_to_client (c, | 308 | GSC_send_to_client (c, |
293 | env); | 309 | env); |
294 | return lid; | 310 | return ccn; |
295 | } | 311 | } |
296 | 312 | ||
297 | 313 | ||
298 | /******************************************************************************/ | 314 | /** |
299 | /************************ MAIN FUNCTIONS ****************************/ | 315 | * Callback invoked on all peers to destroy all tunnels |
300 | /******************************************************************************/ | 316 | * that may still exist. |
317 | * | ||
318 | * @param cls NULL | ||
319 | * @param pid identify of a peer | ||
320 | * @param value a `struct CadetPeer` that may still have a tunnel | ||
321 | * @return #GNUNET_OK (iterate over all entries) | ||
322 | */ | ||
323 | static int | ||
324 | destroy_tunnels_now (void *cls, | ||
325 | const struct GNUNET_PeerIdentity *pid, | ||
326 | void *value) | ||
327 | { | ||
328 | struct CadetPeer *cp = value; | ||
329 | struct CadetTunnel *t = GCP_get_tunnel (cp, | ||
330 | GNUNET_NO); | ||
331 | |||
332 | if (NULL != t) | ||
333 | GCT_destroy_tunnel_now (t); | ||
334 | return GNUNET_OK; | ||
335 | } | ||
336 | |||
301 | 337 | ||
302 | /** | 338 | /** |
303 | * Task run during shutdown. | 339 | * Callback invoked on all peers to destroy all tunnels |
340 | * that may still exist. | ||
304 | * | 341 | * |
305 | * @param cls unused | 342 | * @param cls NULL |
343 | * @param pid identify of a peer | ||
344 | * @param value a `struct CadetPeer` that may still have a tunnel | ||
345 | * @return #GNUNET_OK (iterate over all entries) | ||
346 | */ | ||
347 | static int | ||
348 | destroy_paths_now (void *cls, | ||
349 | const struct GNUNET_PeerIdentity *pid, | ||
350 | void *value) | ||
351 | { | ||
352 | struct CadetPeer *cp = value; | ||
353 | |||
354 | GCP_drop_owned_paths (cp); | ||
355 | return GNUNET_OK; | ||
356 | } | ||
357 | |||
358 | |||
359 | /** | ||
360 | * Shutdown everything once the clients have disconnected. | ||
306 | */ | 361 | */ |
307 | static void | 362 | static void |
308 | shutdown_task (void *cls) | 363 | shutdown_rest () |
309 | { | 364 | { |
310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
311 | "shutting down\n"); | ||
312 | shutting_down = GNUNET_YES; | ||
313 | GCO_shutdown (); | ||
314 | if (NULL != stats) | 365 | if (NULL != stats) |
315 | { | 366 | { |
316 | GNUNET_STATISTICS_destroy (stats, | 367 | GNUNET_STATISTICS_destroy (stats, |
@@ -327,7 +378,13 @@ shutdown_task (void *cls) | |||
327 | GNUNET_CONTAINER_multihashmap_destroy (loose_channels); | 378 | GNUNET_CONTAINER_multihashmap_destroy (loose_channels); |
328 | loose_channels = NULL; | 379 | loose_channels = NULL; |
329 | } | 380 | } |
330 | /* All channels, connections and CORE must be down before this point. */ | 381 | /* Destroy tunnels. Note that all channels must be destroyed first! */ |
382 | GCP_iterate_all (&destroy_tunnels_now, | ||
383 | NULL); | ||
384 | /* All tunnels, channels, connections and CORE must be down before this point. */ | ||
385 | GCP_iterate_all (&destroy_paths_now, | ||
386 | NULL); | ||
387 | /* All paths, tunnels, channels, connections and CORE must be down before this point. */ | ||
331 | GCP_destroy_all_peers (); | 388 | GCP_destroy_all_peers (); |
332 | if (NULL != peers) | 389 | if (NULL != peers) |
333 | { | 390 | { |
@@ -352,6 +409,23 @@ shutdown_task (void *cls) | |||
352 | 409 | ||
353 | 410 | ||
354 | /** | 411 | /** |
412 | * Task run during shutdown. | ||
413 | * | ||
414 | * @param cls unused | ||
415 | */ | ||
416 | static void | ||
417 | shutdown_task (void *cls) | ||
418 | { | ||
419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
420 | "Shutting down\n"); | ||
421 | shutting_down = GNUNET_YES; | ||
422 | GCO_shutdown (); | ||
423 | if (NULL == clients_head) | ||
424 | shutdown_rest (); | ||
425 | } | ||
426 | |||
427 | |||
428 | /** | ||
355 | * We had a remote connection @a value to port @a port before | 429 | * We had a remote connection @a value to port @a port before |
356 | * client @a cls opened port @a port. Bind them now. | 430 | * client @a cls opened port @a port. Bind them now. |
357 | * | 431 | * |
@@ -379,7 +453,10 @@ bind_loose_channel (void *cls, | |||
379 | 453 | ||
380 | 454 | ||
381 | /** | 455 | /** |
382 | * Handler for port open requests. | 456 | * Handle port open request. Creates a mapping from the |
457 | * port to the respective client and checks whether we have | ||
458 | * loose channels trying to bind to the port. If so, those | ||
459 | * are bound. | ||
383 | * | 460 | * |
384 | * @param cls Identification of the client. | 461 | * @param cls Identification of the client. |
385 | * @param pmsg The actual message. | 462 | * @param pmsg The actual message. |
@@ -391,12 +468,12 @@ handle_port_open (void *cls, | |||
391 | struct CadetClient *c = cls; | 468 | struct CadetClient *c = cls; |
392 | 469 | ||
393 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 470 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
394 | "Open port %s requested by client %u\n", | 471 | "Open port %s requested by %s\n", |
395 | GNUNET_h2s (&pmsg->port), | 472 | GNUNET_h2s (&pmsg->port), |
396 | c->id); | 473 | GSC_2s (c)); |
397 | if (NULL == c->ports) | 474 | if (NULL == c->ports) |
398 | c->ports = GNUNET_CONTAINER_multihashmap_create (4, | 475 | c->ports = GNUNET_CONTAINER_multihashmap_create (4, |
399 | GNUNET_NO); | 476 | GNUNET_NO); |
400 | if (GNUNET_OK != | 477 | if (GNUNET_OK != |
401 | GNUNET_CONTAINER_multihashmap_put (c->ports, | 478 | GNUNET_CONTAINER_multihashmap_put (c->ports, |
402 | &pmsg->port, | 479 | &pmsg->port, |
@@ -407,13 +484,10 @@ handle_port_open (void *cls, | |||
407 | GNUNET_SERVICE_client_drop (c->client); | 484 | GNUNET_SERVICE_client_drop (c->client); |
408 | return; | 485 | return; |
409 | } | 486 | } |
410 | /* store in global hashmap */ | 487 | (void) GNUNET_CONTAINER_multihashmap_put (open_ports, |
411 | /* FIXME only allow one client to have the port open, | 488 | &pmsg->port, |
412 | * have a backup hashmap with waiting clients */ | 489 | c, |
413 | GNUNET_CONTAINER_multihashmap_put (open_ports, | 490 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
414 | &pmsg->port, | ||
415 | c, | ||
416 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
417 | GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels, | 491 | GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels, |
418 | &pmsg->port, | 492 | &pmsg->port, |
419 | &bind_loose_channel, | 493 | &bind_loose_channel, |
@@ -423,7 +497,10 @@ handle_port_open (void *cls, | |||
423 | 497 | ||
424 | 498 | ||
425 | /** | 499 | /** |
426 | * Handler for port close requests. | 500 | * Handler for port close requests. Marks this port as closed |
501 | * (unless of course we have another client with the same port | ||
502 | * open). Note that existing channels accepted on the port are | ||
503 | * not affected. | ||
427 | * | 504 | * |
428 | * @param cls Identification of the client. | 505 | * @param cls Identification of the client. |
429 | * @param pmsg The actual message. | 506 | * @param pmsg The actual message. |
@@ -435,9 +512,9 @@ handle_port_close (void *cls, | |||
435 | struct CadetClient *c = cls; | 512 | struct CadetClient *c = cls; |
436 | 513 | ||
437 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 514 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
438 | "Open port %s requested by client %u\n", | 515 | "Closing port %s as requested by %s\n", |
439 | GNUNET_h2s (&pmsg->port), | 516 | GNUNET_h2s (&pmsg->port), |
440 | c->id); | 517 | GSC_2s (c)); |
441 | if (GNUNET_YES != | 518 | if (GNUNET_YES != |
442 | GNUNET_CONTAINER_multihashmap_remove (c->ports, | 519 | GNUNET_CONTAINER_multihashmap_remove (c->ports, |
443 | &pmsg->port, | 520 | &pmsg->port, |
@@ -451,36 +528,32 @@ handle_port_close (void *cls, | |||
451 | GNUNET_CONTAINER_multihashmap_remove (open_ports, | 528 | GNUNET_CONTAINER_multihashmap_remove (open_ports, |
452 | &pmsg->port, | 529 | &pmsg->port, |
453 | c)); | 530 | c)); |
454 | |||
455 | GNUNET_SERVICE_client_continue (c->client); | 531 | GNUNET_SERVICE_client_continue (c->client); |
456 | } | 532 | } |
457 | 533 | ||
458 | 534 | ||
459 | /** | 535 | /** |
460 | * Handler for requests of new channels. | 536 | * Handler for requests for us creating a new channel to another peer and port. |
461 | * | 537 | * |
462 | * @param cls Identification of the client. | 538 | * @param cls Identification of the client. |
463 | * @param ccm The actual message. | 539 | * @param tcm The actual message. |
464 | */ | 540 | */ |
465 | static void | 541 | static void |
466 | handle_channel_create (void *cls, | 542 | handle_channel_create (void *cls, |
467 | const struct GNUNET_CADET_ChannelOpenMessageMessage *ccm) | 543 | const struct GNUNET_CADET_LocalChannelCreateMessage *tcm) |
468 | { | 544 | { |
469 | struct CadetClient *c = cls; | 545 | struct CadetClient *c = cls; |
470 | struct CadetChannel *ch; | 546 | struct CadetChannel *ch; |
471 | struct GNUNET_CADET_ClientChannelNumber chid; | ||
472 | struct CadetPeer *dst; | ||
473 | 547 | ||
474 | chid = ccm->channel_id; | 548 | if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
475 | if (ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
476 | { | 549 | { |
477 | /* Channel ID not in allowed range. */ | 550 | /* Channel ID not in allowed range. */ |
478 | GNUNET_break (0); | 551 | GNUNET_break (0); |
479 | GNUNET_SERVICE_client_drop (c->client); | 552 | GNUNET_SERVICE_client_drop (c->client); |
480 | return; | 553 | return; |
481 | } | 554 | } |
482 | ch = GNUNET_CONTAINER_multihashmap32_get (c->own_channels, | 555 | ch = lookup_channel (c, |
483 | ntohl (chid.channel_of_client)); | 556 | tcm->ccn); |
484 | if (NULL != ch) | 557 | if (NULL != ch) |
485 | { | 558 | { |
486 | /* Channel ID already in use. Not allowed. */ | 559 | /* Channel ID already in use. Not allowed. */ |
@@ -488,16 +561,19 @@ handle_channel_create (void *cls, | |||
488 | GNUNET_SERVICE_client_drop (c->client); | 561 | GNUNET_SERVICE_client_drop (c->client); |
489 | return; | 562 | return; |
490 | } | 563 | } |
491 | 564 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
492 | dst = GCP_get (&ccm->peer, | 565 | "New channel to %s at port %s requested by %s\n", |
493 | GNUNET_YES); | 566 | GNUNET_i2s (&tcm->peer), |
567 | GNUNET_h2s (&tcm->port), | ||
568 | GSC_2s (c)); | ||
494 | 569 | ||
495 | /* Create channel */ | 570 | /* Create channel */ |
496 | ch = GCCH_channel_local_new (c, | 571 | ch = GCCH_channel_local_new (c, |
497 | chid, | 572 | tcm->ccn, |
498 | dst, | 573 | GCP_get (&tcm->peer, |
499 | &ccm->port, | 574 | GNUNET_YES), |
500 | ntohl (ccm->opt)); | 575 | &tcm->port, |
576 | ntohl (tcm->opt)); | ||
501 | if (NULL == ch) | 577 | if (NULL == ch) |
502 | { | 578 | { |
503 | GNUNET_break (0); | 579 | GNUNET_break (0); |
@@ -505,59 +581,30 @@ handle_channel_create (void *cls, | |||
505 | return; | 581 | return; |
506 | } | 582 | } |
507 | GNUNET_assert (GNUNET_YES == | 583 | GNUNET_assert (GNUNET_YES == |
508 | GNUNET_CONTAINER_multihashmap32_put (c->own_channels, | 584 | GNUNET_CONTAINER_multihashmap32_put (c->channels, |
509 | ntohl (chid.channel_of_client), | 585 | ntohl (tcm->ccn.channel_of_client), |
510 | ch, | 586 | ch, |
511 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 587 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
512 | 588 | ||
513 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
514 | "New channel %s to %s at port %s requested by client %u\n", | ||
515 | GCCH_2s (ch), | ||
516 | GNUNET_i2s (&ccm->peer), | ||
517 | GNUNET_h2s (&ccm->port), | ||
518 | c->id); | ||
519 | GNUNET_SERVICE_client_continue (c->client); | 589 | GNUNET_SERVICE_client_continue (c->client); |
520 | } | 590 | } |
521 | 591 | ||
522 | 592 | ||
523 | /** | 593 | /** |
524 | * Return the map which we use for client @a c for a channel ID of @a chid | 594 | * Handler for requests of destroying an existing channel. |
525 | * | ||
526 | * @param c client to find map for | ||
527 | * @param chid chid to find map for | ||
528 | * @return applicable map we use | ||
529 | */ | ||
530 | static struct GNUNET_CONTAINER_MultiHashMap32 * | ||
531 | get_map_by_chid (struct CadetClient *c, | ||
532 | struct GNUNET_CADET_ClientChannelNumber chid) | ||
533 | { | ||
534 | return (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
535 | ? c->own_channels | ||
536 | : c->incoming_channels; | ||
537 | } | ||
538 | |||
539 | |||
540 | /** | ||
541 | * Handler for requests of deleting tunnels | ||
542 | * | 595 | * |
543 | * @param cls client identification of the client | 596 | * @param cls client identification of the client |
544 | * @param msg the actual message | 597 | * @param msg the actual message |
545 | */ | 598 | */ |
546 | static void | 599 | static void |
547 | handle_channel_destroy (void *cls, | 600 | handle_channel_destroy (void *cls, |
548 | const struct GNUNET_CADET_ChannelDestroyMessage *msg) | 601 | const struct GNUNET_CADET_LocalChannelDestroyMessage *msg) |
549 | { | 602 | { |
550 | struct CadetClient *c = cls; | 603 | struct CadetClient *c = cls; |
551 | struct GNUNET_CADET_ClientChannelNumber chid; | ||
552 | struct GNUNET_CONTAINER_MultiHashMap32 *map; | ||
553 | struct CadetChannel *ch; | 604 | struct CadetChannel *ch; |
554 | 605 | ||
555 | /* Retrieve tunnel */ | 606 | ch = lookup_channel (c, |
556 | chid = msg->channel_id; | 607 | msg->ccn); |
557 | map = get_map_by_chid (c, | ||
558 | chid); | ||
559 | ch = GNUNET_CONTAINER_multihashmap32_get (map, | ||
560 | ntohl (chid.channel_of_client)); | ||
561 | if (NULL == ch) | 608 | if (NULL == ch) |
562 | { | 609 | { |
563 | /* Client attempted to destroy unknown channel */ | 610 | /* Client attempted to destroy unknown channel */ |
@@ -566,46 +613,70 @@ handle_channel_destroy (void *cls, | |||
566 | return; | 613 | return; |
567 | } | 614 | } |
568 | LOG (GNUNET_ERROR_TYPE_INFO, | 615 | LOG (GNUNET_ERROR_TYPE_INFO, |
569 | "Client %u is destroying channel %s\n", | 616 | "%s is destroying %s\n", |
570 | c->id, | 617 | GSC_2s(c), |
571 | GCCH_2s (ch)); | 618 | GCCH_2s (ch)); |
572 | GNUNET_assert (GNUNET_YES == | 619 | GNUNET_assert (GNUNET_YES == |
573 | GNUNET_CONTAINER_multihashmap32_remove (map, | 620 | GNUNET_CONTAINER_multihashmap32_remove (c->channels, |
574 | ntohl (chid.channel_of_client), | 621 | ntohl (msg->ccn.channel_of_client), |
575 | ch)); | 622 | ch)); |
576 | GCCH_channel_local_destroy (ch); | 623 | GCCH_channel_local_destroy (ch, |
624 | c, | ||
625 | msg->ccn); | ||
577 | GNUNET_SERVICE_client_continue (c->client); | 626 | GNUNET_SERVICE_client_continue (c->client); |
578 | } | 627 | } |
579 | 628 | ||
580 | 629 | ||
581 | /** | 630 | /** |
582 | * Check for client traffic data message is well-formed | 631 | * Check for client traffic data message is well-formed. |
583 | * | 632 | * |
584 | * @param cls identification of the client | 633 | * @param cls identification of the client |
585 | * @param msg the actual message | 634 | * @param msg the actual message |
586 | * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not | 635 | * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not |
587 | */ | 636 | */ |
588 | static int | 637 | static int |
589 | check_data (void *cls, | 638 | check_local_data (void *cls, |
590 | const struct GNUNET_CADET_LocalData *msg) | 639 | const struct GNUNET_CADET_LocalData *msg) |
591 | { | 640 | { |
592 | const struct GNUNET_MessageHeader *payload; | ||
593 | size_t payload_size; | 641 | size_t payload_size; |
594 | size_t payload_claimed_size; | 642 | size_t payload_claimed_size; |
595 | 643 | const char *buf; | |
644 | struct GNUNET_MessageHeader pa; | ||
645 | |||
646 | /* FIXME: what is the format we shall allow for @a msg? | ||
647 | ONE payload item or multiple? Seems current cadet_api | ||
648 | at least in theory allows more than one. Next-gen | ||
649 | cadet_api will likely no more, so we could then | ||
650 | simplify this mess again. */ | ||
596 | /* Sanity check for message size */ | 651 | /* Sanity check for message size */ |
597 | payload_size = ntohs (msg->header.size) - sizeof (*msg); | 652 | payload_size = ntohs (msg->header.size) - sizeof (*msg); |
598 | if ( (payload_size < sizeof (struct GNUNET_MessageHeader)) || | 653 | buf = (const char *) &msg[1]; |
599 | (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_size) ) | 654 | while (payload_size >= sizeof (struct GNUNET_MessageHeader)) |
600 | { | 655 | { |
601 | GNUNET_break (0); | 656 | /* need to memcpy() for alignment */ |
602 | return GNUNET_SYSERR; | 657 | GNUNET_memcpy (&pa, |
658 | buf, | ||
659 | sizeof (pa)); | ||
660 | payload_claimed_size = ntohs (pa.size); | ||
661 | if ( (payload_size < payload_claimed_size) || | ||
662 | (payload_claimed_size < sizeof (struct GNUNET_MessageHeader)) || | ||
663 | (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size) ) | ||
664 | { | ||
665 | GNUNET_break (0); | ||
666 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
667 | "Local data of %u total size had sub-message %u at %u with %u bytes\n", | ||
668 | ntohs (msg->header.size), | ||
669 | ntohs (pa.type), | ||
670 | (unsigned int) (buf - (const char *) &msg[1]), | ||
671 | (unsigned int) payload_claimed_size); | ||
672 | return GNUNET_SYSERR; | ||
673 | } | ||
674 | payload_size -= payload_claimed_size; | ||
675 | buf += payload_claimed_size; | ||
603 | } | 676 | } |
604 | payload = (struct GNUNET_MessageHeader *) &msg[1]; | 677 | if (0 != payload_size) |
605 | payload_claimed_size = ntohs (payload->size); | ||
606 | if (payload_size != payload_claimed_size) | ||
607 | { | 678 | { |
608 | GNUNET_break (0); | 679 | GNUNET_break_op (0); |
609 | return GNUNET_SYSERR; | 680 | return GNUNET_SYSERR; |
610 | } | 681 | } |
611 | return GNUNET_OK; | 682 | return GNUNET_OK; |
@@ -613,26 +684,23 @@ check_data (void *cls, | |||
613 | 684 | ||
614 | 685 | ||
615 | /** | 686 | /** |
616 | * Handler for client traffic | 687 | * Handler for client payload traffic to be send on a channel to |
688 | * another peer. | ||
617 | * | 689 | * |
618 | * @param cls identification of the client | 690 | * @param cls identification of the client |
619 | * @param msg the actual message | 691 | * @param msg the actual message |
620 | */ | 692 | */ |
621 | static void | 693 | static void |
622 | handle_data (void *cls, | 694 | handle_local_data (void *cls, |
623 | const struct GNUNET_CADET_LocalData *msg) | 695 | const struct GNUNET_CADET_LocalData *msg) |
624 | { | 696 | { |
625 | struct CadetClient *c = cls; | 697 | struct CadetClient *c = cls; |
626 | struct GNUNET_CONTAINER_MultiHashMap32 *map; | ||
627 | struct GNUNET_CADET_ClientChannelNumber chid; | ||
628 | struct CadetChannel *ch; | 698 | struct CadetChannel *ch; |
629 | const struct GNUNET_MessageHeader *payload; | 699 | size_t payload_size; |
700 | const char *buf; | ||
630 | 701 | ||
631 | chid = msg->id; | 702 | ch = lookup_channel (c, |
632 | map = get_map_by_chid (c, | 703 | msg->ccn); |
633 | chid); | ||
634 | ch = GNUNET_CONTAINER_multihashmap32_get (map, | ||
635 | ntohl (chid.channel_of_client)); | ||
636 | if (NULL == ch) | 704 | if (NULL == ch) |
637 | { | 705 | { |
638 | /* Channel does not exist! */ | 706 | /* Channel does not exist! */ |
@@ -640,16 +708,18 @@ handle_data (void *cls, | |||
640 | GNUNET_SERVICE_client_drop (c->client); | 708 | GNUNET_SERVICE_client_drop (c->client); |
641 | return; | 709 | return; |
642 | } | 710 | } |
643 | 711 | payload_size = ntohs (msg->header.size) - sizeof (*msg); | |
644 | payload = (const struct GNUNET_MessageHeader *) &msg[1]; | 712 | buf = (const char *) &msg[1]; |
645 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 713 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
646 | "Received %u bytes payload from client %u for channel %s\n", | 714 | "Received %u bytes payload from %s for %s\n", |
647 | ntohs (payload->size), | 715 | (unsigned int) payload_size, |
648 | c->id, | 716 | GSC_2s (c), |
649 | GCCH_2s (ch)); | 717 | GCCH_2s (ch)); |
650 | if (GNUNET_OK != | 718 | if (GNUNET_OK != |
651 | GCCH_handle_local_data (ch, | 719 | GCCH_handle_local_data (ch, |
652 | payload)) | 720 | msg->ccn, |
721 | buf, | ||
722 | payload_size)) | ||
653 | { | 723 | { |
654 | GNUNET_SERVICE_client_drop (c->client); | 724 | GNUNET_SERVICE_client_drop (c->client); |
655 | return; | 725 | return; |
@@ -665,19 +735,14 @@ handle_data (void *cls, | |||
665 | * @param msg The actual message. | 735 | * @param msg The actual message. |
666 | */ | 736 | */ |
667 | static void | 737 | static void |
668 | handle_ack (void *cls, | 738 | handle_local_ack (void *cls, |
669 | const struct GNUNET_CADET_LocalAck *msg) | 739 | const struct GNUNET_CADET_LocalAck *msg) |
670 | { | 740 | { |
671 | struct CadetClient *c = cls; | 741 | struct CadetClient *c = cls; |
672 | struct GNUNET_CONTAINER_MultiHashMap32 *map; | ||
673 | struct GNUNET_CADET_ClientChannelNumber chid; | ||
674 | struct CadetChannel *ch; | 742 | struct CadetChannel *ch; |
675 | 743 | ||
676 | chid = msg->channel_id; | 744 | ch = lookup_channel (c, |
677 | map = get_map_by_chid (c, | 745 | msg->ccn); |
678 | chid); | ||
679 | ch = GNUNET_CONTAINER_multihashmap32_get (map, | ||
680 | ntohl (chid.channel_of_client)); | ||
681 | if (NULL == ch) | 746 | if (NULL == ch) |
682 | { | 747 | { |
683 | /* Channel does not exist! */ | 748 | /* Channel does not exist! */ |
@@ -686,10 +751,11 @@ handle_ack (void *cls, | |||
686 | return; | 751 | return; |
687 | } | 752 | } |
688 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 753 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
689 | "Got a local ACK from client %u for channel %s\n", | 754 | "Got a local ACK from %s for %s\n", |
690 | c->id, | 755 | GSC_2s(c), |
691 | GCCH_2s (ch)); | 756 | GCCH_2s (ch)); |
692 | GCCH_handle_local_ack (ch); | 757 | GCCH_handle_local_ack (ch, |
758 | msg->ccn); | ||
693 | GNUNET_SERVICE_client_continue (c->client); | 759 | GNUNET_SERVICE_client_continue (c->client); |
694 | } | 760 | } |
695 | 761 | ||
@@ -855,7 +921,7 @@ get_all_tunnels_iterator (void *cls, | |||
855 | msg->destination = *peer; | 921 | msg->destination = *peer; |
856 | msg->channels = htonl (GCT_count_channels (t)); | 922 | msg->channels = htonl (GCT_count_channels (t)); |
857 | msg->connections = htonl (GCT_count_any_connections (t)); | 923 | msg->connections = htonl (GCT_count_any_connections (t)); |
858 | msg->cstate = htons ((uint16_t) GCT_get_cstate (t)); | 924 | msg->cstate = htons (0); |
859 | msg->estate = htons ((uint16_t) GCT_get_estate (t)); | 925 | msg->estate = htons ((uint16_t) GCT_get_estate (t)); |
860 | GNUNET_MQ_send (c->mq, | 926 | GNUNET_MQ_send (c->mq, |
861 | env); | 927 | env); |
@@ -864,14 +930,14 @@ get_all_tunnels_iterator (void *cls, | |||
864 | 930 | ||
865 | 931 | ||
866 | /** | 932 | /** |
867 | * Handler for client's INFO TUNNELS request. | 933 | * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS request. |
868 | * | 934 | * |
869 | * @param cls client Identification of the client. | 935 | * @param cls client Identification of the client. |
870 | * @param message The actual message. | 936 | * @param message The actual message. |
871 | */ | 937 | */ |
872 | static void | 938 | static void |
873 | handle_get_tunnels (void *cls, | 939 | handle_info_tunnels (void *cls, |
874 | const struct GNUNET_MessageHeader *message) | 940 | const struct GNUNET_MessageHeader *message) |
875 | { | 941 | { |
876 | struct CadetClient *c = cls; | 942 | struct CadetClient *c = cls; |
877 | struct GNUNET_MQ_Envelope *env; | 943 | struct GNUNET_MQ_Envelope *env; |
@@ -888,7 +954,10 @@ handle_get_tunnels (void *cls, | |||
888 | 954 | ||
889 | 955 | ||
890 | /** | 956 | /** |
891 | * FIXME. | 957 | * Update the message with information about the connection. |
958 | * | ||
959 | * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update | ||
960 | * @param c a connection about which we should store information in @a cls | ||
892 | */ | 961 | */ |
893 | static void | 962 | static void |
894 | iter_connection (void *cls, | 963 | iter_connection (void *cls, |
@@ -903,7 +972,10 @@ iter_connection (void *cls, | |||
903 | 972 | ||
904 | 973 | ||
905 | /** | 974 | /** |
906 | * FIXME. | 975 | * Update the message with information about the channel. |
976 | * | ||
977 | * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update | ||
978 | * @param ch a channel about which we should store information in @a cls | ||
907 | */ | 979 | */ |
908 | static void | 980 | static void |
909 | iter_channel (void *cls, | 981 | iter_channel (void *cls, |
@@ -919,13 +991,13 @@ iter_channel (void *cls, | |||
919 | 991 | ||
920 | 992 | ||
921 | /** | 993 | /** |
922 | * Handler for client's SHOW_TUNNEL request. | 994 | * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL request. |
923 | * | 995 | * |
924 | * @param cls Identification of the client. | 996 | * @param cls Identification of the client. |
925 | * @param msg The actual message. | 997 | * @param msg The actual message. |
926 | */ | 998 | */ |
927 | static void | 999 | static void |
928 | handle_show_tunnel (void *cls, | 1000 | handle_info_tunnel (void *cls, |
929 | const struct GNUNET_CADET_LocalInfo *msg) | 1001 | const struct GNUNET_CADET_LocalInfo *msg) |
930 | { | 1002 | { |
931 | struct CadetClient *c = cls; | 1003 | struct CadetClient *c = cls; |
@@ -975,7 +1047,7 @@ handle_show_tunnel (void *cls, | |||
975 | resp); | 1047 | resp); |
976 | resp->connections = htonl (resp->connections); | 1048 | resp->connections = htonl (resp->connections); |
977 | resp->channels = htonl (resp->channels); | 1049 | resp->channels = htonl (resp->channels); |
978 | resp->cstate = htons (GCT_get_cstate (t)); | 1050 | resp->cstate = htons (0); |
979 | resp->estate = htons (GCT_get_estate (t)); | 1051 | resp->estate = htons (GCT_get_estate (t)); |
980 | GNUNET_MQ_send (c->mq, | 1052 | GNUNET_MQ_send (c->mq, |
981 | env); | 1053 | env); |
@@ -1028,18 +1100,19 @@ handle_info_dump (void *cls, | |||
1028 | 1100 | ||
1029 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1101 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1030 | "*************************** DUMP START ***************************\n"); | 1102 | "*************************** DUMP START ***************************\n"); |
1031 | for (struct CadetClient *ci = clients_head; NULL != ci; ci = ci->next) | 1103 | for (struct CadetClient *ci = clients_head; |
1104 | NULL != ci; | ||
1105 | ci = ci->next) | ||
1032 | { | 1106 | { |
1033 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1107 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1034 | "Client %u (%p), handle: %p, ports: %u, own channels: %u, incoming channels: %u\n", | 1108 | "Client %u (%p), handle: %p, ports: %u, channels: %u\n", |
1035 | ci->id, | 1109 | ci->id, |
1036 | ci, | 1110 | ci, |
1037 | ci->client, | 1111 | ci->client, |
1038 | (NULL != c->ports) | 1112 | (NULL != c->ports) |
1039 | ? GNUNET_CONTAINER_multihashmap_size (ci->ports) | 1113 | ? GNUNET_CONTAINER_multihashmap_size (ci->ports) |
1040 | : 0, | 1114 | : 0, |
1041 | GNUNET_CONTAINER_multihashmap32_size (ci->own_channels), | 1115 | GNUNET_CONTAINER_multihashmap32_size (ci->channels)); |
1042 | GNUNET_CONTAINER_multihashmap32_size (ci->incoming_channels)); | ||
1043 | } | 1116 | } |
1044 | LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n"); | 1117 | LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n"); |
1045 | GCP_iterate_all (&show_peer_iterator, | 1118 | GCP_iterate_all (&show_peer_iterator, |
@@ -1072,9 +1145,7 @@ client_connect_cb (void *cls, | |||
1072 | c->client = client; | 1145 | c->client = client; |
1073 | c->mq = mq; | 1146 | c->mq = mq; |
1074 | c->id = next_client_id++; /* overflow not important: just for debug */ | 1147 | c->id = next_client_id++; /* overflow not important: just for debug */ |
1075 | c->own_channels | 1148 | c->channels |
1076 | = GNUNET_CONTAINER_multihashmap32_create (32); | ||
1077 | c->incoming_channels | ||
1078 | = GNUNET_CONTAINER_multihashmap32_create (32); | 1149 | = GNUNET_CONTAINER_multihashmap32_create (32); |
1079 | GNUNET_CONTAINER_DLL_insert (clients_head, | 1150 | GNUNET_CONTAINER_DLL_insert (clients_head, |
1080 | clients_tail, | 1151 | clients_tail, |
@@ -1083,36 +1154,37 @@ client_connect_cb (void *cls, | |||
1083 | "# clients", | 1154 | "# clients", |
1084 | +1, | 1155 | +1, |
1085 | GNUNET_NO); | 1156 | GNUNET_NO); |
1157 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1158 | "%s connected\n", | ||
1159 | GSC_2s (c)); | ||
1086 | return c; | 1160 | return c; |
1087 | } | 1161 | } |
1088 | 1162 | ||
1089 | 1163 | ||
1090 | /** | 1164 | /** |
1091 | * Iterator for deleting each channel whose client endpoint disconnected. | 1165 | * A channel was destroyed by the other peer. Tell our client. |
1092 | * | 1166 | * |
1093 | * @param cls Closure (client that has disconnected). | 1167 | * @param c client that lost a channel |
1094 | * @param key The local channel id (used to access the hashmap). | 1168 | * @param ccn channel identification number for the client |
1095 | * @param value The value stored at the key (channel to destroy). | 1169 | * @param ch the channel object |
1096 | * @return #GNUNET_OK, keep iterating. | ||
1097 | */ | 1170 | */ |
1098 | static int | 1171 | void |
1099 | own_channel_destroy_iterator (void *cls, | 1172 | GSC_handle_remote_channel_destroy (struct CadetClient *c, |
1100 | uint32_t key, | 1173 | struct GNUNET_CADET_ClientChannelNumber ccn, |
1101 | void *value) | 1174 | struct CadetChannel *ch) |
1102 | { | 1175 | { |
1103 | struct CadetClient *c = cls; | 1176 | struct GNUNET_MQ_Envelope *env; |
1104 | struct CadetChannel *ch = value; | 1177 | struct GNUNET_CADET_LocalChannelDestroyMessage *tdm; |
1105 | 1178 | ||
1179 | env = GNUNET_MQ_msg (tdm, | ||
1180 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY); | ||
1181 | tdm->ccn = ccn; | ||
1182 | GSC_send_to_client (c, | ||
1183 | env); | ||
1106 | GNUNET_assert (GNUNET_YES == | 1184 | GNUNET_assert (GNUNET_YES == |
1107 | GNUNET_CONTAINER_multihashmap32_remove (c->own_channels, | 1185 | GNUNET_CONTAINER_multihashmap32_remove (c->channels, |
1108 | key, | 1186 | ntohl (ccn.channel_of_client), |
1109 | ch)); | 1187 | ch)); |
1110 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1111 | "Destroying own channel %s, due to client %u shutdown.\n", | ||
1112 | GCCH_2s (ch), | ||
1113 | c->id); | ||
1114 | GCCH_channel_local_destroy (ch); | ||
1115 | return GNUNET_OK; | ||
1116 | } | 1188 | } |
1117 | 1189 | ||
1118 | 1190 | ||
@@ -1120,28 +1192,31 @@ own_channel_destroy_iterator (void *cls, | |||
1120 | * Iterator for deleting each channel whose client endpoint disconnected. | 1192 | * Iterator for deleting each channel whose client endpoint disconnected. |
1121 | * | 1193 | * |
1122 | * @param cls Closure (client that has disconnected). | 1194 | * @param cls Closure (client that has disconnected). |
1123 | * @param key The local channel id (used to access the hashmap). | 1195 | * @param key The local channel id in host byte order |
1124 | * @param value The value stored at the key (channel to destroy). | 1196 | * @param value The value stored at the key (channel to destroy). |
1125 | * @return #GNUNET_OK, keep iterating. | 1197 | * @return #GNUNET_OK, keep iterating. |
1126 | */ | 1198 | */ |
1127 | static int | 1199 | static int |
1128 | incoming_channel_destroy_iterator (void *cls, | 1200 | channel_destroy_iterator (void *cls, |
1129 | uint32_t key, | 1201 | uint32_t key, |
1130 | void *value) | 1202 | void *value) |
1131 | { | 1203 | { |
1132 | struct CadetChannel *ch = value; | ||
1133 | struct CadetClient *c = cls; | 1204 | struct CadetClient *c = cls; |
1205 | struct GNUNET_CADET_ClientChannelNumber ccn; | ||
1206 | struct CadetChannel *ch = value; | ||
1134 | 1207 | ||
1208 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1209 | "Destroying %s, due to %s disconnecting.\n", | ||
1210 | GCCH_2s (ch), | ||
1211 | GSC_2s (c)); | ||
1135 | GNUNET_assert (GNUNET_YES == | 1212 | GNUNET_assert (GNUNET_YES == |
1136 | GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels, | 1213 | GNUNET_CONTAINER_multihashmap32_remove (c->channels, |
1137 | key, | 1214 | key, |
1138 | ch)); | 1215 | ch)); |
1139 | 1216 | ccn.channel_of_client = htonl (key); | |
1140 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1217 | GCCH_channel_local_destroy (ch, |
1141 | "Destroying incoming channel %s due to client %u shutdown.\n", | 1218 | c, |
1142 | GCCH_2s (ch), | 1219 | ccn); |
1143 | c->id); | ||
1144 | GCCH_channel_incoming_destroy (ch); | ||
1145 | return GNUNET_OK; | 1220 | return GNUNET_OK; |
1146 | } | 1221 | } |
1147 | 1222 | ||
@@ -1150,7 +1225,7 @@ incoming_channel_destroy_iterator (void *cls, | |||
1150 | * Remove client's ports from the global hashmap on disconnect. | 1225 | * Remove client's ports from the global hashmap on disconnect. |
1151 | * | 1226 | * |
1152 | * @param cls Closure (unused). | 1227 | * @param cls Closure (unused). |
1153 | * @param key Port. | 1228 | * @param key the port. |
1154 | * @param value the `struct CadetClient` to remove | 1229 | * @param value the `struct CadetClient` to remove |
1155 | * @return #GNUNET_OK, keep iterating. | 1230 | * @return #GNUNET_OK, keep iterating. |
1156 | */ | 1231 | */ |
@@ -1161,6 +1236,10 @@ client_release_ports (void *cls, | |||
1161 | { | 1236 | { |
1162 | struct CadetClient *c = value; | 1237 | struct CadetClient *c = value; |
1163 | 1238 | ||
1239 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1240 | "Closing port %s due to %s disconnect.\n", | ||
1241 | GNUNET_h2s (key), | ||
1242 | GSC_2s (c)); | ||
1164 | GNUNET_assert (GNUNET_YES == | 1243 | GNUNET_assert (GNUNET_YES == |
1165 | GNUNET_CONTAINER_multihashmap_remove (open_ports, | 1244 | GNUNET_CONTAINER_multihashmap_remove (open_ports, |
1166 | key, | 1245 | key, |
@@ -1188,20 +1267,15 @@ client_disconnect_cb (void *cls, | |||
1188 | struct CadetClient *c = internal_cls; | 1267 | struct CadetClient *c = internal_cls; |
1189 | 1268 | ||
1190 | GNUNET_assert (c->client == client); | 1269 | GNUNET_assert (c->client == client); |
1191 | c->shutting_down = GNUNET_YES; | 1270 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1192 | if (NULL != c->own_channels) | 1271 | "%s is disconnecting.\n", |
1193 | { | 1272 | GSC_2s (c)); |
1194 | GNUNET_CONTAINER_multihashmap32_iterate (c->own_channels, | 1273 | if (NULL != c->channels) |
1195 | &own_channel_destroy_iterator, | ||
1196 | c); | ||
1197 | GNUNET_CONTAINER_multihashmap32_destroy (c->own_channels); | ||
1198 | } | ||
1199 | if (NULL != c->incoming_channels) | ||
1200 | { | 1274 | { |
1201 | GNUNET_CONTAINER_multihashmap32_iterate (c->incoming_channels, | 1275 | GNUNET_CONTAINER_multihashmap32_iterate (c->channels, |
1202 | &incoming_channel_destroy_iterator, | 1276 | &channel_destroy_iterator, |
1203 | c); | 1277 | c); |
1204 | GNUNET_CONTAINER_multihashmap32_destroy (c->incoming_channels); | 1278 | GNUNET_CONTAINER_multihashmap32_destroy (c->channels); |
1205 | } | 1279 | } |
1206 | if (NULL != c->ports) | 1280 | if (NULL != c->ports) |
1207 | { | 1281 | { |
@@ -1218,6 +1292,9 @@ client_disconnect_cb (void *cls, | |||
1218 | -1, | 1292 | -1, |
1219 | GNUNET_NO); | 1293 | GNUNET_NO); |
1220 | GNUNET_free (c); | 1294 | GNUNET_free (c); |
1295 | if ( (NULL == clients_head) && | ||
1296 | (GNUNET_YES == shutting_down) ) | ||
1297 | shutdown_rest (); | ||
1221 | } | 1298 | } |
1222 | 1299 | ||
1223 | 1300 | ||
@@ -1233,6 +1310,7 @@ run (void *cls, | |||
1233 | const struct GNUNET_CONFIGURATION_Handle *c, | 1310 | const struct GNUNET_CONFIGURATION_Handle *c, |
1234 | struct GNUNET_SERVICE_Handle *service) | 1311 | struct GNUNET_SERVICE_Handle *service) |
1235 | { | 1312 | { |
1313 | cfg = c; | ||
1236 | if (GNUNET_OK != | 1314 | if (GNUNET_OK != |
1237 | GNUNET_CONFIGURATION_get_value_number (c, | 1315 | GNUNET_CONFIGURATION_get_value_number (c, |
1238 | "CADET", | 1316 | "CADET", |
@@ -1285,7 +1363,7 @@ run (void *cls, | |||
1285 | GCD_init (c); | 1363 | GCD_init (c); |
1286 | GCO_init (c); | 1364 | GCO_init (c); |
1287 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1365 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1288 | "CADET starting at peer %s\n", | 1366 | "CADET started for peer %s\n", |
1289 | GNUNET_i2s (&my_full_id)); | 1367 | GNUNET_i2s (&my_full_id)); |
1290 | 1368 | ||
1291 | } | 1369 | } |
@@ -1310,18 +1388,18 @@ GNUNET_SERVICE_MAIN | |||
1310 | struct GNUNET_CADET_PortMessage, | 1388 | struct GNUNET_CADET_PortMessage, |
1311 | NULL), | 1389 | NULL), |
1312 | GNUNET_MQ_hd_fixed_size (channel_create, | 1390 | GNUNET_MQ_hd_fixed_size (channel_create, |
1313 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | 1391 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE, |
1314 | struct GNUNET_CADET_ChannelOpenMessageMessage, | 1392 | struct GNUNET_CADET_LocalChannelCreateMessage, |
1315 | NULL), | 1393 | NULL), |
1316 | GNUNET_MQ_hd_fixed_size (channel_destroy, | 1394 | GNUNET_MQ_hd_fixed_size (channel_destroy, |
1317 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | 1395 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY, |
1318 | struct GNUNET_CADET_ChannelDestroyMessage, | 1396 | struct GNUNET_CADET_LocalChannelDestroyMessage, |
1319 | NULL), | 1397 | NULL), |
1320 | GNUNET_MQ_hd_var_size (data, | 1398 | GNUNET_MQ_hd_var_size (local_data, |
1321 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, | 1399 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, |
1322 | struct GNUNET_CADET_LocalData, | 1400 | struct GNUNET_CADET_LocalData, |
1323 | NULL), | 1401 | NULL), |
1324 | GNUNET_MQ_hd_fixed_size (ack, | 1402 | GNUNET_MQ_hd_fixed_size (local_ack, |
1325 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, | 1403 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, |
1326 | struct GNUNET_CADET_LocalAck, | 1404 | struct GNUNET_CADET_LocalAck, |
1327 | NULL), | 1405 | NULL), |
@@ -1333,11 +1411,11 @@ GNUNET_SERVICE_MAIN | |||
1333 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, | 1411 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, |
1334 | struct GNUNET_CADET_LocalInfo, | 1412 | struct GNUNET_CADET_LocalInfo, |
1335 | NULL), | 1413 | NULL), |
1336 | GNUNET_MQ_hd_fixed_size (get_tunnels, | 1414 | GNUNET_MQ_hd_fixed_size (info_tunnels, |
1337 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, | 1415 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, |
1338 | struct GNUNET_MessageHeader, | 1416 | struct GNUNET_MessageHeader, |
1339 | NULL), | 1417 | NULL), |
1340 | GNUNET_MQ_hd_fixed_size (show_tunnel, | 1418 | GNUNET_MQ_hd_fixed_size (info_tunnel, |
1341 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, | 1419 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, |
1342 | struct GNUNET_CADET_LocalInfo, | 1420 | struct GNUNET_CADET_LocalInfo, |
1343 | NULL), | 1421 | NULL), |
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h index 9f4667e23..4a76c578b 100644 --- a/src/cadet/gnunet-service-cadet-new.h +++ b/src/cadet/gnunet-service-cadet-new.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | #define NEW_CADET 1 | 32 | #define NEW_CADET 1 |
33 | #include "cadet_protocol.h" | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * A client to the CADET service. Each client gets a unique handle. | 36 | * A client to the CADET service. Each client gets a unique handle. |
@@ -167,6 +168,11 @@ struct CadetRoute; | |||
167 | struct CadetChannel; | 168 | struct CadetChannel; |
168 | 169 | ||
169 | /** | 170 | /** |
171 | * Handle to our configuration. | ||
172 | */ | ||
173 | extern const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
174 | |||
175 | /** | ||
170 | * Handle to the statistics service. | 176 | * Handle to the statistics service. |
171 | */ | 177 | */ |
172 | extern struct GNUNET_STATISTICS_Handle *stats; | 178 | extern struct GNUNET_STATISTICS_Handle *stats; |
@@ -219,6 +225,10 @@ extern unsigned long long ratchet_messages; | |||
219 | */ | 225 | */ |
220 | extern struct GNUNET_TIME_Relative ratchet_time; | 226 | extern struct GNUNET_TIME_Relative ratchet_time; |
221 | 227 | ||
228 | /** | ||
229 | * Signal that shutdown is happening: prevent recovery measures. | ||
230 | */ | ||
231 | extern int shutting_down; | ||
222 | 232 | ||
223 | 233 | ||
224 | /** | 234 | /** |
@@ -233,6 +243,19 @@ GSC_send_to_client (struct CadetClient *c, | |||
233 | 243 | ||
234 | 244 | ||
235 | /** | 245 | /** |
246 | * A channel was destroyed by the other peer. Tell our client. | ||
247 | * | ||
248 | * @param c client that lost a channel | ||
249 | * @param ccn channel identification number for the client | ||
250 | * @param ch the channel object | ||
251 | */ | ||
252 | void | ||
253 | GSC_handle_remote_channel_destroy (struct CadetClient *c, | ||
254 | struct GNUNET_CADET_ClientChannelNumber ccn, | ||
255 | struct CadetChannel *ch); | ||
256 | |||
257 | |||
258 | /** | ||
236 | * Bind incoming channel to this client, and notify client | 259 | * Bind incoming channel to this client, and notify client |
237 | * about incoming connection. | 260 | * about incoming connection. |
238 | * | 261 | * |
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index 5acd098b6..0c6241817 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c | |||
@@ -18,7 +18,6 @@ | |||
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. | 19 | Boston, MA 02110-1301, USA. |
20 | */ | 20 | */ |
21 | |||
22 | /** | 21 | /** |
23 | * @file cadet/gnunet-service-cadet-new_channel.c | 22 | * @file cadet/gnunet-service-cadet-new_channel.c |
24 | * @brief logical links between CADET clients | 23 | * @brief logical links between CADET clients |
@@ -26,10 +25,16 @@ | |||
26 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
27 | * | 26 | * |
28 | * TODO: | 27 | * TODO: |
29 | * - estimate max bandwidth using bursts and use to optimize | 28 | * - FIXME: send ACKs back to loopback clients! |
30 | * transmission rate(s) | 29 | * |
30 | * - introduce shutdown so we can have half-closed channels, modify | ||
31 | * destroy to include MID to have FIN-ACK equivalents, etc. | ||
32 | * - estimate max bandwidth using bursts and use to for CONGESTION CONTROL! | ||
33 | * - check that '0xFFULL' really is sufficient for flow control! | ||
34 | * - revisit handling of 'unreliable' traffic! | ||
35 | * - revisit handling of 'out-of-order' option, especially in combination with/without 'reliable'. | ||
36 | * - figure out flow control without ACKs (unreliable traffic!) | ||
31 | */ | 37 | */ |
32 | |||
33 | #include "platform.h" | 38 | #include "platform.h" |
34 | #include "gnunet_util_lib.h" | 39 | #include "gnunet_util_lib.h" |
35 | #include "cadet.h" | 40 | #include "cadet.h" |
@@ -41,7 +46,7 @@ | |||
41 | #include "gnunet-service-cadet-new_peer.h" | 46 | #include "gnunet-service-cadet-new_peer.h" |
42 | #include "gnunet-service-cadet-new_paths.h" | 47 | #include "gnunet-service-cadet-new_paths.h" |
43 | 48 | ||
44 | #define LOG(level, ...) GNUNET_log (level,__VA_ARGS__) | 49 | #define LOG(level,...) GNUNET_log_from (level,"cadet-chn",__VA_ARGS__) |
45 | 50 | ||
46 | /** | 51 | /** |
47 | * How long do we initially wait before retransmitting? | 52 | * How long do we initially wait before retransmitting? |
@@ -68,7 +73,7 @@ enum CadetChannelState | |||
68 | /** | 73 | /** |
69 | * Connection create message sent, waiting for ACK. | 74 | * Connection create message sent, waiting for ACK. |
70 | */ | 75 | */ |
71 | CADET_CHANNEL_CREATE_SENT, | 76 | CADET_CHANNEL_OPEN_SENT, |
72 | 77 | ||
73 | /** | 78 | /** |
74 | * Connection confirmed, ready to carry traffic. | 79 | * Connection confirmed, ready to carry traffic. |
@@ -121,9 +126,8 @@ struct CadetReliableMessage | |||
121 | /** | 126 | /** |
122 | * Data message we are trying to send. | 127 | * Data message we are trying to send. |
123 | */ | 128 | */ |
124 | struct GNUNET_CADET_ChannelAppDataMessage data_message; | 129 | struct GNUNET_CADET_ChannelAppDataMessage *data_message; |
125 | 130 | ||
126 | /* followed by variable-size payload */ | ||
127 | }; | 131 | }; |
128 | 132 | ||
129 | 133 | ||
@@ -143,7 +147,8 @@ struct CadetOutOfOrderMessage | |||
143 | struct CadetOutOfOrderMessage *prev; | 147 | struct CadetOutOfOrderMessage *prev; |
144 | 148 | ||
145 | /** | 149 | /** |
146 | * ID of the message (ACK needed to free) | 150 | * ID of the message (messages up to this point needed |
151 | * before we give this one to the client). | ||
147 | */ | 152 | */ |
148 | struct ChannelMessageIdentifier mid; | 153 | struct ChannelMessageIdentifier mid; |
149 | 154 | ||
@@ -156,6 +161,46 @@ struct CadetOutOfOrderMessage | |||
156 | 161 | ||
157 | 162 | ||
158 | /** | 163 | /** |
164 | * Client endpoint of a `struct CadetChannel`. A channel may be a | ||
165 | * loopback channel, in which case it has two of these endpoints. | ||
166 | * Note that flow control also is required in both directions. | ||
167 | */ | ||
168 | struct CadetChannelClient | ||
169 | { | ||
170 | /** | ||
171 | * Client handle. Not by itself sufficient to designate | ||
172 | * the client endpoint, as the same client handle may | ||
173 | * be used for both the owner and the destination, and | ||
174 | * we thus also need the channel ID to identify the client. | ||
175 | */ | ||
176 | struct CadetClient *c; | ||
177 | |||
178 | /** | ||
179 | * Head of DLL of messages received out of order or while client was unready. | ||
180 | */ | ||
181 | struct CadetOutOfOrderMessage *head_recv; | ||
182 | |||
183 | /** | ||
184 | * Tail DLL of messages received out of order or while client was unready. | ||
185 | */ | ||
186 | struct CadetOutOfOrderMessage *tail_recv; | ||
187 | |||
188 | /** | ||
189 | * Local tunnel number for this client. | ||
190 | * (if owner >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI, | ||
191 | * otherwise < #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
192 | */ | ||
193 | struct GNUNET_CADET_ClientChannelNumber ccn; | ||
194 | |||
195 | /** | ||
196 | * Can we send data to the client? | ||
197 | */ | ||
198 | int client_ready; | ||
199 | |||
200 | }; | ||
201 | |||
202 | |||
203 | /** | ||
159 | * Struct containing all information regarding a channel to a remote client. | 204 | * Struct containing all information regarding a channel to a remote client. |
160 | */ | 205 | */ |
161 | struct CadetChannel | 206 | struct CadetChannel |
@@ -166,24 +211,24 @@ struct CadetChannel | |||
166 | struct CadetTunnel *t; | 211 | struct CadetTunnel *t; |
167 | 212 | ||
168 | /** | 213 | /** |
169 | * Last entry in the tunnel's queue relating to control messages | ||
170 | * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or | ||
171 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel | ||
172 | * transmission in case we receive updated information. | ||
173 | */ | ||
174 | struct CadetTunnelQueueEntry *last_control_qe; | ||
175 | |||
176 | /** | ||
177 | * Client owner of the tunnel, if any. | 214 | * Client owner of the tunnel, if any. |
178 | * (Used if this channel represends the initiating end of the tunnel.) | 215 | * (Used if this channel represends the initiating end of the tunnel.) |
179 | */ | 216 | */ |
180 | struct CadetClient *owner; | 217 | struct CadetChannelClient *owner; |
181 | 218 | ||
182 | /** | 219 | /** |
183 | * Client destination of the tunnel, if any. | 220 | * Client destination of the tunnel, if any. |
184 | * (Used if this channel represents the listening end of the tunnel.) | 221 | * (Used if this channel represents the listening end of the tunnel.) |
185 | */ | 222 | */ |
186 | struct CadetClient *dest; | 223 | struct CadetChannelClient *dest; |
224 | |||
225 | /** | ||
226 | * Last entry in the tunnel's queue relating to control messages | ||
227 | * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or | ||
228 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel | ||
229 | * transmission in case we receive updated information. | ||
230 | */ | ||
231 | struct CadetTunnelQueueEntry *last_control_qe; | ||
187 | 232 | ||
188 | /** | 233 | /** |
189 | * Head of DLL of messages sent and not yet ACK'd. | 234 | * Head of DLL of messages sent and not yet ACK'd. |
@@ -196,19 +241,14 @@ struct CadetChannel | |||
196 | struct CadetReliableMessage *tail_sent; | 241 | struct CadetReliableMessage *tail_sent; |
197 | 242 | ||
198 | /** | 243 | /** |
199 | * Head of DLL of messages received out of order or while client was unready. | 244 | * Task to resend/poll in case no ACK is received. |
200 | */ | 245 | */ |
201 | struct CadetOutOfOrderMessage *head_recv; | 246 | struct GNUNET_SCHEDULER_Task *retry_control_task; |
202 | |||
203 | /** | ||
204 | * Tail DLL of messages received out of order or while client was unready. | ||
205 | */ | ||
206 | struct CadetOutOfOrderMessage *tail_recv; | ||
207 | 247 | ||
208 | /** | 248 | /** |
209 | * Task to resend/poll in case no ACK is received. | 249 | * Task to resend/poll in case no ACK is received. |
210 | */ | 250 | */ |
211 | struct GNUNET_SCHEDULER_Task *retry_task; | 251 | struct GNUNET_SCHEDULER_Task *retry_data_task; |
212 | 252 | ||
213 | /** | 253 | /** |
214 | * Last time the channel was used | 254 | * Last time the channel was used |
@@ -259,13 +299,7 @@ struct CadetChannel | |||
259 | /** | 299 | /** |
260 | * Number identifying this channel in its tunnel. | 300 | * Number identifying this channel in its tunnel. |
261 | */ | 301 | */ |
262 | struct GNUNET_CADET_ChannelTunnelNumber gid; | 302 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
263 | |||
264 | /** | ||
265 | * Local tunnel number for local client owning the channel. | ||
266 | * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 ) | ||
267 | */ | ||
268 | struct GNUNET_CADET_ClientChannelNumber lid; | ||
269 | 303 | ||
270 | /** | 304 | /** |
271 | * Channel state. | 305 | * Channel state. |
@@ -273,16 +307,6 @@ struct CadetChannel | |||
273 | enum CadetChannelState state; | 307 | enum CadetChannelState state; |
274 | 308 | ||
275 | /** | 309 | /** |
276 | * Can we send data to the client? | ||
277 | */ | ||
278 | int client_ready; | ||
279 | |||
280 | /** | ||
281 | * Can the client send data to us? | ||
282 | */ | ||
283 | int client_allowed; | ||
284 | |||
285 | /** | ||
286 | * Is the tunnel bufferless (minimum latency)? | 310 | * Is the tunnel bufferless (minimum latency)? |
287 | */ | 311 | */ |
288 | int nobuffer; | 312 | int nobuffer; |
@@ -298,6 +322,11 @@ struct CadetChannel | |||
298 | int out_of_order; | 322 | int out_of_order; |
299 | 323 | ||
300 | /** | 324 | /** |
325 | * Is this channel a loopback channel, where the destination is us again? | ||
326 | */ | ||
327 | int is_loopback; | ||
328 | |||
329 | /** | ||
301 | * Flag to signal the destruction of the channel. If this is set to | 330 | * Flag to signal the destruction of the channel. If this is set to |
302 | * #GNUNET_YES the channel will be destroyed once the queue is | 331 | * #GNUNET_YES the channel will be destroyed once the queue is |
303 | * empty. | 332 | * empty. |
@@ -307,7 +336,6 @@ struct CadetChannel | |||
307 | }; | 336 | }; |
308 | 337 | ||
309 | 338 | ||
310 | |||
311 | /** | 339 | /** |
312 | * Get the static string for identification of the channel. | 340 | * Get the static string for identification of the channel. |
313 | * | 341 | * |
@@ -320,15 +348,16 @@ GCCH_2s (const struct CadetChannel *ch) | |||
320 | { | 348 | { |
321 | static char buf[128]; | 349 | static char buf[128]; |
322 | 350 | ||
323 | if (NULL == ch) | ||
324 | return "(NULL Channel)"; | ||
325 | GNUNET_snprintf (buf, | 351 | GNUNET_snprintf (buf, |
326 | sizeof (buf), | 352 | sizeof (buf), |
327 | "%s:%s gid:%X (%X)", | 353 | "Channel %s:%s ctn:%X(%X/%X)", |
328 | GCT_2s (ch->t), | 354 | (GNUNET_YES == ch->is_loopback) |
355 | ? "loopback" | ||
356 | : GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))), | ||
329 | GNUNET_h2s (&ch->port), | 357 | GNUNET_h2s (&ch->port), |
330 | ch->gid, | 358 | ch->ctn, |
331 | ntohl (ch->lid.channel_of_client)); | 359 | (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client), |
360 | (NULL == ch->dest) ? 0 : ntohl (ch->dest->ccn.channel_of_client)); | ||
332 | return buf; | 361 | return buf; |
333 | } | 362 | } |
334 | 363 | ||
@@ -343,7 +372,29 @@ GCCH_2s (const struct CadetChannel *ch) | |||
343 | struct GNUNET_CADET_ChannelTunnelNumber | 372 | struct GNUNET_CADET_ChannelTunnelNumber |
344 | GCCH_get_id (const struct CadetChannel *ch) | 373 | GCCH_get_id (const struct CadetChannel *ch) |
345 | { | 374 | { |
346 | return ch->gid; | 375 | return ch->ctn; |
376 | } | ||
377 | |||
378 | |||
379 | /** | ||
380 | * Release memory associated with @a ccc | ||
381 | * | ||
382 | * @param ccc data structure to clean up | ||
383 | */ | ||
384 | static void | ||
385 | free_channel_client (struct CadetChannelClient *ccc) | ||
386 | { | ||
387 | struct CadetOutOfOrderMessage *com; | ||
388 | |||
389 | while (NULL != (com = ccc->head_recv)) | ||
390 | { | ||
391 | GNUNET_CONTAINER_DLL_remove (ccc->head_recv, | ||
392 | ccc->tail_recv, | ||
393 | com); | ||
394 | GNUNET_MQ_discard (com->env); | ||
395 | GNUNET_free (com); | ||
396 | } | ||
397 | GNUNET_free (ccc); | ||
347 | } | 398 | } |
348 | 399 | ||
349 | 400 | ||
@@ -356,7 +407,6 @@ static void | |||
356 | channel_destroy (struct CadetChannel *ch) | 407 | channel_destroy (struct CadetChannel *ch) |
357 | { | 408 | { |
358 | struct CadetReliableMessage *crm; | 409 | struct CadetReliableMessage *crm; |
359 | struct CadetOutOfOrderMessage *com; | ||
360 | 410 | ||
361 | while (NULL != (crm = ch->head_sent)) | 411 | while (NULL != (crm = ch->head_sent)) |
362 | { | 412 | { |
@@ -369,29 +419,41 @@ channel_destroy (struct CadetChannel *ch) | |||
369 | GNUNET_CONTAINER_DLL_remove (ch->head_sent, | 419 | GNUNET_CONTAINER_DLL_remove (ch->head_sent, |
370 | ch->tail_sent, | 420 | ch->tail_sent, |
371 | crm); | 421 | crm); |
422 | GNUNET_free (crm->data_message); | ||
372 | GNUNET_free (crm); | 423 | GNUNET_free (crm); |
373 | } | 424 | } |
374 | while (NULL != (com = ch->head_recv)) | 425 | if (NULL != ch->owner) |
375 | { | 426 | { |
376 | GNUNET_CONTAINER_DLL_remove (ch->head_recv, | 427 | free_channel_client (ch->owner); |
377 | ch->tail_recv, | 428 | ch->owner = NULL; |
378 | com); | 429 | } |
379 | GNUNET_MQ_discard (com->env); | 430 | if (NULL != ch->dest) |
380 | GNUNET_free (com); | 431 | { |
432 | free_channel_client (ch->dest); | ||
433 | ch->dest = NULL; | ||
381 | } | 434 | } |
382 | if (NULL != ch->last_control_qe) | 435 | if (NULL != ch->last_control_qe) |
383 | { | 436 | { |
384 | GCT_send_cancel (ch->last_control_qe); | 437 | GCT_send_cancel (ch->last_control_qe); |
385 | ch->last_control_qe = NULL; | 438 | ch->last_control_qe = NULL; |
386 | } | 439 | } |
387 | if (NULL != ch->retry_task) | 440 | if (NULL != ch->retry_data_task) |
441 | { | ||
442 | GNUNET_SCHEDULER_cancel (ch->retry_data_task); | ||
443 | ch->retry_data_task = NULL; | ||
444 | } | ||
445 | if (NULL != ch->retry_control_task) | ||
388 | { | 446 | { |
389 | GNUNET_SCHEDULER_cancel (ch->retry_task); | 447 | GNUNET_SCHEDULER_cancel (ch->retry_control_task); |
390 | ch->retry_task = NULL; | 448 | ch->retry_control_task = NULL; |
449 | } | ||
450 | if (GNUNET_NO == ch->is_loopback) | ||
451 | { | ||
452 | GCT_remove_channel (ch->t, | ||
453 | ch, | ||
454 | ch->ctn); | ||
455 | ch->t = NULL; | ||
391 | } | 456 | } |
392 | GCT_remove_channel (ch->t, | ||
393 | ch, | ||
394 | ch->gid); | ||
395 | GNUNET_free (ch); | 457 | GNUNET_free (ch); |
396 | } | 458 | } |
397 | 459 | ||
@@ -402,7 +464,7 @@ channel_destroy (struct CadetChannel *ch) | |||
402 | * @param cls Channel for which to send. | 464 | * @param cls Channel for which to send. |
403 | */ | 465 | */ |
404 | static void | 466 | static void |
405 | send_create (void *cls); | 467 | send_channel_open (void *cls); |
406 | 468 | ||
407 | 469 | ||
408 | /** | 470 | /** |
@@ -412,30 +474,41 @@ send_create (void *cls); | |||
412 | * @param cls our `struct CadetChannel`. | 474 | * @param cls our `struct CadetChannel`. |
413 | */ | 475 | */ |
414 | static void | 476 | static void |
415 | create_sent_cb (void *cls) | 477 | channel_open_sent_cb (void *cls) |
416 | { | 478 | { |
417 | struct CadetChannel *ch = cls; | 479 | struct CadetChannel *ch = cls; |
418 | 480 | ||
481 | GNUNET_assert (NULL != ch->last_control_qe); | ||
419 | ch->last_control_qe = NULL; | 482 | ch->last_control_qe = NULL; |
420 | ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time); | 483 | ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time); |
421 | ch->retry_task = GNUNET_SCHEDULER_add_delayed (ch->retry_time, | 484 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
422 | &send_create, | 485 | "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n", |
423 | ch); | 486 | GCCH_2s (ch), |
487 | GNUNET_STRINGS_relative_time_to_string (ch->retry_time, | ||
488 | GNUNET_YES)); | ||
489 | ch->retry_control_task | ||
490 | = GNUNET_SCHEDULER_add_delayed (ch->retry_time, | ||
491 | &send_channel_open, | ||
492 | ch); | ||
424 | } | 493 | } |
425 | 494 | ||
426 | 495 | ||
427 | /** | 496 | /** |
428 | * Send a channel create message. | 497 | * Send a channel open message. |
429 | * | 498 | * |
430 | * @param cls Channel for which to send. | 499 | * @param cls Channel for which to send. |
431 | */ | 500 | */ |
432 | static void | 501 | static void |
433 | send_create (void *cls) | 502 | send_channel_open (void *cls) |
434 | { | 503 | { |
435 | struct CadetChannel *ch = cls; | 504 | struct CadetChannel *ch = cls; |
436 | struct GNUNET_CADET_ChannelOpenMessage msgcc; | 505 | struct GNUNET_CADET_ChannelOpenMessage msgcc; |
437 | uint32_t options; | 506 | uint32_t options; |
438 | 507 | ||
508 | ch->retry_control_task = NULL; | ||
509 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
510 | "Sending CHANNEL_OPEN message for %s\n", | ||
511 | GCCH_2s (ch)); | ||
439 | options = 0; | 512 | options = 0; |
440 | if (ch->nobuffer) | 513 | if (ch->nobuffer) |
441 | options |= GNUNET_CADET_OPTION_NOBUFFER; | 514 | options |= GNUNET_CADET_OPTION_NOBUFFER; |
@@ -447,20 +520,43 @@ send_create (void *cls) | |||
447 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 520 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); |
448 | msgcc.opt = htonl (options); | 521 | msgcc.opt = htonl (options); |
449 | msgcc.port = ch->port; | 522 | msgcc.port = ch->port; |
450 | msgcc.chid = ch->gid; | 523 | msgcc.ctn = ch->ctn; |
451 | ch->state = CADET_CHANNEL_CREATE_SENT; | 524 | ch->state = CADET_CHANNEL_OPEN_SENT; |
452 | ch->last_control_qe = GCT_send (ch->t, | 525 | ch->last_control_qe = GCT_send (ch->t, |
453 | &msgcc.header, | 526 | &msgcc.header, |
454 | &create_sent_cb, | 527 | &channel_open_sent_cb, |
455 | ch); | 528 | ch); |
456 | } | 529 | } |
457 | 530 | ||
458 | 531 | ||
459 | /** | 532 | /** |
533 | * Function called once and only once after a channel was bound | ||
534 | * to its tunnel via #GCT_add_channel() is ready for transmission. | ||
535 | * Note that this is only the case for channels that this peer | ||
536 | * initiates, as for incoming channels we assume that they are | ||
537 | * ready for transmission immediately upon receiving the open | ||
538 | * message. Used to bootstrap the #GCT_send() process. | ||
539 | * | ||
540 | * @param ch the channel for which the tunnel is now ready | ||
541 | */ | ||
542 | void | ||
543 | GCCH_tunnel_up (struct CadetChannel *ch) | ||
544 | { | ||
545 | GNUNET_assert (NULL == ch->retry_control_task); | ||
546 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
547 | "Tunnel up, sending CHANNEL_OPEN on %s now\n", | ||
548 | GCCH_2s (ch)); | ||
549 | ch->retry_control_task | ||
550 | = GNUNET_SCHEDULER_add_now (&send_channel_open, | ||
551 | ch); | ||
552 | } | ||
553 | |||
554 | |||
555 | /** | ||
460 | * Create a new channel. | 556 | * Create a new channel. |
461 | * | 557 | * |
462 | * @param owner local client owning the channel | 558 | * @param owner local client owning the channel |
463 | * @param owner_id local chid of this channel at the @a owner | 559 | * @param ccn local number of this channel at the @a owner |
464 | * @param destination peer to which we should build the channel | 560 | * @param destination peer to which we should build the channel |
465 | * @param port desired port at @a destination | 561 | * @param port desired port at @a destination |
466 | * @param options options for the channel | 562 | * @param options options for the channel |
@@ -468,33 +564,74 @@ send_create (void *cls) | |||
468 | */ | 564 | */ |
469 | struct CadetChannel * | 565 | struct CadetChannel * |
470 | GCCH_channel_local_new (struct CadetClient *owner, | 566 | GCCH_channel_local_new (struct CadetClient *owner, |
471 | struct GNUNET_CADET_ClientChannelNumber owner_id, | 567 | struct GNUNET_CADET_ClientChannelNumber ccn, |
472 | struct CadetPeer *destination, | 568 | struct CadetPeer *destination, |
473 | const struct GNUNET_HashCode *port, | 569 | const struct GNUNET_HashCode *port, |
474 | uint32_t options) | 570 | uint32_t options) |
475 | { | 571 | { |
476 | struct CadetChannel *ch; | 572 | struct CadetChannel *ch; |
573 | struct CadetChannelClient *ccco; | ||
574 | |||
575 | ccco = GNUNET_new (struct CadetChannelClient); | ||
576 | ccco->c = owner; | ||
577 | ccco->ccn = ccn; | ||
578 | ccco->client_ready = GNUNET_YES; | ||
477 | 579 | ||
478 | ch = GNUNET_new (struct CadetChannel); | 580 | ch = GNUNET_new (struct CadetChannel); |
479 | ch->max_pending_messages = 32; /* FIXME: allow control via options | 581 | ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */ |
480 | or adjust dynamically... */ | ||
481 | ch->owner = owner; | ||
482 | ch->lid = owner_id; | ||
483 | ch->port = *port; | ||
484 | ch->t = GCP_get_tunnel (destination, | ||
485 | GNUNET_YES); | ||
486 | ch->gid = GCT_add_channel (ch->t, | ||
487 | ch); | ||
488 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; | ||
489 | ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); | 582 | ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); |
490 | ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); | 583 | ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); |
491 | ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER)); | 584 | ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER)); |
492 | ch->retry_task = GNUNET_SCHEDULER_add_now (&send_create, | 585 | ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */ |
493 | ch); | 586 | ch->owner = ccco; |
587 | ch->port = *port; | ||
588 | if (0 == memcmp (&my_full_id, | ||
589 | GCP_get_id (destination), | ||
590 | sizeof (struct GNUNET_PeerIdentity))) | ||
591 | { | ||
592 | struct CadetClient *c; | ||
593 | |||
594 | ch->is_loopback = GNUNET_YES; | ||
595 | c = GNUNET_CONTAINER_multihashmap_get (open_ports, | ||
596 | port); | ||
597 | if (NULL == c) | ||
598 | { | ||
599 | /* port closed, wait for it to possibly open */ | ||
600 | (void) GNUNET_CONTAINER_multihashmap_put (loose_channels, | ||
601 | port, | ||
602 | ch, | ||
603 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
604 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
605 | "Created loose incoming loopback channel to port %s\n", | ||
606 | GNUNET_h2s (&ch->port)); | ||
607 | } | ||
608 | else | ||
609 | { | ||
610 | ch->dest = GNUNET_new (struct CadetChannelClient); | ||
611 | ch->dest->c = c; | ||
612 | ch->dest->client_ready = GNUNET_YES; | ||
613 | GCCH_bind (ch, | ||
614 | ch->dest->c); | ||
615 | } | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | ch->t = GCP_get_tunnel (destination, | ||
620 | GNUNET_YES); | ||
621 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; | ||
622 | ch->ctn = GCT_add_channel (ch->t, | ||
623 | ch); | ||
624 | } | ||
494 | GNUNET_STATISTICS_update (stats, | 625 | GNUNET_STATISTICS_update (stats, |
495 | "# channels", | 626 | "# channels", |
496 | 1, | 627 | 1, |
497 | GNUNET_NO); | 628 | GNUNET_NO); |
629 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
630 | "Created channel to port %s at peer %s for %s using %s\n", | ||
631 | GNUNET_h2s (port), | ||
632 | GCP_2s (destination), | ||
633 | GSC_2s (owner), | ||
634 | (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t)); | ||
498 | return ch; | 635 | return ch; |
499 | } | 636 | } |
500 | 637 | ||
@@ -510,23 +647,27 @@ timeout_closed_cb (void *cls) | |||
510 | { | 647 | { |
511 | struct CadetChannel *ch = cls; | 648 | struct CadetChannel *ch = cls; |
512 | 649 | ||
513 | ch->retry_task = NULL; | 650 | ch->retry_control_task = NULL; |
651 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
652 | "Closing incoming channel to port %s from peer %s due to timeout\n", | ||
653 | GNUNET_h2s (&ch->port), | ||
654 | GCP_2s (GCT_get_destination (ch->t))); | ||
514 | channel_destroy (ch); | 655 | channel_destroy (ch); |
515 | } | 656 | } |
516 | 657 | ||
517 | 658 | ||
518 | /** | 659 | /** |
519 | * Create a new channel. | 660 | * Create a new channel based on a request coming in over the network. |
520 | * | 661 | * |
521 | * @param t tunnel to the remote peer | 662 | * @param t tunnel to the remote peer |
522 | * @param gid identifier of this channel in the tunnel | 663 | * @param ctn identifier of this channel in the tunnel |
523 | * @param port desired local port | 664 | * @param port desired local port |
524 | * @param options options for the channel | 665 | * @param options options for the channel |
525 | * @return handle to the new channel | 666 | * @return handle to the new channel |
526 | */ | 667 | */ |
527 | struct CadetChannel * | 668 | struct CadetChannel * |
528 | GCCH_channel_incoming_new (struct CadetTunnel *t, | 669 | GCCH_channel_incoming_new (struct CadetTunnel *t, |
529 | struct GNUNET_CADET_ChannelTunnelNumber gid, | 670 | struct GNUNET_CADET_ChannelTunnelNumber ctn, |
530 | const struct GNUNET_HashCode *port, | 671 | const struct GNUNET_HashCode *port, |
531 | uint32_t options) | 672 | uint32_t options) |
532 | { | 673 | { |
@@ -534,15 +675,14 @@ GCCH_channel_incoming_new (struct CadetTunnel *t, | |||
534 | struct CadetClient *c; | 675 | struct CadetClient *c; |
535 | 676 | ||
536 | ch = GNUNET_new (struct CadetChannel); | 677 | ch = GNUNET_new (struct CadetChannel); |
537 | ch->max_pending_messages = 32; /* FIXME: allow control via options | ||
538 | or adjust dynamically... */ | ||
539 | ch->port = *port; | 678 | ch->port = *port; |
540 | ch->t = t; | 679 | ch->t = t; |
541 | ch->gid = gid; | 680 | ch->ctn = ctn; |
542 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; | 681 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; |
543 | ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); | 682 | ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); |
544 | ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); | 683 | ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); |
545 | ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER)); | 684 | ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER)); |
685 | ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */ | ||
546 | GNUNET_STATISTICS_update (stats, | 686 | GNUNET_STATISTICS_update (stats, |
547 | "# channels", | 687 | "# channels", |
548 | 1, | 688 | 1, |
@@ -557,9 +697,14 @@ GCCH_channel_incoming_new (struct CadetTunnel *t, | |||
557 | port, | 697 | port, |
558 | ch, | 698 | ch, |
559 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 699 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
560 | ch->retry_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT, | 700 | ch->retry_control_task |
561 | &timeout_closed_cb, | 701 | = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT, |
562 | ch); | 702 | &timeout_closed_cb, |
703 | ch); | ||
704 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
705 | "Created loose incoming channel to port %s from peer %s\n", | ||
706 | GNUNET_h2s (&ch->port), | ||
707 | GCP_2s (GCT_get_destination (ch->t))); | ||
563 | } | 708 | } |
564 | else | 709 | else |
565 | { | 710 | { |
@@ -586,23 +731,24 @@ send_ack_cb (void *cls) | |||
586 | { | 731 | { |
587 | struct CadetChannel *ch = cls; | 732 | struct CadetChannel *ch = cls; |
588 | 733 | ||
734 | GNUNET_assert (NULL != ch->last_control_qe); | ||
589 | ch->last_control_qe = NULL; | 735 | ch->last_control_qe = NULL; |
590 | } | 736 | } |
591 | 737 | ||
592 | 738 | ||
593 | /** | 739 | /** |
594 | * Compute and send the current ACK to the other peer. | 740 | * Compute and send the current #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer. |
595 | * | 741 | * |
596 | * @param ch channel to send the ACK for | 742 | * @param ch channel to send the #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK for |
597 | */ | 743 | */ |
598 | static void | 744 | static void |
599 | send_channel_ack (struct CadetChannel *ch) | 745 | send_channel_data_ack (struct CadetChannel *ch) |
600 | { | 746 | { |
601 | struct GNUNET_CADET_ChannelDataAckMessage msg; | 747 | struct GNUNET_CADET_ChannelDataAckMessage msg; |
602 | 748 | ||
603 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); | 749 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); |
604 | msg.header.size = htons (sizeof (msg)); | 750 | msg.header.size = htons (sizeof (msg)); |
605 | msg.gid = ch->gid; | 751 | msg.ctn = ch->ctn; |
606 | msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1); | 752 | msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1); |
607 | msg.futures = GNUNET_htonll (ch->mid_futures); | 753 | msg.futures = GNUNET_htonll (ch->mid_futures); |
608 | if (NULL != ch->last_control_qe) | 754 | if (NULL != ch->last_control_qe) |
@@ -615,18 +761,93 @@ send_channel_ack (struct CadetChannel *ch) | |||
615 | 761 | ||
616 | 762 | ||
617 | /** | 763 | /** |
618 | * Send our initial ACK to the client confirming that the | 764 | * Send our initial #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the |
619 | * connection is up. | 765 | * connection is up. |
620 | * | 766 | * |
621 | * @param cls the `struct CadetChannel` | 767 | * @param cls the `struct CadetChannel` |
622 | */ | 768 | */ |
623 | static void | 769 | static void |
624 | send_connect_ack (void *cls) | 770 | send_open_ack (void *cls) |
625 | { | 771 | { |
626 | struct CadetChannel *ch = cls; | 772 | struct CadetChannel *ch = cls; |
773 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
627 | 774 | ||
628 | ch->retry_task = NULL; | 775 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
629 | send_channel_ack (ch); | 776 | "Sending CHANNEL_OPEN_ACK on %s\n", |
777 | GCCH_2s (ch)); | ||
778 | ch->retry_control_task = NULL; | ||
779 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK); | ||
780 | msg.header.size = htons (sizeof (msg)); | ||
781 | msg.reserved = htonl (0); | ||
782 | msg.ctn = ch->ctn; | ||
783 | if (NULL != ch->last_control_qe) | ||
784 | GCT_send_cancel (ch->last_control_qe); | ||
785 | ch->last_control_qe = GCT_send (ch->t, | ||
786 | &msg.header, | ||
787 | &send_ack_cb, | ||
788 | ch); | ||
789 | } | ||
790 | |||
791 | |||
792 | /** | ||
793 | * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for | ||
794 | * this channel. If the binding was successful, (re)transmit the | ||
795 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK. | ||
796 | * | ||
797 | * @param ch channel that got the duplicate open | ||
798 | */ | ||
799 | void | ||
800 | GCCH_handle_duplicate_open (struct CadetChannel *ch) | ||
801 | { | ||
802 | if (NULL == ch->dest) | ||
803 | { | ||
804 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
805 | "Ignoring duplicate channel OPEN on %s: port is closed\n", | ||
806 | GCCH_2s (ch)); | ||
807 | return; | ||
808 | } | ||
809 | if (NULL != ch->retry_control_task) | ||
810 | { | ||
811 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
812 | "Ignoring duplicate channel OPEN on %s: control message is pending\n", | ||
813 | GCCH_2s (ch)); | ||
814 | return; | ||
815 | } | ||
816 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
817 | "Retransmitting OPEN_ACK on %s\n", | ||
818 | GCCH_2s (ch)); | ||
819 | ch->retry_control_task | ||
820 | = GNUNET_SCHEDULER_add_now (&send_open_ack, | ||
821 | ch); | ||
822 | } | ||
823 | |||
824 | |||
825 | /** | ||
826 | * Send a #GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages. | ||
827 | * | ||
828 | * @param ch channel the ack is for | ||
829 | * @param to_owner #GNUNET_YES to send to owner, | ||
830 | * #GNUNET_NO to send to dest | ||
831 | */ | ||
832 | static void | ||
833 | send_ack_to_client (struct CadetChannel *ch, | ||
834 | int to_owner) | ||
835 | { | ||
836 | struct GNUNET_MQ_Envelope *env; | ||
837 | struct GNUNET_CADET_LocalAck *ack; | ||
838 | struct CadetChannelClient *ccc; | ||
839 | |||
840 | env = GNUNET_MQ_msg (ack, | ||
841 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); | ||
842 | ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest; | ||
843 | ack->ccn = ccc->ccn; | ||
844 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
845 | "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X\n", | ||
846 | GSC_2s (ccc->c), | ||
847 | (GNUNET_YES == to_owner) ? "owner" : "dest", | ||
848 | ntohl (ack->ccn.channel_of_client)); | ||
849 | GSC_send_to_client (ccc->c, | ||
850 | env); | ||
630 | } | 851 | } |
631 | 852 | ||
632 | 853 | ||
@@ -643,12 +864,19 @@ GCCH_bind (struct CadetChannel *ch, | |||
643 | struct CadetClient *c) | 864 | struct CadetClient *c) |
644 | { | 865 | { |
645 | uint32_t options; | 866 | uint32_t options; |
867 | struct CadetChannelClient *cccd; | ||
646 | 868 | ||
647 | if (NULL != ch->retry_task) | 869 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
870 | "Binding %s from %s to port %s of %s\n", | ||
871 | GCCH_2s (ch), | ||
872 | GCT_2s (ch->t), | ||
873 | GNUNET_h2s (&ch->port), | ||
874 | GSC_2s (c)); | ||
875 | if (NULL != ch->retry_control_task) | ||
648 | { | 876 | { |
649 | /* there might be a timeout task here */ | 877 | /* there might be a timeout task here */ |
650 | GNUNET_SCHEDULER_cancel (ch->retry_task); | 878 | GNUNET_SCHEDULER_cancel (ch->retry_control_task); |
651 | ch->retry_task = NULL; | 879 | ch->retry_control_task = NULL; |
652 | } | 880 | } |
653 | options = 0; | 881 | options = 0; |
654 | if (ch->nobuffer) | 882 | if (ch->nobuffer) |
@@ -657,29 +885,79 @@ GCCH_bind (struct CadetChannel *ch, | |||
657 | options |= GNUNET_CADET_OPTION_RELIABLE; | 885 | options |= GNUNET_CADET_OPTION_RELIABLE; |
658 | if (ch->out_of_order) | 886 | if (ch->out_of_order) |
659 | options |= GNUNET_CADET_OPTION_OUT_OF_ORDER; | 887 | options |= GNUNET_CADET_OPTION_OUT_OF_ORDER; |
660 | ch->dest = c; | 888 | cccd = GNUNET_new (struct CadetChannelClient); |
661 | ch->lid = GSC_bind (c, | 889 | ch->dest = cccd; |
662 | ch, | 890 | cccd->c = c; |
663 | GCT_get_destination (ch->t), | 891 | cccd->client_ready = GNUNET_YES; |
664 | &ch->port, | 892 | cccd->ccn = GSC_bind (c, |
665 | options); | 893 | ch, |
666 | ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */ | 894 | (GNUNET_YES == ch->is_loopback) |
667 | 895 | ? GCP_get (&my_full_id, | |
668 | /* notify other peer that we accepted the connection */ | 896 | GNUNET_YES) |
669 | ch->retry_task = GNUNET_SCHEDULER_add_now (&send_connect_ack, | 897 | : GCT_get_destination (ch->t), |
670 | ch); | 898 | &ch->port, |
899 | options); | ||
900 | GNUNET_assert (ntohl (cccd->ccn.channel_of_client) < | ||
901 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | ||
902 | ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */ | ||
903 | if (GNUNET_YES == ch->is_loopback) | ||
904 | { | ||
905 | ch->state = CADET_CHANNEL_OPEN_SENT; | ||
906 | GCCH_handle_channel_open_ack (ch); | ||
907 | } | ||
908 | else | ||
909 | { | ||
910 | /* notify other peer that we accepted the connection */ | ||
911 | ch->retry_control_task | ||
912 | = GNUNET_SCHEDULER_add_now (&send_open_ack, | ||
913 | ch); | ||
914 | } | ||
915 | /* give client it's initial supply of ACKs */ | ||
916 | GNUNET_assert (ntohl (cccd->ccn.channel_of_client) < | ||
917 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | ||
918 | for (unsigned int i=0;i<ch->max_pending_messages;i++) | ||
919 | send_ack_to_client (ch, | ||
920 | GNUNET_NO); | ||
671 | } | 921 | } |
672 | 922 | ||
673 | 923 | ||
674 | /** | 924 | /** |
675 | * Destroy locally created channel. Called by the | 925 | * Destroy locally created channel. Called by the local client, so no |
676 | * local client, so no need to tell the client. | 926 | * need to tell the client. |
677 | * | 927 | * |
678 | * @param ch channel to destroy | 928 | * @param ch channel to destroy |
929 | * @param c client that caused the destruction | ||
930 | * @param ccn client number of the client @a c | ||
679 | */ | 931 | */ |
680 | void | 932 | void |
681 | GCCH_channel_local_destroy (struct CadetChannel *ch) | 933 | GCCH_channel_local_destroy (struct CadetChannel *ch, |
934 | struct CadetClient *c, | ||
935 | struct GNUNET_CADET_ClientChannelNumber ccn) | ||
682 | { | 936 | { |
937 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
938 | "%s asks for destruction of %s\n", | ||
939 | GSC_2s (c), | ||
940 | GCCH_2s (ch)); | ||
941 | GNUNET_assert (NULL != c); | ||
942 | if ( (NULL != ch->owner) && | ||
943 | (c == ch->owner->c) && | ||
944 | (ccn.channel_of_client == ch->owner->ccn.channel_of_client) ) | ||
945 | { | ||
946 | free_channel_client (ch->owner); | ||
947 | ch->owner = NULL; | ||
948 | } | ||
949 | else if ( (NULL != ch->dest) && | ||
950 | (c == ch->dest->c) && | ||
951 | (ccn.channel_of_client == ch->dest->ccn.channel_of_client) ) | ||
952 | { | ||
953 | free_channel_client (ch->dest); | ||
954 | ch->dest = NULL; | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | GNUNET_assert (0); | ||
959 | } | ||
960 | |||
683 | if (GNUNET_YES == ch->destroy) | 961 | if (GNUNET_YES == ch->destroy) |
684 | { | 962 | { |
685 | /* other end already destroyed, with the local client gone, no need | 963 | /* other end already destroyed, with the local client gone, no need |
@@ -687,41 +965,279 @@ GCCH_channel_local_destroy (struct CadetChannel *ch) | |||
687 | channel_destroy (ch); | 965 | channel_destroy (ch); |
688 | return; | 966 | return; |
689 | } | 967 | } |
690 | if (NULL != ch->head_sent) | 968 | if ( (NULL != ch->head_sent) || |
969 | (NULL != ch->owner) || | ||
970 | (NULL != ch->dest) ) | ||
691 | { | 971 | { |
692 | /* allow send queue to train first */ | 972 | /* Wait for other end to destroy us as well, |
973 | and otherwise allow send queue to be transmitted first */ | ||
693 | ch->destroy = GNUNET_YES; | 974 | ch->destroy = GNUNET_YES; |
694 | return; | 975 | return; |
695 | } | 976 | } |
977 | /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */ | ||
978 | if (CADET_CHANNEL_NEW != ch->state) | ||
979 | GCT_send_channel_destroy (ch->t, | ||
980 | ch->ctn); | ||
696 | /* Nothing left to do, just finish destruction */ | 981 | /* Nothing left to do, just finish destruction */ |
697 | channel_destroy (ch); | 982 | channel_destroy (ch); |
698 | } | 983 | } |
699 | 984 | ||
700 | 985 | ||
701 | /** | 986 | /** |
702 | * Destroy channel that was incoming. Called by the | 987 | * We got an acknowledgement for the creation of the channel |
703 | * local client, so no need to tell the client. | 988 | * (the port is open on the other side). Begin transmissions. |
704 | * | 989 | * |
705 | * @param ch channel to destroy | 990 | * @param ch channel to destroy |
706 | */ | 991 | */ |
707 | void | 992 | void |
708 | GCCH_channel_incoming_destroy (struct CadetChannel *ch) | 993 | GCCH_handle_channel_open_ack (struct CadetChannel *ch) |
709 | { | 994 | { |
710 | if (GNUNET_YES == ch->destroy) | 995 | switch (ch->state) |
711 | { | 996 | { |
712 | /* other end already destroyed, with the remote client gone, no need | 997 | case CADET_CHANNEL_NEW: |
713 | to finish transmissions, just destroy immediately. */ | 998 | /* this should be impossible */ |
714 | channel_destroy (ch); | 999 | GNUNET_break (0); |
1000 | break; | ||
1001 | case CADET_CHANNEL_OPEN_SENT: | ||
1002 | if (NULL == ch->owner) | ||
1003 | { | ||
1004 | /* We're not the owner, wrong direction! */ | ||
1005 | GNUNET_break_op (0); | ||
1006 | return; | ||
1007 | } | ||
1008 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1009 | "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n", | ||
1010 | GCCH_2s (ch)); | ||
1011 | if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */ | ||
1012 | { | ||
1013 | GNUNET_SCHEDULER_cancel (ch->retry_control_task); | ||
1014 | ch->retry_control_task = NULL; | ||
1015 | } | ||
1016 | ch->state = CADET_CHANNEL_READY; | ||
1017 | /* On first connect, send client as many ACKs as we allow messages | ||
1018 | to be buffered! */ | ||
1019 | for (unsigned int i=0;i<ch->max_pending_messages;i++) | ||
1020 | send_ack_to_client (ch, | ||
1021 | GNUNET_YES); | ||
1022 | break; | ||
1023 | case CADET_CHANNEL_READY: | ||
1024 | /* duplicate ACK, maybe we retried the CREATE. Ignore. */ | ||
1025 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1026 | "Received duplicate channel OPEN_ACK for %s\n", | ||
1027 | GCCH_2s (ch)); | ||
1028 | GNUNET_STATISTICS_update (stats, | ||
1029 | "# duplicate CREATE_ACKs", | ||
1030 | 1, | ||
1031 | GNUNET_NO); | ||
1032 | break; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | |||
1037 | /** | ||
1038 | * Test if element @a e1 comes before element @a e2. | ||
1039 | * | ||
1040 | * TODO: use opportunity to create generic list insertion sort | ||
1041 | * logic in container! | ||
1042 | * | ||
1043 | * @param cls closure, our `struct CadetChannel` | ||
1044 | * @param e1 an element of to sort | ||
1045 | * @param e2 another element to sort | ||
1046 | * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO | ||
1047 | */ | ||
1048 | static int | ||
1049 | is_before (void *cls, | ||
1050 | void *e1, | ||
1051 | void *e2) | ||
1052 | { | ||
1053 | struct CadetOutOfOrderMessage *m1 = e1; | ||
1054 | struct CadetOutOfOrderMessage *m2 = e2; | ||
1055 | uint32_t v1 = ntohl (m1->mid.mid); | ||
1056 | uint32_t v2 = ntohl (m2->mid.mid); | ||
1057 | uint32_t delta; | ||
1058 | |||
1059 | delta = v1 - v2; | ||
1060 | if (delta > (uint32_t) INT_MAX) | ||
1061 | { | ||
1062 | /* in overflow range, we can safely assume we wrapped around */ | ||
1063 | return GNUNET_NO; | ||
1064 | } | ||
1065 | else | ||
1066 | { | ||
1067 | return GNUNET_YES; | ||
1068 | } | ||
1069 | } | ||
1070 | |||
1071 | |||
1072 | /** | ||
1073 | * We got payload data for a channel. Pass it on to the client | ||
1074 | * and send an ACK to the other end (once flow control allows it!) | ||
1075 | * | ||
1076 | * @param ch channel that got data | ||
1077 | * @param msg message that was received | ||
1078 | */ | ||
1079 | void | ||
1080 | GCCH_handle_channel_plaintext_data (struct CadetChannel *ch, | ||
1081 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | ||
1082 | { | ||
1083 | struct GNUNET_MQ_Envelope *env; | ||
1084 | struct GNUNET_CADET_LocalData *ld; | ||
1085 | struct CadetChannelClient *ccc; | ||
1086 | struct CadetOutOfOrderMessage *com; | ||
1087 | size_t payload_size; | ||
1088 | |||
1089 | GNUNET_assert (GNUNET_NO == ch->is_loopback); | ||
1090 | if ( (GNUNET_YES == ch->destroy) && | ||
1091 | (NULL == ch->owner) && | ||
1092 | (NULL == ch->dest) ) | ||
1093 | { | ||
1094 | /* This client is gone, but we still have messages to send to | ||
1095 | the other end (which is why @a ch is not yet dead). However, | ||
1096 | we cannot pass messages to our client anymore. */ | ||
1097 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1098 | "Dropping incoming payload on %s as this end is already closed\n", | ||
1099 | GCCH_2s (ch)); | ||
1100 | /* FIXME: send back ACK/NACK/Closed notification | ||
1101 | to stop retransmissions! */ | ||
715 | return; | 1102 | return; |
716 | } | 1103 | } |
717 | if (NULL != ch->head_recv) | 1104 | payload_size = ntohs (msg->header.size) - sizeof (*msg); |
1105 | env = GNUNET_MQ_msg_extra (ld, | ||
1106 | payload_size, | ||
1107 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); | ||
1108 | ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn; | ||
1109 | GNUNET_memcpy (&ld[1], | ||
1110 | &msg[1], | ||
1111 | payload_size); | ||
1112 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; | ||
1113 | if ( (GNUNET_YES == ccc->client_ready) && | ||
1114 | ( (GNUNET_YES == ch->out_of_order) || | ||
1115 | (msg->mid.mid == ch->mid_recv.mid) ) ) | ||
718 | { | 1116 | { |
719 | /* allow local client to see all data first */ | 1117 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
720 | ch->destroy = GNUNET_YES; | 1118 | "Giving %u bytes of payload from %s to client %s\n", |
1119 | (unsigned int) payload_size, | ||
1120 | GCCH_2s (ch), | ||
1121 | GSC_2s (ccc->c)); | ||
1122 | ccc->client_ready = GNUNET_NO; | ||
1123 | GSC_send_to_client (ccc->c, | ||
1124 | env); | ||
1125 | ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid)); | ||
1126 | ch->mid_futures >>= 1; | ||
1127 | } | ||
1128 | else | ||
1129 | { | ||
1130 | /* FIXME-SECURITY: if the element is WAY too far ahead, | ||
1131 | drop it (can't buffer too much!) */ | ||
1132 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1133 | "Queuing %s payload of %u bytes on %s (mid %u, need %u first)\n", | ||
1134 | (GNUNET_YES == ccc->client_ready) | ||
1135 | ? "out-of-order" | ||
1136 | : "client-not-ready", | ||
1137 | (unsigned int) payload_size, | ||
1138 | GCCH_2s (ch), | ||
1139 | ntohl (msg->mid.mid), | ||
1140 | ntohl (ch->mid_recv.mid)); | ||
1141 | |||
1142 | com = GNUNET_new (struct CadetOutOfOrderMessage); | ||
1143 | com->mid = msg->mid; | ||
1144 | com->env = env; | ||
1145 | /* sort into list ordered by "is_before" */ | ||
1146 | if ( (NULL == ccc->head_recv) || | ||
1147 | (GNUNET_YES == is_before (ch, | ||
1148 | com, | ||
1149 | ccc->head_recv)) ) | ||
1150 | { | ||
1151 | GNUNET_CONTAINER_DLL_insert (ccc->head_recv, | ||
1152 | ccc->tail_recv, | ||
1153 | com); | ||
1154 | } | ||
1155 | else | ||
1156 | { | ||
1157 | struct CadetOutOfOrderMessage *pos; | ||
1158 | |||
1159 | for (pos = ccc->head_recv; | ||
1160 | NULL != pos; | ||
1161 | pos = pos->next) | ||
1162 | { | ||
1163 | if (GNUNET_YES != | ||
1164 | is_before (NULL, | ||
1165 | pos, | ||
1166 | com)) | ||
1167 | break; | ||
1168 | } | ||
1169 | if (NULL == pos) | ||
1170 | GNUNET_CONTAINER_DLL_insert_tail (ccc->head_recv, | ||
1171 | ccc->tail_recv, | ||
1172 | com); | ||
1173 | else | ||
1174 | GNUNET_CONTAINER_DLL_insert_after (ccc->head_recv, | ||
1175 | ccc->tail_recv, | ||
1176 | com, | ||
1177 | pos->prev); | ||
1178 | } | ||
1179 | } | ||
1180 | } | ||
1181 | |||
1182 | |||
1183 | /** | ||
1184 | * We got an acknowledgement for payload data for a channel. | ||
1185 | * Possibly resume transmissions. | ||
1186 | * | ||
1187 | * @param ch channel that got the ack | ||
1188 | * @param ack details about what was received | ||
1189 | */ | ||
1190 | void | ||
1191 | GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch, | ||
1192 | const struct GNUNET_CADET_ChannelDataAckMessage *ack) | ||
1193 | { | ||
1194 | struct CadetReliableMessage *crm; | ||
1195 | |||
1196 | GNUNET_break (GNUNET_NO == ch->is_loopback); | ||
1197 | if (GNUNET_NO == ch->reliable) | ||
1198 | { | ||
1199 | /* not expecting ACKs on unreliable channel, odd */ | ||
1200 | GNUNET_break_op (0); | ||
721 | return; | 1201 | return; |
722 | } | 1202 | } |
723 | /* Nothing left to do, just finish destruction */ | 1203 | for (crm = ch->head_sent; |
724 | channel_destroy (ch); | 1204 | NULL != crm; |
1205 | crm = crm->next) | ||
1206 | if (ack->mid.mid == crm->data_message->mid.mid) | ||
1207 | break; | ||
1208 | if (NULL == crm) | ||
1209 | { | ||
1210 | /* ACK for message we already dropped, might have been a | ||
1211 | duplicate ACK? Ignore. */ | ||
1212 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1213 | "Duplicate DATA_ACK on %s, ignoring\n", | ||
1214 | GCCH_2s (ch)); | ||
1215 | GNUNET_STATISTICS_update (stats, | ||
1216 | "# duplicate DATA_ACKs", | ||
1217 | 1, | ||
1218 | GNUNET_NO); | ||
1219 | return; | ||
1220 | } | ||
1221 | GNUNET_CONTAINER_DLL_remove (ch->head_sent, | ||
1222 | ch->tail_sent, | ||
1223 | crm); | ||
1224 | GNUNET_free (crm->data_message); | ||
1225 | GNUNET_free (crm); | ||
1226 | ch->pending_messages--; | ||
1227 | send_ack_to_client (ch, | ||
1228 | (NULL == ch->owner) | ||
1229 | ? GNUNET_NO | ||
1230 | : GNUNET_YES); | ||
1231 | GNUNET_assert (ch->pending_messages < ch->max_pending_messages); | ||
1232 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1233 | "Received DATA_ACK on %s for message %u (%u ACKs pending)\n", | ||
1234 | GCCH_2s (ch), | ||
1235 | (unsigned int) ntohl (ack->mid.mid), | ||
1236 | ch->pending_messages); | ||
1237 | send_ack_to_client (ch, | ||
1238 | (NULL == ch->owner) | ||
1239 | ? GNUNET_NO | ||
1240 | : GNUNET_YES); | ||
725 | } | 1241 | } |
726 | 1242 | ||
727 | 1243 | ||
@@ -730,19 +1246,36 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch) | |||
730 | * connection. Also needs to remove this channel from | 1246 | * connection. Also needs to remove this channel from |
731 | * the tunnel. | 1247 | * the tunnel. |
732 | * | 1248 | * |
733 | * FIXME: need to make it possible to defer destruction until we have | ||
734 | * received all messages up to the destroy, and right now the destroy | ||
735 | * message (and this API) fails to give is the information we need! | ||
736 | * | ||
737 | * FIXME: also need to know if the other peer got a destroy from | ||
738 | * us before! | ||
739 | * | ||
740 | * @param ch channel to destroy | 1249 | * @param ch channel to destroy |
741 | */ | 1250 | */ |
742 | void | 1251 | void |
743 | GCCH_channel_remote_destroy (struct CadetChannel *ch) | 1252 | GCCH_handle_remote_destroy (struct CadetChannel *ch) |
744 | { | 1253 | { |
745 | GNUNET_break (0); // FIXME! | 1254 | struct CadetChannelClient *ccc; |
1255 | |||
1256 | GNUNET_assert (GNUNET_NO == ch->is_loopback); | ||
1257 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1258 | "Received remote channel DESTROY for %s\n", | ||
1259 | GCCH_2s (ch)); | ||
1260 | if (GNUNET_YES == ch->destroy) | ||
1261 | { | ||
1262 | /* Local client already gone, this is instant-death. */ | ||
1263 | channel_destroy (ch); | ||
1264 | return; | ||
1265 | } | ||
1266 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; | ||
1267 | if (NULL != ccc->head_recv) | ||
1268 | { | ||
1269 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1270 | "Lost end of transmission due to remote shutdown on %s\n", | ||
1271 | GCCH_2s (ch)); | ||
1272 | /* FIXME: change API to notify client about truncated transmission! */ | ||
1273 | } | ||
1274 | ch->destroy = GNUNET_YES; | ||
1275 | GSC_handle_remote_channel_destroy (ccc->c, | ||
1276 | ccc->ccn, | ||
1277 | ch); | ||
1278 | channel_destroy (ch); | ||
746 | } | 1279 | } |
747 | 1280 | ||
748 | 1281 | ||
@@ -770,67 +1303,16 @@ retry_transmission (void *cls) | |||
770 | struct CadetChannel *ch = cls; | 1303 | struct CadetChannel *ch = cls; |
771 | struct CadetReliableMessage *crm = ch->head_sent; | 1304 | struct CadetReliableMessage *crm = ch->head_sent; |
772 | 1305 | ||
1306 | ch->retry_data_task = NULL; | ||
773 | GNUNET_assert (NULL == crm->qe); | 1307 | GNUNET_assert (NULL == crm->qe); |
774 | crm->qe = GCT_send (ch->t, | 1308 | crm->qe = GCT_send (ch->t, |
775 | &crm->data_message.header, | 1309 | &crm->data_message->header, |
776 | &data_sent_cb, | 1310 | &data_sent_cb, |
777 | crm); | 1311 | crm); |
778 | } | 1312 | } |
779 | 1313 | ||
780 | 1314 | ||
781 | /** | 1315 | /** |
782 | * Check if we can now allow the client to transmit, and if so, | ||
783 | * let the client know about it. | ||
784 | * | ||
785 | * @param ch channel to check | ||
786 | */ | ||
787 | static void | ||
788 | GCCH_check_allow_client (struct CadetChannel *ch) | ||
789 | { | ||
790 | struct GNUNET_MQ_Envelope *env; | ||
791 | struct GNUNET_CADET_LocalAck *msg; | ||
792 | |||
793 | if (GNUNET_YES == ch->client_allowed) | ||
794 | return; /* client already allowed! */ | ||
795 | if (CADET_CHANNEL_READY != ch->state) | ||
796 | { | ||
797 | /* destination did not yet ACK our CREATE! */ | ||
798 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
799 | "Channel %s not yet ready, throttling client until ACK.\n", | ||
800 | GCCH_2s (ch)); | ||
801 | return; | ||
802 | } | ||
803 | if (ch->pending_messages > ch->max_pending_messages) | ||
804 | { | ||
805 | /* Too many messages in queue. */ | ||
806 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
807 | "Message queue still too long on channel %s, throttling client until ACK.\n", | ||
808 | GCCH_2s (ch)); | ||
809 | return; | ||
810 | } | ||
811 | if ( (NULL != ch->head_sent) && | ||
812 | (64 <= ntohl (ch->mid_send.mid) - ntohl (ch->head_sent->data_message.mid.mid)) ) | ||
813 | { | ||
814 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
815 | "Gap in ACKs too big on channel %s, throttling client until ACK.\n", | ||
816 | GCCH_2s (ch)); | ||
817 | return; | ||
818 | } | ||
819 | ch->client_allowed = GNUNET_YES; | ||
820 | |||
821 | |||
822 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
823 | "Sending local ack to channel %s client\n", | ||
824 | GCCH_2s (ch)); | ||
825 | env = GNUNET_MQ_msg (msg, | ||
826 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); | ||
827 | msg->channel_id = ch->lid; | ||
828 | GSC_send_to_client (ch->owner ? ch->owner : ch->dest, | ||
829 | env); | ||
830 | } | ||
831 | |||
832 | |||
833 | /** | ||
834 | * Function called once the tunnel has sent one of our messages. | 1316 | * Function called once the tunnel has sent one of our messages. |
835 | * If the message is unreliable, simply frees the `crm`. If the | 1317 | * If the message is unreliable, simply frees the `crm`. If the |
836 | * message was reliable, calculate retransmission time and | 1318 | * message was reliable, calculate retransmission time and |
@@ -845,6 +1327,7 @@ data_sent_cb (void *cls) | |||
845 | struct CadetChannel *ch = crm->ch; | 1327 | struct CadetChannel *ch = crm->ch; |
846 | struct CadetReliableMessage *off; | 1328 | struct CadetReliableMessage *off; |
847 | 1329 | ||
1330 | GNUNET_assert (GNUNET_NO == ch->is_loopback); | ||
848 | crm->qe = NULL; | 1331 | crm->qe = NULL; |
849 | GNUNET_CONTAINER_DLL_remove (ch->head_sent, | 1332 | GNUNET_CONTAINER_DLL_remove (ch->head_sent, |
850 | ch->tail_sent, | 1333 | ch->tail_sent, |
@@ -853,7 +1336,10 @@ data_sent_cb (void *cls) | |||
853 | { | 1336 | { |
854 | GNUNET_free (crm); | 1337 | GNUNET_free (crm); |
855 | ch->pending_messages--; | 1338 | ch->pending_messages--; |
856 | GCCH_check_allow_client (ch); | 1339 | send_ack_to_client (ch, |
1340 | (NULL == ch->owner) | ||
1341 | ? GNUNET_NO | ||
1342 | : GNUNET_YES); | ||
857 | return; | 1343 | return; |
858 | } | 1344 | } |
859 | if (0 == crm->retry_delay.rel_value_us) | 1345 | if (0 == crm->retry_delay.rel_value_us) |
@@ -868,11 +1354,12 @@ data_sent_cb (void *cls) | |||
868 | GNUNET_CONTAINER_DLL_insert (ch->head_sent, | 1354 | GNUNET_CONTAINER_DLL_insert (ch->head_sent, |
869 | ch->tail_sent, | 1355 | ch->tail_sent, |
870 | crm); | 1356 | crm); |
871 | if (NULL != ch->retry_task) | 1357 | if (NULL != ch->retry_data_task) |
872 | GNUNET_SCHEDULER_cancel (ch->retry_task); | 1358 | GNUNET_SCHEDULER_cancel (ch->retry_data_task); |
873 | ch->retry_task = GNUNET_SCHEDULER_add_delayed (crm->retry_delay, | 1359 | ch->retry_data_task |
874 | &retry_transmission, | 1360 | = GNUNET_SCHEDULER_add_delayed (crm->retry_delay, |
875 | ch); | 1361 | &retry_transmission, |
1362 | ch); | ||
876 | return; | 1363 | return; |
877 | } | 1364 | } |
878 | for (off = ch->head_sent; NULL != off; off = off->next) | 1365 | for (off = ch->head_sent; NULL != off; off = off->next) |
@@ -904,82 +1391,142 @@ data_sent_cb (void *cls) | |||
904 | * buffer space in the tunnel. | 1391 | * buffer space in the tunnel. |
905 | * | 1392 | * |
906 | * @param ch Channel. | 1393 | * @param ch Channel. |
907 | * @param message payload to transmit. | 1394 | * @param sender_ccn ccn of the sender |
1395 | * @param buf payload to transmit. | ||
1396 | * @param buf_len number of bytes in @a buf | ||
908 | * @return #GNUNET_OK if everything goes well, | 1397 | * @return #GNUNET_OK if everything goes well, |
909 | * #GNUNET_SYSERR in case of an error. | 1398 | * #GNUNET_SYSERR in case of an error. |
910 | */ | 1399 | */ |
911 | int | 1400 | int |
912 | GCCH_handle_local_data (struct CadetChannel *ch, | 1401 | GCCH_handle_local_data (struct CadetChannel *ch, |
913 | const struct GNUNET_MessageHeader *message) | 1402 | struct GNUNET_CADET_ClientChannelNumber sender_ccn, |
1403 | const char *buf, | ||
1404 | size_t buf_len) | ||
914 | { | 1405 | { |
915 | uint16_t payload_size = ntohs (message->size); | ||
916 | struct CadetReliableMessage *crm; | 1406 | struct CadetReliableMessage *crm; |
917 | 1407 | ||
918 | if (GNUNET_NO == ch->client_allowed) | 1408 | if (ch->pending_messages > ch->max_pending_messages) |
919 | { | 1409 | { |
920 | GNUNET_break_op (0); | 1410 | GNUNET_break (0); |
921 | return GNUNET_SYSERR; | 1411 | return GNUNET_SYSERR; |
922 | } | 1412 | } |
923 | ch->client_allowed = GNUNET_NO; | ||
924 | ch->pending_messages++; | 1413 | ch->pending_messages++; |
925 | 1414 | ||
1415 | if (GNUNET_YES == ch->is_loopback) | ||
1416 | { | ||
1417 | struct CadetChannelClient *receiver; | ||
1418 | struct GNUNET_MQ_Envelope *env; | ||
1419 | struct GNUNET_CADET_LocalData *ld; | ||
1420 | int to_owner; | ||
1421 | |||
1422 | env = GNUNET_MQ_msg_extra (ld, | ||
1423 | buf_len, | ||
1424 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); | ||
1425 | if (sender_ccn.channel_of_client == | ||
1426 | ch->owner->ccn.channel_of_client) | ||
1427 | { | ||
1428 | receiver = ch->dest; | ||
1429 | to_owner = GNUNET_NO; | ||
1430 | } | ||
1431 | else | ||
1432 | { | ||
1433 | GNUNET_assert (sender_ccn.channel_of_client == | ||
1434 | ch->dest->ccn.channel_of_client); | ||
1435 | receiver = ch->owner; | ||
1436 | to_owner = GNUNET_YES; | ||
1437 | } | ||
1438 | ld->ccn = receiver->ccn; | ||
1439 | GNUNET_memcpy (&ld[1], | ||
1440 | buf, | ||
1441 | buf_len); | ||
1442 | /* FIXME: this does not provide for flow control! */ | ||
1443 | GSC_send_to_client (receiver->c, | ||
1444 | env); | ||
1445 | send_ack_to_client (ch, | ||
1446 | to_owner); | ||
1447 | return GNUNET_OK; | ||
1448 | } | ||
1449 | |||
926 | /* Everything is correct, send the message. */ | 1450 | /* Everything is correct, send the message. */ |
927 | crm = GNUNET_malloc (sizeof (*crm) + payload_size); | 1451 | crm = GNUNET_malloc (sizeof (*crm)); |
928 | crm->ch = ch; | 1452 | crm->ch = ch; |
929 | crm->data_message.header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + payload_size); | 1453 | crm->data_message = GNUNET_malloc (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) |
930 | crm->data_message.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); | 1454 | + buf_len); |
1455 | crm->data_message->header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + buf_len); | ||
1456 | crm->data_message->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); | ||
931 | ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1); | 1457 | ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1); |
932 | crm->data_message.mid = ch->mid_send; | 1458 | crm->data_message->mid = ch->mid_send; |
933 | crm->data_message.gid = ch->gid; | 1459 | crm->data_message->ctn = ch->ctn; |
934 | GNUNET_memcpy (&crm[1], | 1460 | GNUNET_memcpy (&crm->data_message[1], |
935 | message, | 1461 | buf, |
936 | payload_size); | 1462 | buf_len); |
937 | GNUNET_CONTAINER_DLL_insert (ch->head_sent, | 1463 | GNUNET_CONTAINER_DLL_insert (ch->head_sent, |
938 | ch->tail_sent, | 1464 | ch->tail_sent, |
939 | crm); | 1465 | crm); |
940 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1466 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
941 | "Sending %u bytes from local client to channel %s\n", | 1467 | "Sending %u bytes from local client to %s\n", |
942 | payload_size, | 1468 | buf_len, |
943 | GCCH_2s (ch)); | 1469 | GCCH_2s (ch)); |
944 | crm->qe = GCT_send (ch->t, | 1470 | crm->qe = GCT_send (ch->t, |
945 | &crm->data_message.header, | 1471 | &crm->data_message->header, |
946 | &data_sent_cb, | 1472 | &data_sent_cb, |
947 | crm); | 1473 | crm); |
948 | GCCH_check_allow_client (ch); | ||
949 | return GNUNET_OK; | 1474 | return GNUNET_OK; |
950 | } | 1475 | } |
951 | 1476 | ||
952 | 1477 | ||
953 | /** | 1478 | /** |
954 | * Try to deliver messages to the local client, if it is ready for more. | 1479 | * Handle ACK from client on local channel. Means the client is ready |
1480 | * for more data, see if we have any for it. | ||
955 | * | 1481 | * |
956 | * @param ch channel to process | 1482 | * @param ch channel to destroy |
1483 | * @param client_ccn ccn of the client sending the ack | ||
957 | */ | 1484 | */ |
958 | static void | 1485 | void |
959 | send_client_buffered_data (struct CadetChannel *ch) | 1486 | GCCH_handle_local_ack (struct CadetChannel *ch, |
1487 | struct GNUNET_CADET_ClientChannelNumber client_ccn) | ||
960 | { | 1488 | { |
1489 | struct CadetChannelClient *ccc; | ||
961 | struct CadetOutOfOrderMessage *com; | 1490 | struct CadetOutOfOrderMessage *com; |
962 | 1491 | ||
963 | if (GNUNET_NO == ch->client_ready) | 1492 | if ( (NULL != ch->owner) && |
964 | return; /* client not ready */ | 1493 | (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client) ) |
965 | com = ch->head_recv; | 1494 | ccc = ch->owner; |
1495 | else if ( (NULL != ch->dest) && | ||
1496 | (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client) ) | ||
1497 | ccc = ch->dest; | ||
1498 | else | ||
1499 | GNUNET_assert (0); | ||
1500 | ccc->client_ready = GNUNET_YES; | ||
1501 | com = ccc->head_recv; | ||
966 | if (NULL == com) | 1502 | if (NULL == com) |
1503 | { | ||
1504 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1505 | "Got LOCAL_ACK, %s-%X ready to receive more data (but none pending)!\n", | ||
1506 | GSC_2s (ccc->c), | ||
1507 | ntohl (ccc->ccn.channel_of_client)); | ||
967 | return; /* none pending */ | 1508 | return; /* none pending */ |
1509 | } | ||
968 | if ( (com->mid.mid != ch->mid_recv.mid) && | 1510 | if ( (com->mid.mid != ch->mid_recv.mid) && |
969 | (GNUNET_NO == ch->out_of_order) ) | 1511 | (GNUNET_NO == ch->out_of_order) ) |
970 | return; /* missing next one in-order */ | 1512 | return; /* missing next one in-order */ |
971 | 1513 | ||
972 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1514 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
973 | "Passing payload message to client on channel %s\n", | 1515 | "Got LOCAL ACK, passing payload message to %s-%X on %s\n", |
1516 | GSC_2s (ccc->c), | ||
1517 | ntohl (ccc->ccn.channel_of_client), | ||
974 | GCCH_2s (ch)); | 1518 | GCCH_2s (ch)); |
975 | 1519 | ||
976 | /* all good, pass next message to client */ | 1520 | /* all good, pass next message to client */ |
977 | GNUNET_CONTAINER_DLL_remove (ch->head_recv, | 1521 | GNUNET_CONTAINER_DLL_remove (ccc->head_recv, |
978 | ch->tail_recv, | 1522 | ccc->tail_recv, |
979 | com); | 1523 | com); |
1524 | /* FIXME: if unreliable, this is not aggressive | ||
1525 | enough, as it would be OK to have lost some! */ | ||
980 | ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid)); | 1526 | ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid)); |
981 | ch->mid_futures >>= 1; /* equivalent to division by 2 */ | 1527 | ch->mid_futures >>= 1; /* equivalent to division by 2 */ |
982 | GSC_send_to_client (ch->owner ? ch->owner : ch->dest, | 1528 | ccc->client_ready = GNUNET_NO; |
1529 | GSC_send_to_client (ccc->c, | ||
983 | com->env); | 1530 | com->env); |
984 | GNUNET_free (com); | 1531 | GNUNET_free (com); |
985 | if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) && | 1532 | if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) && |
@@ -991,33 +1538,22 @@ send_client_buffered_data (struct CadetChannel *ch) | |||
991 | maximum of 64 bits, and 15 is getting too close for comfort.) | 1538 | maximum of 64 bits, and 15 is getting too close for comfort.) |
992 | So we should send one now. */ | 1539 | So we should send one now. */ |
993 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
994 | "Sender on channel %s likely blocked on flow-control, sending ACK now.\n", | 1541 | "Sender on %s likely blocked on flow-control, sending ACK now.\n", |
995 | GCCH_2s (ch)); | 1542 | GCCH_2s (ch)); |
996 | if (GNUNET_YES == ch->reliable) | 1543 | if (GNUNET_YES == ch->reliable) |
997 | send_channel_ack (ch); | 1544 | send_channel_data_ack (ch); |
998 | } | 1545 | } |
999 | 1546 | ||
1000 | if (NULL != ch->head_recv) | 1547 | if (NULL != ccc->head_recv) |
1001 | return; | 1548 | return; |
1002 | if (GNUNET_NO == ch->destroy) | 1549 | if (GNUNET_NO == ch->destroy) |
1003 | return; | 1550 | return; |
1551 | GCT_send_channel_destroy (ch->t, | ||
1552 | ch->ctn); | ||
1004 | channel_destroy (ch); | 1553 | channel_destroy (ch); |
1005 | } | 1554 | } |
1006 | 1555 | ||
1007 | 1556 | ||
1008 | /** | ||
1009 | * Handle ACK from client on local channel. | ||
1010 | * | ||
1011 | * @param ch channel to destroy | ||
1012 | */ | ||
1013 | void | ||
1014 | GCCH_handle_local_ack (struct CadetChannel *ch) | ||
1015 | { | ||
1016 | ch->client_ready = GNUNET_YES; | ||
1017 | send_client_buffered_data (ch); | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__) | 1557 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__) |
1022 | 1558 | ||
1023 | 1559 | ||
@@ -1045,25 +1581,25 @@ GCCH_debug (struct CadetChannel *ch, | |||
1045 | return; | 1581 | return; |
1046 | } | 1582 | } |
1047 | LOG2 (level, | 1583 | LOG2 (level, |
1048 | "CHN Channel %s:%X (%p)\n", | 1584 | "CHN %s:%X (%p)\n", |
1049 | GCT_2s (ch->t), | 1585 | GCT_2s (ch->t), |
1050 | ch->gid, | 1586 | ch->ctn, |
1051 | ch); | 1587 | ch); |
1052 | if (NULL != ch->owner) | 1588 | if (NULL != ch->owner) |
1053 | { | 1589 | { |
1054 | LOG2 (level, | 1590 | LOG2 (level, |
1055 | "CHN origin %s ready %s local-id: %u\n", | 1591 | "CHN origin %s ready %s local-id: %u\n", |
1056 | GSC_2s (ch->owner), | 1592 | GSC_2s (ch->owner->c), |
1057 | ch->client_ready ? "YES" : "NO", | 1593 | ch->owner->client_ready ? "YES" : "NO", |
1058 | ntohl (ch->lid.channel_of_client)); | 1594 | ntohl (ch->owner->ccn.channel_of_client)); |
1059 | } | 1595 | } |
1060 | if (NULL != ch->dest) | 1596 | if (NULL != ch->dest) |
1061 | { | 1597 | { |
1062 | LOG2 (level, | 1598 | LOG2 (level, |
1063 | "CHN destination %s ready %s local-id: %u\n", | 1599 | "CHN destination %s ready %s local-id: %u\n", |
1064 | GSC_2s (ch->dest), | 1600 | GSC_2s (ch->dest->c), |
1065 | ch->client_ready ? "YES" : "NO", | 1601 | ch->dest->client_ready ? "YES" : "NO", |
1066 | ntohl (ch->lid.channel_of_client)); | 1602 | ntohl (ch->dest->ccn.channel_of_client)); |
1067 | } | 1603 | } |
1068 | LOG2 (level, | 1604 | LOG2 (level, |
1069 | "CHN Message IDs recv: %d (%LLX), send: %d\n", | 1605 | "CHN Message IDs recv: %d (%LLX), send: %d\n", |
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h index 8caa254d1..e572b7633 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.h +++ b/src/cadet/gnunet-service-cadet-new_channel.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "gnunet-service-cadet-new.h" | 31 | #include "gnunet-service-cadet-new.h" |
32 | #include "gnunet-service-cadet-new_peer.h" | 32 | #include "gnunet-service-cadet-new_peer.h" |
33 | #include "cadet_protocol.h" | ||
33 | 34 | ||
34 | 35 | ||
35 | /** | 36 | /** |
@@ -107,22 +108,39 @@ GCCH_bind (struct CadetChannel *ch, | |||
107 | struct CadetClient *c); | 108 | struct CadetClient *c); |
108 | 109 | ||
109 | 110 | ||
110 | |||
111 | /** | 111 | /** |
112 | * Destroy locally created channel. Called by the | 112 | * Destroy locally created channel. Called by the |
113 | * local client, so no need to tell the client. | 113 | * local client, so no need to tell the client. |
114 | * | 114 | * |
115 | * @param ch channel to destroy | 115 | * @param ch channel to destroy |
116 | * @param c client that caused the destruction | ||
117 | * @param ccn client number of the client @a c | ||
116 | */ | 118 | */ |
117 | void | 119 | void |
118 | GCCH_channel_local_destroy (struct CadetChannel *ch); | 120 | GCCH_channel_local_destroy (struct CadetChannel *ch, |
121 | struct CadetClient *c, | ||
122 | struct GNUNET_CADET_ClientChannelNumber ccn); | ||
119 | 123 | ||
120 | 124 | ||
121 | /** | 125 | /** |
122 | * Create a new channel. | 126 | * Function called once and only once after a channel was bound |
127 | * to its tunnel via #GCT_add_channel() is ready for transmission. | ||
128 | * Note that this is only the case for channels that this peer | ||
129 | * initiates, as for incoming channels we assume that they are | ||
130 | * ready for transmission immediately upon receiving the open | ||
131 | * message. Used to bootstrap the #GCT_send() process. | ||
132 | * | ||
133 | * @param ch the channel for which the tunnel is now ready | ||
134 | */ | ||
135 | void | ||
136 | GCCH_tunnel_up (struct CadetChannel *ch); | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Create a new channel based on a request coming in over the network. | ||
123 | * | 141 | * |
124 | * @param t tunnel to the remote peer | 142 | * @param t tunnel to the remote peer |
125 | * @param gid identifier of this channel in the tunnel | 143 | * @param chid identifier of this channel in the tunnel |
126 | * @param origin peer to who initiated the channel | 144 | * @param origin peer to who initiated the channel |
127 | * @param port desired local port | 145 | * @param port desired local port |
128 | * @param options options for the channel | 146 | * @param options options for the channel |
@@ -130,19 +148,53 @@ GCCH_channel_local_destroy (struct CadetChannel *ch); | |||
130 | */ | 148 | */ |
131 | struct CadetChannel * | 149 | struct CadetChannel * |
132 | GCCH_channel_incoming_new (struct CadetTunnel *t, | 150 | GCCH_channel_incoming_new (struct CadetTunnel *t, |
133 | struct GNUNET_CADET_ChannelTunnelNumber gid, | 151 | struct GNUNET_CADET_ChannelTunnelNumber chid, |
134 | const struct GNUNET_HashCode *port, | 152 | const struct GNUNET_HashCode *port, |
135 | uint32_t options); | 153 | uint32_t options); |
136 | 154 | ||
137 | 155 | ||
138 | /** | 156 | /** |
139 | * Destroy channel that was incoming. Called by the | 157 | * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for |
140 | * local client, so no need to tell the client. | 158 | * this channel. If the binding was successful, (re)transmit the |
159 | * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK. | ||
160 | * | ||
161 | * @param ch channel that got the duplicate open | ||
162 | */ | ||
163 | void | ||
164 | GCCH_handle_duplicate_open (struct CadetChannel *ch); | ||
165 | |||
166 | |||
167 | /** | ||
168 | * We got payload data for a channel. Pass it on to the client. | ||
169 | * | ||
170 | * @param ch channel that got data | ||
171 | * @param msg message that was received | ||
172 | */ | ||
173 | void | ||
174 | GCCH_handle_channel_plaintext_data (struct CadetChannel *ch, | ||
175 | const struct GNUNET_CADET_ChannelAppDataMessage *msg); | ||
176 | |||
177 | |||
178 | /** | ||
179 | * We got an acknowledgement for payload data for a channel. | ||
180 | * Possibly resume transmissions. | ||
181 | * | ||
182 | * @param ch channel that got the ack | ||
183 | * @param ack details about what was received | ||
184 | */ | ||
185 | void | ||
186 | GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch, | ||
187 | const struct GNUNET_CADET_ChannelDataAckMessage *ack); | ||
188 | |||
189 | |||
190 | /** | ||
191 | * We got an acknowledgement for the creation of the channel | ||
192 | * (the port is open on the other side). Begin transmissions. | ||
141 | * | 193 | * |
142 | * @param ch channel to destroy | 194 | * @param ch channel to destroy |
143 | */ | 195 | */ |
144 | void | 196 | void |
145 | GCCH_channel_incoming_destroy (struct CadetChannel *ch); | 197 | GCCH_handle_channel_open_ack (struct CadetChannel *ch); |
146 | 198 | ||
147 | 199 | ||
148 | /** | 200 | /** |
@@ -160,7 +212,7 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch); | |||
160 | * @param ch channel to destroy | 212 | * @param ch channel to destroy |
161 | */ | 213 | */ |
162 | void | 214 | void |
163 | GCCH_channel_remote_destroy (struct CadetChannel *ch); | 215 | GCCH_handle_remote_destroy (struct CadetChannel *ch); |
164 | 216 | ||
165 | 217 | ||
166 | /** | 218 | /** |
@@ -171,21 +223,27 @@ GCCH_channel_remote_destroy (struct CadetChannel *ch); | |||
171 | * buffer space in the tunnel. | 223 | * buffer space in the tunnel. |
172 | * | 224 | * |
173 | * @param ch Channel. | 225 | * @param ch Channel. |
174 | * @param message payload to transmit. | 226 | * @param sender_ccn ccn of the sender |
227 | * @param buf payload to transmit. | ||
228 | * @param buf_len number of bytes in @a buf | ||
175 | * @return #GNUNET_OK if everything goes well, | 229 | * @return #GNUNET_OK if everything goes well, |
176 | * #GNUNET_SYSERR in case of an error. | 230 | * #GNUNET_SYSERR in case of an error. |
177 | */ | 231 | */ |
178 | int | 232 | int |
179 | GCCH_handle_local_data (struct CadetChannel *ch, | 233 | GCCH_handle_local_data (struct CadetChannel *ch, |
180 | const struct GNUNET_MessageHeader *message); | 234 | struct GNUNET_CADET_ClientChannelNumber sender_ccn, |
235 | const char *buf, | ||
236 | size_t buf_len); | ||
181 | 237 | ||
182 | 238 | ||
183 | /** | 239 | /** |
184 | * Handle ACK from client on local channel. | 240 | * Handle ACK from client on local channel. |
185 | * | 241 | * |
186 | * @param ch channel to destroy | 242 | * @param ch channel to destroy |
243 | * @param client_ccn ccn of the client sending the ack | ||
187 | */ | 244 | */ |
188 | void | 245 | void |
189 | GCCH_handle_local_ack (struct CadetChannel *ch); | 246 | GCCH_handle_local_ack (struct CadetChannel *ch, |
247 | struct GNUNET_CADET_ClientChannelNumber client_ccn); | ||
190 | 248 | ||
191 | #endif | 249 | #endif |
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c index bf88d78e1..60389008c 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c | |||
@@ -27,8 +27,8 @@ | |||
27 | * @author Christian Grothoff | 27 | * @author Christian Grothoff |
28 | * | 28 | * |
29 | * TODO: | 29 | * TODO: |
30 | * - keepalive messages | 30 | * - Optimization: keepalive messages / timeout (timeout to be done @ peer level!) |
31 | * - keep performance metrics (?) | 31 | * - Optimization: keep performance metrics (?) |
32 | */ | 32 | */ |
33 | #include "platform.h" | 33 | #include "platform.h" |
34 | #include "gnunet-service-cadet-new_channel.h" | 34 | #include "gnunet-service-cadet-new_channel.h" |
@@ -40,6 +40,9 @@ | |||
40 | #include "cadet_protocol.h" | 40 | #include "cadet_protocol.h" |
41 | 41 | ||
42 | 42 | ||
43 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__) | ||
44 | |||
45 | |||
43 | /** | 46 | /** |
44 | * All the states a connection can be in. | 47 | * All the states a connection can be in. |
45 | */ | 48 | */ |
@@ -158,6 +161,9 @@ GCC_destroy (struct CadetConnection *cc) | |||
158 | { | 161 | { |
159 | struct GNUNET_MQ_Envelope *env = NULL; | 162 | struct GNUNET_MQ_Envelope *env = NULL; |
160 | 163 | ||
164 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
165 | "Destroying %s\n", | ||
166 | GCC_2s (cc)); | ||
161 | if (CADET_CONNECTION_SENDING_CREATE != cc->state) | 167 | if (CADET_CONNECTION_SENDING_CREATE != cc->state) |
162 | { | 168 | { |
163 | struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg; | 169 | struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg; |
@@ -167,9 +173,17 @@ GCC_destroy (struct CadetConnection *cc) | |||
167 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY); | 173 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY); |
168 | destroy_msg->cid = cc->cid; | 174 | destroy_msg->cid = cc->cid; |
169 | } | 175 | } |
170 | GCP_request_mq_cancel (cc->mq_man, | 176 | if (NULL != cc->mq_man) |
171 | env); | 177 | { |
172 | cc->mq_man = NULL; | 178 | GCP_request_mq_cancel (cc->mq_man, |
179 | env); | ||
180 | cc->mq_man = NULL; | ||
181 | } | ||
182 | if (NULL != cc->task) | ||
183 | { | ||
184 | GNUNET_SCHEDULER_cancel (cc->task); | ||
185 | cc->task = NULL; | ||
186 | } | ||
173 | GCPP_del_connection (cc->path, | 187 | GCPP_del_connection (cc->path, |
174 | cc->off, | 188 | cc->off, |
175 | cc); | 189 | cc); |
@@ -195,14 +209,19 @@ GCC_get_ct (struct CadetConnection *cc) | |||
195 | 209 | ||
196 | 210 | ||
197 | /** | 211 | /** |
198 | * A connection ACK was received for this connection, implying | 212 | * A CADET_CONNECTION_ACK was received for this connection, implying |
199 | * that the end-to-end connection is up. Process it. | 213 | * that the end-to-end connection is up. Process it. |
200 | * | 214 | * |
201 | * @param cc the connection that got the ACK. | 215 | * @param cc the connection that got the ACK. |
202 | */ | 216 | */ |
203 | void | 217 | void |
204 | GCC_handle_connection_ack (struct CadetConnection *cc) | 218 | GCC_handle_connection_create_ack (struct CadetConnection *cc) |
205 | { | 219 | { |
220 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
221 | "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n", | ||
222 | GCC_2s (cc), | ||
223 | cc->state, | ||
224 | (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy"); | ||
206 | if (NULL != cc->task) | 225 | if (NULL != cc->task) |
207 | { | 226 | { |
208 | GNUNET_SCHEDULER_cancel (cc->task); | 227 | GNUNET_SCHEDULER_cancel (cc->task); |
@@ -232,9 +251,12 @@ GCC_handle_kx (struct CadetConnection *cc, | |||
232 | { | 251 | { |
233 | if (CADET_CONNECTION_SENT == cc->state) | 252 | if (CADET_CONNECTION_SENT == cc->state) |
234 | { | 253 | { |
235 | /* We didn't get the CREATE_ACK, but instead got payload. That's fine, | 254 | /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine, |
236 | clearly something is working, so pretend we got an ACK. */ | 255 | clearly something is working, so pretend we got an ACK. */ |
237 | GCC_handle_connection_ack (cc); | 256 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
257 | "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n", | ||
258 | GCC_2s (cc)); | ||
259 | GCC_handle_connection_create_ack (cc); | ||
238 | } | 260 | } |
239 | GCT_handle_kx (cc->ct, | 261 | GCT_handle_kx (cc->ct, |
240 | msg); | 262 | msg); |
@@ -255,7 +277,10 @@ GCC_handle_encrypted (struct CadetConnection *cc, | |||
255 | { | 277 | { |
256 | /* We didn't get the CREATE_ACK, but instead got payload. That's fine, | 278 | /* We didn't get the CREATE_ACK, but instead got payload. That's fine, |
257 | clearly something is working, so pretend we got an ACK. */ | 279 | clearly something is working, so pretend we got an ACK. */ |
258 | GCC_handle_connection_ack (cc); | 280 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
281 | "Faking connection ACK for %s due to ENCRYPTED payload\n", | ||
282 | GCC_2s (cc)); | ||
283 | GCC_handle_connection_create_ack (cc); | ||
259 | } | 284 | } |
260 | GCT_handle_encrypted (cc->ct, | 285 | GCT_handle_encrypted (cc->ct, |
261 | msg); | 286 | msg); |
@@ -280,13 +305,17 @@ send_create (void *cls) | |||
280 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); | 305 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); |
281 | path_length = GCPP_get_length (cc->path); | 306 | path_length = GCPP_get_length (cc->path); |
282 | env = GNUNET_MQ_msg_extra (create_msg, | 307 | env = GNUNET_MQ_msg_extra (create_msg, |
283 | path_length * sizeof (struct GNUNET_PeerIdentity), | 308 | (1 + path_length) * sizeof (struct GNUNET_PeerIdentity), |
284 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE); | 309 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE); |
285 | create_msg->cid = cc->cid; | 310 | create_msg->cid = cc->cid; |
286 | pids = (struct GNUNET_PeerIdentity *) &create_msg[1]; | 311 | pids = (struct GNUNET_PeerIdentity *) &create_msg[1]; |
312 | pids[0] = my_full_id; | ||
287 | for (unsigned int i=0;i<path_length;i++) | 313 | for (unsigned int i=0;i<path_length;i++) |
288 | pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, | 314 | pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, |
289 | i)); | 315 | i)); |
316 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
317 | "Sending CADET_CONNECTION_CREATE message for %s\n", | ||
318 | GCC_2s (cc)); | ||
290 | cc->env = env; | 319 | cc->env = env; |
291 | cc->mqm_ready = GNUNET_NO; | 320 | cc->mqm_ready = GNUNET_NO; |
292 | cc->state = CADET_CONNECTION_SENT; | 321 | cc->state = CADET_CONNECTION_SENT; |
@@ -304,22 +333,18 @@ static void | |||
304 | send_create_ack (void *cls) | 333 | send_create_ack (void *cls) |
305 | { | 334 | { |
306 | struct CadetConnection *cc = cls; | 335 | struct CadetConnection *cc = cls; |
307 | struct GNUNET_CADET_ConnectionCreateMessage *create_msg; | 336 | struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg; |
308 | struct GNUNET_PeerIdentity *pids; | ||
309 | struct GNUNET_MQ_Envelope *env; | 337 | struct GNUNET_MQ_Envelope *env; |
310 | unsigned int path_length; | ||
311 | 338 | ||
312 | cc->task = NULL; | 339 | cc->task = NULL; |
340 | GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state); | ||
341 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
342 | "Sending CONNECTION_CREATE_ACK message for %s\n", | ||
343 | GCC_2s (cc)); | ||
313 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); | 344 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); |
314 | path_length = GCPP_get_length (cc->path); | 345 | env = GNUNET_MQ_msg (ack_msg, |
315 | env = GNUNET_MQ_msg_extra (create_msg, | 346 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK); |
316 | path_length * sizeof (struct GNUNET_PeerIdentity), | 347 | ack_msg->cid = cc->cid; |
317 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE); | ||
318 | create_msg->cid = cc->cid; | ||
319 | pids = (struct GNUNET_PeerIdentity *) &create_msg[1]; | ||
320 | for (unsigned int i=0;i<path_length;i++) | ||
321 | pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, | ||
322 | i)); | ||
323 | cc->env = env; | 348 | cc->env = env; |
324 | cc->mqm_ready = GNUNET_NO; | 349 | cc->mqm_ready = GNUNET_NO; |
325 | cc->state = CADET_CONNECTION_READY; | 350 | cc->state = CADET_CONNECTION_READY; |
@@ -340,14 +365,19 @@ GCC_handle_duplicate_create (struct CadetConnection *cc) | |||
340 | { | 365 | { |
341 | if (GNUNET_YES == cc->mqm_ready) | 366 | if (GNUNET_YES == cc->mqm_ready) |
342 | { | 367 | { |
368 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
369 | "Got duplicate CREATE for %s, scheduling another ACK (%s)\n", | ||
370 | GCC_2s (cc), | ||
371 | (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy"); | ||
343 | /* Tell tunnel that we are not ready for transmission anymore | 372 | /* Tell tunnel that we are not ready for transmission anymore |
344 | (until CREATE_ACK is done) */ | 373 | (until CREATE_ACK is done) */ |
345 | cc->ready_cb (cc->ready_cb_cls, | 374 | cc->ready_cb (cc->ready_cb_cls, |
346 | GNUNET_NO); | 375 | GNUNET_NO); |
347 | |||
348 | /* Revert back to the state of having only received the 'CREATE', | 376 | /* Revert back to the state of having only received the 'CREATE', |
349 | and immediately proceed to send the CREATE_ACK. */ | 377 | and immediately proceed to send the CREATE_ACK. */ |
350 | cc->state = CADET_CONNECTION_CREATE_RECEIVED; | 378 | cc->state = CADET_CONNECTION_CREATE_RECEIVED; |
379 | if (NULL != cc->task) | ||
380 | GNUNET_SCHEDULER_cancel (cc->task); | ||
351 | cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, | 381 | cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, |
352 | cc); | 382 | cc); |
353 | } | 383 | } |
@@ -356,6 +386,9 @@ GCC_handle_duplicate_create (struct CadetConnection *cc) | |||
356 | /* We are currently sending something else back, which | 386 | /* We are currently sending something else back, which |
357 | can only be an ACK or payload, either of which would | 387 | can only be an ACK or payload, either of which would |
358 | do. So actually no need to do anything. */ | 388 | do. So actually no need to do anything. */ |
389 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
390 | "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n", | ||
391 | GCC_2s (cc)); | ||
359 | } | 392 | } |
360 | } | 393 | } |
361 | 394 | ||
@@ -379,6 +412,9 @@ manage_first_hop_mq (void *cls, | |||
379 | if (GNUNET_YES != available) | 412 | if (GNUNET_YES != available) |
380 | { | 413 | { |
381 | /* Connection is down, for now... */ | 414 | /* Connection is down, for now... */ |
415 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
416 | "Core MQ for %s went down\n", | ||
417 | GCC_2s (cc)); | ||
382 | cc->mqm_ready = GNUNET_NO; | 418 | cc->mqm_ready = GNUNET_NO; |
383 | cc->state = CADET_CONNECTION_NEW; | 419 | cc->state = CADET_CONNECTION_NEW; |
384 | cc->retry_delay = GNUNET_TIME_UNIT_ZERO; | 420 | cc->retry_delay = GNUNET_TIME_UNIT_ZERO; |
@@ -393,6 +429,10 @@ manage_first_hop_mq (void *cls, | |||
393 | } | 429 | } |
394 | 430 | ||
395 | cc->mqm_ready = GNUNET_YES; | 431 | cc->mqm_ready = GNUNET_YES; |
432 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
433 | "Core MQ for %s became available in state %d\n", | ||
434 | GCC_2s (cc), | ||
435 | cc->state); | ||
396 | switch (cc->state) | 436 | switch (cc->state) |
397 | { | 437 | { |
398 | case CADET_CONNECTION_NEW: | 438 | case CADET_CONNECTION_NEW: |
@@ -466,6 +506,10 @@ connection_create (struct CadetPeer *destination, | |||
466 | cc->ready_cb_cls = ready_cb_cls; | 506 | cc->ready_cb_cls = ready_cb_cls; |
467 | cc->path = path; | 507 | cc->path = path; |
468 | cc->off = off; | 508 | cc->off = off; |
509 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
510 | "Creating %s using path %s\n", | ||
511 | GCC_2s (cc), | ||
512 | GCPP_2s (path)); | ||
469 | GCPP_add_connection (path, | 513 | GCPP_add_connection (path, |
470 | off, | 514 | off, |
471 | cc); | 515 | cc); |
@@ -560,6 +604,9 @@ void | |||
560 | GCC_transmit (struct CadetConnection *cc, | 604 | GCC_transmit (struct CadetConnection *cc, |
561 | struct GNUNET_MQ_Envelope *env) | 605 | struct GNUNET_MQ_Envelope *env) |
562 | { | 606 | { |
607 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
608 | "Scheduling message for transmission on %s\n", | ||
609 | GCC_2s (cc)); | ||
563 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); | 610 | GNUNET_assert (GNUNET_YES == cc->mqm_ready); |
564 | GNUNET_assert (CADET_CONNECTION_READY == cc->state); | 611 | GNUNET_assert (CADET_CONNECTION_READY == cc->state); |
565 | cc->mqm_ready = GNUNET_NO; | 612 | cc->mqm_ready = GNUNET_NO; |
@@ -611,14 +658,14 @@ GCC_2s (const struct CadetConnection *cc) | |||
611 | { | 658 | { |
612 | GNUNET_snprintf (buf, | 659 | GNUNET_snprintf (buf, |
613 | sizeof (buf), | 660 | sizeof (buf), |
614 | "Connection(%s(Tunnel(%s)))", | 661 | "Connection %s (%s)", |
615 | GNUNET_sh2s (&cc->cid.connection_of_tunnel), | 662 | GNUNET_sh2s (&cc->cid.connection_of_tunnel), |
616 | GCT_2s (cc->ct->t)); | 663 | GCT_2s (cc->ct->t)); |
617 | return buf; | 664 | return buf; |
618 | } | 665 | } |
619 | GNUNET_snprintf (buf, | 666 | GNUNET_snprintf (buf, |
620 | sizeof (buf), | 667 | sizeof (buf), |
621 | "Connection(%s(Tunnel(NULL)))", | 668 | "Connection %s", |
622 | GNUNET_sh2s (&cc->cid.connection_of_tunnel)); | 669 | GNUNET_sh2s (&cc->cid.connection_of_tunnel)); |
623 | return buf; | 670 | return buf; |
624 | } | 671 | } |
@@ -638,7 +685,6 @@ GCC_debug (struct CadetConnection *cc, | |||
638 | enum GNUNET_ErrorType level) | 685 | enum GNUNET_ErrorType level) |
639 | { | 686 | { |
640 | int do_log; | 687 | int do_log; |
641 | char *s; | ||
642 | 688 | ||
643 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | 689 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), |
644 | "cadet-con", | 690 | "cadet-con", |
@@ -651,15 +697,13 @@ GCC_debug (struct CadetConnection *cc, | |||
651 | "Connection (NULL)\n"); | 697 | "Connection (NULL)\n"); |
652 | return; | 698 | return; |
653 | } | 699 | } |
654 | s = GCPP_2s (cc->path); | ||
655 | LOG2 (level, | 700 | LOG2 (level, |
656 | "Connection %s to %s via path %s in state %d is %s\n", | 701 | "%s to %s via path %s in state %d is %s\n", |
657 | GCC_2s (cc), | 702 | GCC_2s (cc), |
658 | GCP_2s (cc->destination), | 703 | GCP_2s (cc->destination), |
659 | s, | 704 | GCPP_2s (cc->path), |
660 | cc->state, | 705 | cc->state, |
661 | (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy"); | 706 | (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy"); |
662 | GNUNET_free (s); | ||
663 | } | 707 | } |
664 | 708 | ||
665 | /* end of gnunet-service-cadet-new_connection.c */ | 709 | /* end of gnunet-service-cadet-new_connection.c */ |
diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h index 99426776d..efdf9929a 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.h +++ b/src/cadet/gnunet-service-cadet-new_connection.h | |||
@@ -113,12 +113,23 @@ GCC_transmit (struct CadetConnection *cc, | |||
113 | 113 | ||
114 | 114 | ||
115 | /** | 115 | /** |
116 | * An ACK was received for this connection, process it. | 116 | * A CREATE_ACK was received for this connection, process it. |
117 | * | 117 | * |
118 | * @param cc the connection that got the ACK. | 118 | * @param cc the connection that got the ACK. |
119 | */ | 119 | */ |
120 | void | 120 | void |
121 | GCC_handle_connection_ack (struct CadetConnection *cc); | 121 | GCC_handle_connection_create_ack (struct CadetConnection *cc); |
122 | |||
123 | |||
124 | /** | ||
125 | * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a | ||
126 | * connection that we already have. Either our ACK got lost | ||
127 | * or something is fishy. Consider retransmitting the ACK. | ||
128 | * | ||
129 | * @param cc connection that got the duplicate CREATE | ||
130 | */ | ||
131 | void | ||
132 | GCC_handle_duplicate_create (struct CadetConnection *cc); | ||
122 | 133 | ||
123 | 134 | ||
124 | /** | 135 | /** |
diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c index 9ce4418de..4a4ead05b 100644 --- a/src/cadet/gnunet-service-cadet-new_core.c +++ b/src/cadet/gnunet-service-cadet-new_core.c | |||
@@ -27,10 +27,7 @@ | |||
27 | * All functions in this file should use the prefix GCO (Gnunet Cadet cOre (bottom)) | 27 | * All functions in this file should use the prefix GCO (Gnunet Cadet cOre (bottom)) |
28 | * | 28 | * |
29 | * TODO: | 29 | * TODO: |
30 | * - pass encrypted ACK to connection (!) | 30 | * - Optimization: given BROKEN messages, destroy paths (?) |
31 | * - given BROKEN messages, destroy paths (?) | ||
32 | * - | ||
33 | * - handle POLL (if needed) | ||
34 | */ | 31 | */ |
35 | #include "platform.h" | 32 | #include "platform.h" |
36 | #include "gnunet-service-cadet-new_core.h" | 33 | #include "gnunet-service-cadet-new_core.h" |
@@ -41,6 +38,10 @@ | |||
41 | #include "gnunet_core_service.h" | 38 | #include "gnunet_core_service.h" |
42 | #include "cadet_protocol.h" | 39 | #include "cadet_protocol.h" |
43 | 40 | ||
41 | |||
42 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-cor",__VA_ARGS__) | ||
43 | |||
44 | |||
44 | /** | 45 | /** |
45 | * Number of messages we are willing to buffer per route. | 46 | * Number of messages we are willing to buffer per route. |
46 | */ | 47 | */ |
@@ -172,6 +173,11 @@ route_message (struct CadetPeer *prev, | |||
172 | struct GNUNET_MQ_Envelope *env; | 173 | struct GNUNET_MQ_Envelope *env; |
173 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; | 174 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; |
174 | 175 | ||
176 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
177 | "Failed to route message of type %u from %s on connection %s: no route\n", | ||
178 | ntohs (msg->type), | ||
179 | GCP_2s (prev), | ||
180 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
175 | env = GNUNET_MQ_msg (bm, | 181 | env = GNUNET_MQ_msg (bm, |
176 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); | 182 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); |
177 | bm->cid = *cid; | 183 | bm->cid = *cid; |
@@ -183,6 +189,12 @@ route_message (struct CadetPeer *prev, | |||
183 | dir = (prev == route->prev.hop) ? &route->next : &route->prev; | 189 | dir = (prev == route->prev.hop) ? &route->next : &route->prev; |
184 | if (GNUNET_YES == dir->is_ready) | 190 | if (GNUNET_YES == dir->is_ready) |
185 | { | 191 | { |
192 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
193 | "Routing message of type %u from %s to %s on connection %s\n", | ||
194 | ntohs (msg->type), | ||
195 | GCP_2s (prev), | ||
196 | GNUNET_i2s (GCP_get_id (dir->hop)), | ||
197 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
186 | dir->is_ready = GNUNET_NO; | 198 | dir->is_ready = GNUNET_NO; |
187 | GCP_send (dir->mqm, | 199 | GCP_send (dir->mqm, |
188 | GNUNET_MQ_msg_copy (msg)); | 200 | GNUNET_MQ_msg_copy (msg)); |
@@ -192,12 +204,24 @@ route_message (struct CadetPeer *prev, | |||
192 | if (NULL != env) | 204 | if (NULL != env) |
193 | { | 205 | { |
194 | /* Queue full, drop earliest message in queue */ | 206 | /* Queue full, drop earliest message in queue */ |
207 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
208 | "Queue full due to new message of type %u from %s to %s on connection %s, dropping old message\n", | ||
209 | ntohs (msg->type), | ||
210 | GCP_2s (prev), | ||
211 | GNUNET_i2s (GCP_get_id (dir->hop)), | ||
212 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
195 | GNUNET_assert (dir->out_rpos == dir->out_wpos); | 213 | GNUNET_assert (dir->out_rpos == dir->out_wpos); |
196 | GNUNET_MQ_discard (env); | 214 | GNUNET_MQ_discard (env); |
197 | dir->out_rpos++; | 215 | dir->out_rpos++; |
198 | if (ROUTE_BUFFER_SIZE == dir->out_rpos) | 216 | if (ROUTE_BUFFER_SIZE == dir->out_rpos) |
199 | dir->out_rpos = 0; | 217 | dir->out_rpos = 0; |
200 | } | 218 | } |
219 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
220 | "Queueing new message of type %u from %s to %s on connection %s\n", | ||
221 | ntohs (msg->type), | ||
222 | GCP_2s (prev), | ||
223 | GNUNET_i2s (GCP_get_id (dir->hop)), | ||
224 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
201 | env = GNUNET_MQ_msg_copy (msg); | 225 | env = GNUNET_MQ_msg_copy (msg); |
202 | dir->out_buffer[dir->out_wpos] = env; | 226 | dir->out_buffer[dir->out_wpos] = env; |
203 | dir->out_wpos++; | 227 | dir->out_wpos++; |
@@ -260,6 +284,11 @@ destroy_direction (struct RouteDirection *dir) | |||
260 | static void | 284 | static void |
261 | destroy_route (struct CadetRoute *route) | 285 | destroy_route (struct CadetRoute *route) |
262 | { | 286 | { |
287 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
288 | "Destroying route from %s to %s of connection %s\n", | ||
289 | GNUNET_i2s (GCP_get_id (route->prev.hop)), | ||
290 | GNUNET_i2s2 (GCP_get_id (route->next.hop)), | ||
291 | GNUNET_sh2s (&route->cid.connection_of_tunnel)); | ||
263 | destroy_direction (&route->prev); | 292 | destroy_direction (&route->prev); |
264 | destroy_direction (&route->next); | 293 | destroy_direction (&route->next); |
265 | GNUNET_free (route); | 294 | GNUNET_free (route); |
@@ -283,6 +312,15 @@ send_broken (struct RouteDirection *target, | |||
283 | struct GNUNET_MQ_Envelope *env; | 312 | struct GNUNET_MQ_Envelope *env; |
284 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; | 313 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; |
285 | 314 | ||
315 | if (NULL == target->mqm) | ||
316 | return; /* Can't send notification, connection is down! */ | ||
317 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
318 | "Notifying %s about BROKEN route at %s-%s of connection %s\n", | ||
319 | GCP_2s (target->hop), | ||
320 | GNUNET_i2s (peer1), | ||
321 | GNUNET_i2s2 (peer2), | ||
322 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
323 | |||
286 | env = GNUNET_MQ_msg (bm, | 324 | env = GNUNET_MQ_msg (bm, |
287 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); | 325 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); |
288 | bm->cid = *cid; | 326 | bm->cid = *cid; |
@@ -290,6 +328,7 @@ send_broken (struct RouteDirection *target, | |||
290 | bm->peer1 = *peer1; | 328 | bm->peer1 = *peer1; |
291 | if (NULL != peer2) | 329 | if (NULL != peer2) |
292 | bm->peer2 = *peer2; | 330 | bm->peer2 = *peer2; |
331 | |||
293 | GCP_request_mq_cancel (target->mqm, | 332 | GCP_request_mq_cancel (target->mqm, |
294 | env); | 333 | env); |
295 | target->mqm = NULL; | 334 | target->mqm = NULL; |
@@ -406,6 +445,9 @@ handle_connection_create (void *cls, | |||
406 | get_route (&msg->cid)) | 445 | get_route (&msg->cid)) |
407 | { | 446 | { |
408 | /* Duplicate CREATE, pass it on, previous one might have been lost! */ | 447 | /* Duplicate CREATE, pass it on, previous one might have been lost! */ |
448 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
449 | "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n", | ||
450 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
409 | route_message (sender, | 451 | route_message (sender, |
410 | &msg->cid, | 452 | &msg->cid, |
411 | &msg->header); | 453 | &msg->header); |
@@ -422,16 +464,23 @@ handle_connection_create (void *cls, | |||
422 | &msg->cid.connection_of_tunnel); | 464 | &msg->cid.connection_of_tunnel); |
423 | if (NULL != cc) | 465 | if (NULL != cc) |
424 | { | 466 | { |
425 | /* Duplicate CREATE, likely our ACK got lost, retransmit the ACK! */ | 467 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
426 | GNUNET_break (0); // FIXME: not implemented! | 468 | "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n", |
469 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
470 | GCC_handle_duplicate_create (cc); | ||
427 | return; | 471 | return; |
428 | } | 472 | } |
429 | 473 | ||
430 | path = GCPP_get_path_from_route (path_length, | ||
431 | pids); | ||
432 | origin = GCP_get (&pids[0], | 474 | origin = GCP_get (&pids[0], |
433 | GNUNET_YES); | 475 | GNUNET_YES); |
434 | GCT_add_inbound_connection (GCT_create_tunnel (origin), | 476 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
477 | "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n", | ||
478 | GCP_2s (origin), | ||
479 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
480 | path = GCPP_get_path_from_route (path_length - 1, | ||
481 | pids); | ||
482 | GCT_add_inbound_connection (GCP_get_tunnel (origin, | ||
483 | GNUNET_YES), | ||
435 | &msg->cid, | 484 | &msg->cid, |
436 | path); | 485 | path); |
437 | return; | 486 | return; |
@@ -446,6 +495,12 @@ handle_connection_create (void *cls, | |||
446 | struct GNUNET_MQ_Envelope *env; | 495 | struct GNUNET_MQ_Envelope *env; |
447 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; | 496 | struct GNUNET_CADET_ConnectionBrokenMessage *bm; |
448 | 497 | ||
498 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
499 | "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n", | ||
500 | GCP_2s (sender), | ||
501 | GNUNET_sh2s (&msg->cid.connection_of_tunnel), | ||
502 | GNUNET_i2s (&pids[off + 1]), | ||
503 | off + 1); | ||
449 | env = GNUNET_MQ_msg (bm, | 504 | env = GNUNET_MQ_msg (bm, |
450 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); | 505 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); |
451 | bm->cid = msg->cid; | 506 | bm->cid = msg->cid; |
@@ -457,6 +512,12 @@ handle_connection_create (void *cls, | |||
457 | } | 512 | } |
458 | 513 | ||
459 | /* Workable route, create routing entry */ | 514 | /* Workable route, create routing entry */ |
515 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
516 | "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n", | ||
517 | GCP_2s (sender), | ||
518 | GNUNET_sh2s (&msg->cid.connection_of_tunnel), | ||
519 | GNUNET_i2s (&pids[off + 1]), | ||
520 | off + 1); | ||
460 | route = GNUNET_new (struct CadetRoute); | 521 | route = GNUNET_new (struct CadetRoute); |
461 | route->cid = msg->cid; | 522 | route->cid = msg->cid; |
462 | dir_init (&route->prev, | 523 | dir_init (&route->prev, |
@@ -481,7 +542,7 @@ handle_connection_create (void *cls, | |||
481 | */ | 542 | */ |
482 | static void | 543 | static void |
483 | handle_connection_create_ack (void *cls, | 544 | handle_connection_create_ack (void *cls, |
484 | const struct GNUNET_CADET_ConnectionCreateMessageAckMessage *msg) | 545 | const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) |
485 | { | 546 | { |
486 | struct CadetPeer *peer = cls; | 547 | struct CadetPeer *peer = cls; |
487 | struct CadetConnection *cc; | 548 | struct CadetConnection *cc; |
@@ -502,7 +563,10 @@ handle_connection_create_ack (void *cls, | |||
502 | GNUNET_break_op (0); | 563 | GNUNET_break_op (0); |
503 | return; | 564 | return; |
504 | } | 565 | } |
505 | GCC_handle_connection_ack (cc); | 566 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
567 | "Received CONNECTION_CREATE_ACK for connection %s.\n", | ||
568 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
569 | GCC_handle_connection_create_ack (cc); | ||
506 | return; | 570 | return; |
507 | } | 571 | } |
508 | 572 | ||
@@ -544,6 +608,9 @@ handle_connection_broken (void *cls, | |||
544 | GNUNET_break_op (0); | 608 | GNUNET_break_op (0); |
545 | return; | 609 | return; |
546 | } | 610 | } |
611 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
612 | "Received CONNECTION_BROKEN for connection %s. Destroying it.\n", | ||
613 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
547 | GCC_destroy (cc); | 614 | GCC_destroy (cc); |
548 | 615 | ||
549 | /* FIXME: also destroy the path up to the specified link! */ | 616 | /* FIXME: also destroy the path up to the specified link! */ |
@@ -590,11 +657,18 @@ handle_connection_destroy (void *cls, | |||
590 | GNUNET_break_op (0); | 657 | GNUNET_break_op (0); |
591 | return; | 658 | return; |
592 | } | 659 | } |
660 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
661 | "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n", | ||
662 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
663 | |||
593 | GCC_destroy (cc); | 664 | GCC_destroy (cc); |
594 | return; | 665 | return; |
595 | } | 666 | } |
596 | 667 | ||
597 | /* We're just an intermediary peer, route the message along its path */ | 668 | /* We're just an intermediary peer, route the message along its path */ |
669 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
670 | "Received CONNECTION_DESTROY for connection %s. Destroying route.\n", | ||
671 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
598 | route = get_route (&msg->cid); | 672 | route = get_route (&msg->cid); |
599 | route_message (peer, | 673 | route_message (peer, |
600 | &msg->cid, | 674 | &msg->cid, |
@@ -604,68 +678,6 @@ handle_connection_destroy (void *cls, | |||
604 | 678 | ||
605 | 679 | ||
606 | /** | 680 | /** |
607 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_HOP_BY_HOP_ENCRYPTED_ACK. | ||
608 | * | ||
609 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
610 | * @param msg Message itself. | ||
611 | */ | ||
612 | static void | ||
613 | handle_hop_by_hop_encrypted_ack (void *cls, | ||
614 | const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) | ||
615 | { | ||
616 | struct CadetPeer *peer = cls; | ||
617 | struct CadetConnection *cc; | ||
618 | |||
619 | /* First, check if message belongs to a connection that ends here. */ | ||
620 | cc = GNUNET_CONTAINER_multishortmap_get (connections, | ||
621 | &msg->cid.connection_of_tunnel); | ||
622 | if (NULL != cc) | ||
623 | { | ||
624 | /* verify message came from the right direction */ | ||
625 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
626 | |||
627 | if (peer != | ||
628 | GCPP_get_peer_at_offset (path, | ||
629 | 0)) | ||
630 | { | ||
631 | /* received message from unexpected direction, ignore! */ | ||
632 | GNUNET_break_op (0); | ||
633 | return; | ||
634 | } | ||
635 | #if FIXME | ||
636 | GCC_handle_ack (peer, | ||
637 | msg); | ||
638 | #endif | ||
639 | return; | ||
640 | } | ||
641 | |||
642 | /* We're just an intermediary peer, route the message along its path */ | ||
643 | route_message (peer, | ||
644 | &msg->cid, | ||
645 | &msg->header); | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL | ||
651 | * | ||
652 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
653 | * @param msg Message itself. | ||
654 | */ | ||
655 | static void | ||
656 | handle_poll (void *cls, | ||
657 | const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg) | ||
658 | { | ||
659 | struct CadetPeer *peer = cls; | ||
660 | |||
661 | #if FIXME | ||
662 | GCC_handle_poll (peer, | ||
663 | msg); | ||
664 | #endif | ||
665 | } | ||
666 | |||
667 | |||
668 | /** | ||
669 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX | 681 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX |
670 | * | 682 | * |
671 | * @param cls Closure (CadetPeer for neighbor that sent the message). | 683 | * @param cls Closure (CadetPeer for neighbor that sent the message). |
@@ -755,7 +767,6 @@ handle_tunnel_encrypted (void *cls, | |||
755 | msg); | 767 | msg); |
756 | return; | 768 | return; |
757 | } | 769 | } |
758 | |||
759 | /* We're just an intermediary peer, route the message along its path */ | 770 | /* We're just an intermediary peer, route the message along its path */ |
760 | route_message (peer, | 771 | route_message (peer, |
761 | &msg->cid, | 772 | &msg->cid, |
@@ -804,6 +815,9 @@ core_connect_cb (void *cls, | |||
804 | { | 815 | { |
805 | struct CadetPeer *cp; | 816 | struct CadetPeer *cp; |
806 | 817 | ||
818 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
819 | "CORE connection to peer %s was established.\n", | ||
820 | GNUNET_i2s (peer)); | ||
807 | cp = GCP_get (peer, | 821 | cp = GCP_get (peer, |
808 | GNUNET_YES); | 822 | GNUNET_YES); |
809 | GCP_set_mq (cp, | 823 | GCP_set_mq (cp, |
@@ -825,6 +839,9 @@ core_disconnect_cb (void *cls, | |||
825 | { | 839 | { |
826 | struct CadetPeer *cp = peer_cls; | 840 | struct CadetPeer *cp = peer_cls; |
827 | 841 | ||
842 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
843 | "CORE connection to peer %s went down.\n", | ||
844 | GNUNET_i2s (peer)); | ||
828 | GCP_set_mq (cp, | 845 | GCP_set_mq (cp, |
829 | NULL); | 846 | NULL); |
830 | } | 847 | } |
@@ -845,7 +862,7 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) | |||
845 | NULL), | 862 | NULL), |
846 | GNUNET_MQ_hd_fixed_size (connection_create_ack, | 863 | GNUNET_MQ_hd_fixed_size (connection_create_ack, |
847 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK, | 864 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK, |
848 | struct GNUNET_CADET_ConnectionCreateMessageAckMessage, | 865 | struct GNUNET_CADET_ConnectionCreateAckMessage, |
849 | NULL), | 866 | NULL), |
850 | GNUNET_MQ_hd_fixed_size (connection_broken, | 867 | GNUNET_MQ_hd_fixed_size (connection_broken, |
851 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, | 868 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, |
@@ -855,14 +872,6 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) | |||
855 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, | 872 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, |
856 | struct GNUNET_CADET_ConnectionDestroyMessage, | 873 | struct GNUNET_CADET_ConnectionDestroyMessage, |
857 | NULL), | 874 | NULL), |
858 | GNUNET_MQ_hd_fixed_size (hop_by_hop_encrypted_ack, | ||
859 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK, | ||
860 | struct GNUNET_CADET_ConnectionEncryptedAckMessage, | ||
861 | NULL), | ||
862 | GNUNET_MQ_hd_fixed_size (poll, | ||
863 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL, | ||
864 | struct GNUNET_CADET_ConnectionHopByHopPollMessage, | ||
865 | NULL), | ||
866 | GNUNET_MQ_hd_fixed_size (tunnel_kx, | 875 | GNUNET_MQ_hd_fixed_size (tunnel_kx, |
867 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, | 876 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, |
868 | struct GNUNET_CADET_TunnelKeyExchangeMessage, | 877 | struct GNUNET_CADET_TunnelKeyExchangeMessage, |
diff --git a/src/cadet/gnunet-service-cadet-new_dht.c b/src/cadet/gnunet-service-cadet-new_dht.c index 3cf3f0301..849562f23 100644 --- a/src/cadet/gnunet-service-cadet-new_dht.c +++ b/src/cadet/gnunet-service-cadet-new_dht.c | |||
@@ -34,6 +34,22 @@ | |||
34 | #include "gnunet-service-cadet-new_peer.h" | 34 | #include "gnunet-service-cadet-new_peer.h" |
35 | #include "gnunet-service-cadet-new_paths.h" | 35 | #include "gnunet-service-cadet-new_paths.h" |
36 | 36 | ||
37 | /** | ||
38 | * How long do we wait before first announcing our presence to the DHT. | ||
39 | * Used to wait for our HELLO to be available. Note that we also get | ||
40 | * notifications when our HELLO is ready, so this is just the maximum | ||
41 | * we wait for the first notification. | ||
42 | */ | ||
43 | #define STARTUP_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500) | ||
44 | |||
45 | /** | ||
46 | * How long do we wait after we get an updated HELLO before publishing? | ||
47 | * Allows for the HELLO to be updated again quickly, for example in | ||
48 | * case multiple addresses changed and we got a partial update. | ||
49 | */ | ||
50 | #define CHANGE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) | ||
51 | |||
52 | |||
37 | #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) | 53 | #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) |
38 | 54 | ||
39 | 55 | ||
@@ -195,6 +211,23 @@ announce_id (void *cls) | |||
195 | 211 | ||
196 | 212 | ||
197 | /** | 213 | /** |
214 | * Function called by the HELLO subsystem whenever OUR hello | ||
215 | * changes. Re-triggers the DHT PUT immediately. | ||
216 | */ | ||
217 | void | ||
218 | GCD_hello_update () | ||
219 | { | ||
220 | if (NULL == announce_id_task) | ||
221 | return; /* too early */ | ||
222 | GNUNET_SCHEDULER_cancel (announce_id_task); | ||
223 | announce_id_task | ||
224 | = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY, | ||
225 | &announce_id, | ||
226 | NULL); | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
198 | * Initialize the DHT subsystem. | 231 | * Initialize the DHT subsystem. |
199 | * | 232 | * |
200 | * @param c Configuration. | 233 | * @param c Configuration. |
@@ -202,8 +235,6 @@ announce_id (void *cls) | |||
202 | void | 235 | void |
203 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) | 236 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) |
204 | { | 237 | { |
205 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
206 | "init\n"); | ||
207 | if (GNUNET_OK != | 238 | if (GNUNET_OK != |
208 | GNUNET_CONFIGURATION_get_value_number (c, | 239 | GNUNET_CONFIGURATION_get_value_number (c, |
209 | "CADET", | 240 | "CADET", |
@@ -235,8 +266,9 @@ GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) | |||
235 | 64); | 266 | 64); |
236 | GNUNET_break (NULL != dht_handle); | 267 | GNUNET_break (NULL != dht_handle); |
237 | announce_delay = GNUNET_TIME_UNIT_SECONDS; | 268 | announce_delay = GNUNET_TIME_UNIT_SECONDS; |
238 | announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, | 269 | announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY, |
239 | NULL); | 270 | &announce_id, |
271 | NULL); | ||
240 | } | 272 | } |
241 | 273 | ||
242 | 274 | ||
@@ -271,9 +303,6 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id) | |||
271 | struct GNUNET_HashCode phash; | 303 | struct GNUNET_HashCode phash; |
272 | struct GCD_search_handle *h; | 304 | struct GCD_search_handle *h; |
273 | 305 | ||
274 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
275 | "Starting DHT GET for peer %s\n", | ||
276 | GNUNET_i2s (peer_id)); | ||
277 | GNUNET_STATISTICS_update (stats, | 306 | GNUNET_STATISTICS_update (stats, |
278 | "# DHT search", | 307 | "# DHT search", |
279 | 1, | 308 | 1, |
@@ -296,6 +325,10 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id) | |||
296 | 0, /* xquery bits */ | 325 | 0, /* xquery bits */ |
297 | &dht_get_id_handler, | 326 | &dht_get_id_handler, |
298 | h); | 327 | h); |
328 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
329 | "Starting DHT GET for peer %s (%p)\n", | ||
330 | GNUNET_i2s (peer_id), | ||
331 | h); | ||
299 | return h; | 332 | return h; |
300 | } | 333 | } |
301 | 334 | ||
@@ -308,6 +341,9 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id) | |||
308 | void | 341 | void |
309 | GCD_search_stop (struct GCD_search_handle *h) | 342 | GCD_search_stop (struct GCD_search_handle *h) |
310 | { | 343 | { |
344 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
345 | "Stopping DHT GET %p\n", | ||
346 | h); | ||
311 | GNUNET_DHT_get_stop (h->dhtget); | 347 | GNUNET_DHT_get_stop (h->dhtget); |
312 | GNUNET_free (h); | 348 | GNUNET_free (h); |
313 | } | 349 | } |
diff --git a/src/cadet/gnunet-service-cadet-new_dht.h b/src/cadet/gnunet-service-cadet-new_dht.h index 81f16ae99..5d7ab29a0 100644 --- a/src/cadet/gnunet-service-cadet-new_dht.h +++ b/src/cadet/gnunet-service-cadet-new_dht.h | |||
@@ -63,6 +63,13 @@ GCD_shutdown (void); | |||
63 | 63 | ||
64 | 64 | ||
65 | /** | 65 | /** |
66 | * Function called by the HELLO subsystem whenever OUR hello | ||
67 | * changes. Re-triggers the DHT PUT immediately. | ||
68 | */ | ||
69 | void | ||
70 | GCD_hello_update (void); | ||
71 | |||
72 | /** | ||
66 | * Search DHT for paths to @a peeR_id | 73 | * Search DHT for paths to @a peeR_id |
67 | * | 74 | * |
68 | * @param peer_id peer to search for | 75 | * @param peer_id peer to search for |
diff --git a/src/cadet/gnunet-service-cadet-new_hello.c b/src/cadet/gnunet-service-cadet-new_hello.c index 9d4635021..a24325ada 100644 --- a/src/cadet/gnunet-service-cadet-new_hello.c +++ b/src/cadet/gnunet-service-cadet-new_hello.c | |||
@@ -17,7 +17,16 @@ | |||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | 20 | /** | |
21 | * @file cadet/gnunet-service-cadet-new_hello.c | ||
22 | * @brief spread knowledge about how to contact other peers from PEERINFO | ||
23 | * @author Bartlomiej Polot | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * TODO: | ||
27 | * - is most of this necessary/helpful? | ||
28 | * - should we not simply restrict this to OUR hello? | ||
29 | */ | ||
21 | #include "platform.h" | 30 | #include "platform.h" |
22 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
23 | 32 | ||
@@ -25,6 +34,7 @@ | |||
25 | #include "gnunet_peerinfo_service.h" | 34 | #include "gnunet_peerinfo_service.h" |
26 | #include "cadet_protocol.h" | 35 | #include "cadet_protocol.h" |
27 | #include "gnunet-service-cadet-new.h" | 36 | #include "gnunet-service-cadet-new.h" |
37 | #include "gnunet-service-cadet-new_dht.h" | ||
28 | #include "gnunet-service-cadet-new_hello.h" | 38 | #include "gnunet-service-cadet-new_hello.h" |
29 | #include "gnunet-service-cadet-new_peer.h" | 39 | #include "gnunet-service-cadet-new_peer.h" |
30 | 40 | ||
@@ -43,7 +53,7 @@ static struct GNUNET_PEERINFO_Handle *peerinfo; | |||
43 | /** | 53 | /** |
44 | * Iterator context. | 54 | * Iterator context. |
45 | */ | 55 | */ |
46 | static struct GNUNET_PEERINFO_NotifyContext* nc; | 56 | static struct GNUNET_PEERINFO_NotifyContext *nc; |
47 | 57 | ||
48 | 58 | ||
49 | /** | 59 | /** |
@@ -71,6 +81,7 @@ got_hello (void *cls, | |||
71 | { | 81 | { |
72 | GNUNET_free_non_null (mine); | 82 | GNUNET_free_non_null (mine); |
73 | mine = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (&hello->header); | 83 | mine = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (&hello->header); |
84 | GCD_hello_update (); | ||
74 | return; | 85 | return; |
75 | } | 86 | } |
76 | 87 | ||
@@ -83,7 +94,6 @@ got_hello (void *cls, | |||
83 | GNUNET_YES); | 94 | GNUNET_YES); |
84 | GCP_set_hello (peer, | 95 | GCP_set_hello (peer, |
85 | hello); | 96 | hello); |
86 | |||
87 | } | 97 | } |
88 | 98 | ||
89 | 99 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c b/src/cadet/gnunet-service-cadet-new_paths.c index 3cfce337c..685656ec3 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.c +++ b/src/cadet/gnunet-service-cadet-new_paths.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
4 | Copyright (C) 2001-2017 GNUnet e.V. | 3 | Copyright (C) 2001-2017 GNUnet e.V. |
@@ -18,7 +17,6 @@ | |||
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
20 | */ | 19 | */ |
21 | |||
22 | /** | 20 | /** |
23 | * @file cadet/gnunet-service-cadet-new_paths.c | 21 | * @file cadet/gnunet-service-cadet-new_paths.c |
24 | * @brief Information we track per path. | 22 | * @brief Information we track per path. |
@@ -27,13 +25,16 @@ | |||
27 | * | 25 | * |
28 | * TODO: | 26 | * TODO: |
29 | * - path desirability score calculations are not done | 27 | * - path desirability score calculations are not done |
30 | * (and will be tricky to have during path changes) | ||
31 | */ | 28 | */ |
32 | #include "platform.h" | 29 | #include "platform.h" |
30 | #include "gnunet-service-cadet-new_connection.h" | ||
33 | #include "gnunet-service-cadet-new_peer.h" | 31 | #include "gnunet-service-cadet-new_peer.h" |
34 | #include "gnunet-service-cadet-new_paths.h" | 32 | #include "gnunet-service-cadet-new_paths.h" |
35 | 33 | ||
36 | 34 | ||
35 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-pat",__VA_ARGS__) | ||
36 | |||
37 | |||
37 | /** | 38 | /** |
38 | * Information regarding a possible path to reach a peer. | 39 | * Information regarding a possible path to reach a peer. |
39 | */ | 40 | */ |
@@ -44,7 +45,7 @@ struct CadetPeerPath | |||
44 | * Array of all the peers on the path. If @e hn is non-NULL, the | 45 | * Array of all the peers on the path. If @e hn is non-NULL, the |
45 | * last one is our owner. | 46 | * last one is our owner. |
46 | */ | 47 | */ |
47 | struct CadetPeerPathEntry *entries; | 48 | struct CadetPeerPathEntry **entries; |
48 | 49 | ||
49 | /** | 50 | /** |
50 | * Node of this path in the owner's heap. Used to update our position | 51 | * Node of this path in the owner's heap. Used to update our position |
@@ -53,13 +54,6 @@ struct CadetPeerPath | |||
53 | struct GNUNET_CONTAINER_HeapNode *hn; | 54 | struct GNUNET_CONTAINER_HeapNode *hn; |
54 | 55 | ||
55 | /** | 56 | /** |
56 | * Connections using this path, by destination peer | ||
57 | * (each hop of the path could correspond to an | ||
58 | * active connection). | ||
59 | */ | ||
60 | struct GNUNET_CONTAINER_MultiPeerMap *connections; | ||
61 | |||
62 | /** | ||
63 | * Desirability of the path. How unique is it for the various peers | 57 | * Desirability of the path. How unique is it for the various peers |
64 | * on it? | 58 | * on it? |
65 | */ | 59 | */ |
@@ -74,6 +68,19 @@ struct CadetPeerPath | |||
74 | 68 | ||
75 | 69 | ||
76 | /** | 70 | /** |
71 | * Calculate the path's desirability score. | ||
72 | * | ||
73 | * @param path path to calculate the score for | ||
74 | */ | ||
75 | static void | ||
76 | recalculate_path_desirability (struct CadetPeerPath *path) | ||
77 | { | ||
78 | /* FIXME: update path desirability! */ | ||
79 | GNUNET_break (0); // not implemented | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
77 | * Return how much we like keeping the path. This is an aggregate | 84 | * Return how much we like keeping the path. This is an aggregate |
78 | * score based on various factors, including the age of the path | 85 | * score based on various factors, including the age of the path |
79 | * (older == better), and the value of this path to all of its ajacent | 86 | * (older == better), and the value of this path to all of its ajacent |
@@ -111,7 +118,7 @@ GCPP_get_connection (struct CadetPeerPath *path, | |||
111 | struct CadetPeerPathEntry *entry; | 118 | struct CadetPeerPathEntry *entry; |
112 | 119 | ||
113 | GNUNET_assert (off < path->entries_length); | 120 | GNUNET_assert (off < path->entries_length); |
114 | entry = &path->entries[off]; | 121 | entry = path->entries[off]; |
115 | GNUNET_assert (entry->peer == destination); | 122 | GNUNET_assert (entry->peer == destination); |
116 | return entry->cc; | 123 | return entry->cc; |
117 | } | 124 | } |
@@ -132,8 +139,13 @@ GCPP_add_connection (struct CadetPeerPath *path, | |||
132 | { | 139 | { |
133 | struct CadetPeerPathEntry *entry; | 140 | struct CadetPeerPathEntry *entry; |
134 | 141 | ||
142 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
143 | "Adding connection %s to path %s at offset %u\n", | ||
144 | GCC_2s (cc), | ||
145 | GCPP_2s (path), | ||
146 | off); | ||
135 | GNUNET_assert (off < path->entries_length); | 147 | GNUNET_assert (off < path->entries_length); |
136 | entry = &path->entries[off]; | 148 | entry = path->entries[off]; |
137 | GNUNET_assert (NULL == entry->cc); | 149 | GNUNET_assert (NULL == entry->cc); |
138 | entry->cc = cc; | 150 | entry->cc = cc; |
139 | } | 151 | } |
@@ -155,8 +167,13 @@ GCPP_del_connection (struct CadetPeerPath *path, | |||
155 | { | 167 | { |
156 | struct CadetPeerPathEntry *entry; | 168 | struct CadetPeerPathEntry *entry; |
157 | 169 | ||
170 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
171 | "Removing connection %s to path %s at offset %u\n", | ||
172 | GCC_2s (cc), | ||
173 | GCPP_2s (path), | ||
174 | off); | ||
158 | GNUNET_assert (off < path->entries_length); | 175 | GNUNET_assert (off < path->entries_length); |
159 | entry = &path->entries[off]; | 176 | entry = path->entries[off]; |
160 | GNUNET_assert (cc == entry->cc); | 177 | GNUNET_assert (cc == entry->cc); |
161 | entry->cc = NULL; | 178 | entry->cc = NULL; |
162 | } | 179 | } |
@@ -170,9 +187,11 @@ GCPP_del_connection (struct CadetPeerPath *path, | |||
170 | static void | 187 | static void |
171 | path_destroy (struct CadetPeerPath *path) | 188 | path_destroy (struct CadetPeerPath *path) |
172 | { | 189 | { |
173 | GNUNET_assert (0 == | 190 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
174 | GNUNET_CONTAINER_multipeermap_size (path->connections)); | 191 | "Destroying path %s\n", |
175 | GNUNET_CONTAINER_multipeermap_destroy (path->connections); | 192 | GCPP_2s (path)); |
193 | for (unsigned int i=0;i<path->entries_length;i++) | ||
194 | GNUNET_free (path->entries[i]); | ||
176 | GNUNET_free (path->entries); | 195 | GNUNET_free (path->entries); |
177 | GNUNET_free (path); | 196 | GNUNET_free (path); |
178 | } | 197 | } |
@@ -190,27 +209,29 @@ GCPP_release (struct CadetPeerPath *path) | |||
190 | { | 209 | { |
191 | struct CadetPeerPathEntry *entry; | 210 | struct CadetPeerPathEntry *entry; |
192 | 211 | ||
212 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
213 | "Owner releases path %s\n", | ||
214 | GCPP_2s (path)); | ||
193 | path->hn = NULL; | 215 | path->hn = NULL; |
194 | entry = &path->entries[path->entries_length - 1]; | 216 | entry = path->entries[path->entries_length - 1]; |
195 | while (1) | 217 | while (1) |
196 | { | 218 | { |
197 | /* cut 'off' end of path, verifying it is not in use */ | 219 | /* cut 'off' end of path */ |
198 | GNUNET_assert (NULL == | ||
199 | GNUNET_CONTAINER_multipeermap_get (path->connections, | ||
200 | GCP_get_id (entry->peer))); | ||
201 | GCP_path_entry_remove (entry->peer, | 220 | GCP_path_entry_remove (entry->peer, |
202 | entry, | 221 | entry, |
203 | path->entries_length - 1); | 222 | path->entries_length - 1); |
204 | path->entries_length--; /* We don't bother shrinking the 'entries' array, | 223 | path->entries_length--; /* We don't bother shrinking the 'entries' array, |
205 | as it's probably not worth it. */ | 224 | as it's probably not worth it. */ |
225 | GNUNET_free (entry); | ||
206 | if (0 == path->entries_length) | 226 | if (0 == path->entries_length) |
207 | break; /* the end */ | 227 | break; /* the end */ |
208 | 228 | ||
209 | /* see if new peer at the end likes this path any better */ | 229 | /* see if new peer at the end likes this path any better */ |
210 | entry = &path->entries[path->entries_length - 1]; | 230 | entry = path->entries[path->entries_length - 1]; |
211 | path->hn = GCP_attach_path (entry->peer, | 231 | path->hn = GCP_attach_path (entry->peer, |
212 | path, | 232 | path, |
213 | path->entries_length); | 233 | path->entries_length - 1, |
234 | GNUNET_NO); | ||
214 | if (NULL != path->hn) | 235 | if (NULL != path->hn) |
215 | return; /* yep, got attached, we are done. */ | 236 | return; /* yep, got attached, we are done. */ |
216 | } | 237 | } |
@@ -236,7 +257,7 @@ GCPP_update_score (struct CadetPeerPath *path, | |||
236 | struct CadetPeerPathEntry *entry; | 257 | struct CadetPeerPathEntry *entry; |
237 | 258 | ||
238 | GNUNET_assert (off < path->entries_length); | 259 | GNUNET_assert (off < path->entries_length); |
239 | entry = &path->entries[off]; | 260 | entry = path->entries[off]; |
240 | 261 | ||
241 | /* Add delta, with checks for overflows */ | 262 | /* Add delta, with checks for overflows */ |
242 | if (delta >= 0) | 263 | if (delta >= 0) |
@@ -253,8 +274,7 @@ GCPP_update_score (struct CadetPeerPath *path, | |||
253 | else | 274 | else |
254 | entry->score += delta; | 275 | entry->score += delta; |
255 | } | 276 | } |
256 | 277 | recalculate_path_desirability (path); | |
257 | /* FIXME: update path desirability! */ | ||
258 | } | 278 | } |
259 | 279 | ||
260 | 280 | ||
@@ -274,6 +294,11 @@ struct CheckMatchContext | |||
274 | */ | 294 | */ |
275 | struct CadetPeer **cpath; | 295 | struct CadetPeer **cpath; |
276 | 296 | ||
297 | /** | ||
298 | * How long is the @e cpath array? | ||
299 | */ | ||
300 | unsigned int cpath_length; | ||
301 | |||
277 | }; | 302 | }; |
278 | 303 | ||
279 | 304 | ||
@@ -294,13 +319,32 @@ check_match (void *cls, | |||
294 | { | 319 | { |
295 | struct CheckMatchContext *cm_ctx = cls; | 320 | struct CheckMatchContext *cm_ctx = cls; |
296 | 321 | ||
297 | if (path->entries_length > off) | 322 | GNUNET_assert (path->entries_length > off); |
298 | return GNUNET_YES; /* too long, cannot be useful */ | 323 | if ( (path->entries_length != off + 1) && |
324 | (off + 1 != cm_ctx->cpath_length) ) | ||
325 | { | ||
326 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
327 | "check_match missmatch because path %s is too long (%u vs. %u vs. %u)\n", | ||
328 | GCPP_2s (path), | ||
329 | path->entries_length, | ||
330 | off + 1, | ||
331 | cm_ctx->cpath_length); | ||
332 | return GNUNET_YES; /* too long, goes somewhere else already, thus cannot be useful */ | ||
333 | } | ||
299 | for (unsigned int i=0;i<off;i++) | 334 | for (unsigned int i=0;i<off;i++) |
300 | if (cm_ctx->cpath[i] != | 335 | if (cm_ctx->cpath[i] != |
301 | GCPP_get_peer_at_offset (path, | 336 | GCPP_get_peer_at_offset (path, |
302 | i)) | 337 | i)) |
338 | { | ||
339 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
340 | "check_match path %s missmatches at offset %u\n", | ||
341 | GCPP_2s (path), | ||
342 | i); | ||
303 | return GNUNET_YES; /* missmatch, ignore */ | 343 | return GNUNET_YES; /* missmatch, ignore */ |
344 | } | ||
345 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
346 | "check_match found match with path %s\n", | ||
347 | GCPP_2s (path)); | ||
304 | cm_ctx->match = path; | 348 | cm_ctx->match = path; |
305 | return GNUNET_NO; /* match, we are done! */ | 349 | return GNUNET_NO; /* match, we are done! */ |
306 | } | 350 | } |
@@ -313,47 +357,77 @@ check_match (void *cls, | |||
313 | * @param path path to extend | 357 | * @param path path to extend |
314 | * @param peers list of peers beyond the end of @a path | 358 | * @param peers list of peers beyond the end of @a path |
315 | * @param num_peers length of the @a peers array | 359 | * @param num_peers length of the @a peers array |
360 | * @param force force attachment, even if we have other | ||
361 | * paths already | ||
316 | */ | 362 | */ |
317 | static void | 363 | static void |
318 | extend_path (struct CadetPeerPath *path, | 364 | extend_path (struct CadetPeerPath *path, |
319 | struct CadetPeer **peers, | 365 | struct CadetPeer **peers, |
320 | unsigned int num_peers) | 366 | unsigned int num_peers, |
367 | int force) | ||
321 | { | 368 | { |
322 | unsigned int old_len = path->entries_length; | 369 | unsigned int old_len = path->entries_length; |
323 | struct GNUNET_CONTAINER_HeapNode *hn; | 370 | struct GNUNET_CONTAINER_HeapNode *hn; |
324 | int i; | 371 | int i; |
325 | 372 | ||
373 | /* Expand path */ | ||
374 | GNUNET_array_grow (path->entries, | ||
375 | path->entries_length, | ||
376 | old_len + num_peers); | ||
377 | for (i=num_peers-1;i >= 0;i--) | ||
378 | { | ||
379 | struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry); | ||
380 | |||
381 | path->entries[old_len + i] = entry; | ||
382 | entry->peer = peers[i]; | ||
383 | entry->path = path; | ||
384 | } | ||
385 | for (i=num_peers-1;i >= 0;i--) | ||
386 | { | ||
387 | struct CadetPeerPathEntry *entry = path->entries[old_len + i]; | ||
388 | |||
389 | GCP_path_entry_add (entry->peer, | ||
390 | entry, | ||
391 | old_len + i); | ||
392 | } | ||
393 | |||
326 | /* If we extend an existing path, detach it from the | 394 | /* If we extend an existing path, detach it from the |
327 | old owner and re-attach to the new one */ | 395 | old owner and re-attach to the new one */ |
328 | hn = NULL; | 396 | hn = NULL; |
329 | for (i=num_peers-1;i>=0;i--) | 397 | for (i=num_peers-1;i>=0;i--) |
330 | { | 398 | { |
331 | /* FIXME: note that path->desirability is used, but not yet updated here! */ | 399 | struct CadetPeerPathEntry *entry = path->entries[old_len + i]; |
400 | |||
401 | path->entries_length = old_len + i + 1; | ||
402 | recalculate_path_desirability (path); | ||
332 | hn = GCP_attach_path (peers[i], | 403 | hn = GCP_attach_path (peers[i], |
333 | path, | 404 | path, |
334 | old_len + (unsigned int) i); | 405 | old_len + (unsigned int) i, |
406 | GNUNET_YES); | ||
335 | if (NULL != hn) | 407 | if (NULL != hn) |
336 | break; | 408 | break; |
409 | GCP_path_entry_remove (entry->peer, | ||
410 | entry, | ||
411 | old_len + i); | ||
412 | GNUNET_free (entry); | ||
413 | path->entries[old_len + i] = NULL; | ||
337 | } | 414 | } |
338 | if (NULL == hn) | 415 | if (NULL == hn) |
339 | return; /* none of the peers is interested in this path */ | 416 | { |
340 | GCP_detach_path (path->entries[old_len-1].peer, | 417 | /* none of the peers is interested in this path; |
418 | shrink path back */ | ||
419 | GNUNET_array_grow (path->entries, | ||
420 | path->entries_length, | ||
421 | old_len); | ||
422 | return; | ||
423 | } | ||
424 | GCP_detach_path (path->entries[old_len-1]->peer, | ||
341 | path, | 425 | path, |
342 | path->hn); | 426 | path->hn); |
343 | path->hn = hn; | 427 | path->hn = hn; |
344 | GNUNET_array_grow (path->entries, | 428 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
345 | path->entries_length, | 429 | "Extended path %s\n", |
346 | old_len + i); | 430 | GCPP_2s (path)); |
347 | for (;i >= 0;i--) | ||
348 | { | ||
349 | struct CadetPeerPathEntry *entry = &path->entries[old_len + i]; | ||
350 | |||
351 | entry->peer = peers[i]; | ||
352 | entry->path = path; | ||
353 | GCP_path_entry_add (entry->peer, | ||
354 | entry, | ||
355 | old_len + i); | ||
356 | } | ||
357 | } | 431 | } |
358 | 432 | ||
359 | 433 | ||
@@ -375,8 +449,8 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
375 | const struct GNUNET_PeerIdentity *put_path, | 449 | const struct GNUNET_PeerIdentity *put_path, |
376 | unsigned int put_path_length) | 450 | unsigned int put_path_length) |
377 | { | 451 | { |
378 | struct CheckMatchContext cm_ctx; | ||
379 | struct CadetPeer *cpath[get_path_length + put_path_length]; | 452 | struct CadetPeer *cpath[get_path_length + put_path_length]; |
453 | struct CheckMatchContext cm_ctx; | ||
380 | struct CadetPeerPath *path; | 454 | struct CadetPeerPath *path; |
381 | struct GNUNET_CONTAINER_HeapNode *hn; | 455 | struct GNUNET_CONTAINER_HeapNode *hn; |
382 | int i; | 456 | int i; |
@@ -395,6 +469,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
395 | 469 | ||
396 | /* First figure out if this path is a subset of an existing path, an | 470 | /* First figure out if this path is a subset of an existing path, an |
397 | extension of an existing path, or a new path. */ | 471 | extension of an existing path, or a new path. */ |
472 | cm_ctx.cpath_length = get_path_length + put_path_length; | ||
398 | cm_ctx.cpath = cpath; | 473 | cm_ctx.cpath = cpath; |
399 | cm_ctx.match = NULL; | 474 | cm_ctx.match = NULL; |
400 | for (i=get_path_length + put_path_length-1;i>=0;i--) | 475 | for (i=get_path_length + put_path_length-1;i>=0;i--) |
@@ -408,14 +483,20 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
408 | if (i == get_path_length + put_path_length - 1) | 483 | if (i == get_path_length + put_path_length - 1) |
409 | { | 484 | { |
410 | /* Existing path includes this one, nothing to do! */ | 485 | /* Existing path includes this one, nothing to do! */ |
486 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
487 | "Path discovered from DHT is already known\n"); | ||
411 | return; | 488 | return; |
412 | } | 489 | } |
413 | if (cm_ctx.match->entries_length == i + 1) | 490 | if (cm_ctx.match->entries_length == i + 1) |
414 | { | 491 | { |
415 | /* Existing path ends in the middle of new path, extend it! */ | 492 | /* Existing path ends in the middle of new path, extend it! */ |
493 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
494 | "Trying to extend existing path %s by additional links discovered from DHT\n", | ||
495 | GCPP_2s (cm_ctx.match)); | ||
416 | extend_path (cm_ctx.match, | 496 | extend_path (cm_ctx.match, |
417 | &cpath[i], | 497 | &cpath[i], |
418 | get_path_length + put_path_length - i); | 498 | get_path_length + put_path_length - i, |
499 | GNUNET_NO); | ||
419 | return; | 500 | return; |
420 | } | 501 | } |
421 | } | 502 | } |
@@ -423,39 +504,63 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
423 | 504 | ||
424 | /* No match at all, create completely new path */ | 505 | /* No match at all, create completely new path */ |
425 | path = GNUNET_new (struct CadetPeerPath); | 506 | path = GNUNET_new (struct CadetPeerPath); |
507 | path->entries_length = get_path_length + put_path_length; | ||
508 | path->entries = GNUNET_new_array (path->entries_length, | ||
509 | struct CadetPeerPathEntry *); | ||
510 | for (i=path->entries_length-1;i>=0;i--) | ||
511 | { | ||
512 | struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry); | ||
426 | 513 | ||
427 | /* First, try to attach it */ | 514 | path->entries[i] = entry; |
515 | entry->peer = cpath[i]; | ||
516 | entry->path = path; | ||
517 | } | ||
518 | for (i=path->entries_length-1;i>=0;i--) | ||
519 | { | ||
520 | struct CadetPeerPathEntry *entry = path->entries[i]; | ||
521 | |||
522 | GCP_path_entry_add (entry->peer, | ||
523 | entry, | ||
524 | i); | ||
525 | } | ||
526 | |||
527 | /* Finally, try to attach it */ | ||
428 | hn = NULL; | 528 | hn = NULL; |
429 | for (i=get_path_length + put_path_length-1;i>=0;i--) | 529 | for (i=get_path_length + put_path_length-1;i>=0;i--) |
430 | { | 530 | { |
431 | path->entries_length = i; | 531 | struct CadetPeerPathEntry *entry = path->entries[i]; |
432 | /* FIXME: note that path->desirability is used, but not yet initialized here! */ | 532 | |
533 | path->entries_length = i + 1; | ||
534 | recalculate_path_desirability (path); | ||
433 | hn = GCP_attach_path (cpath[i], | 535 | hn = GCP_attach_path (cpath[i], |
434 | path, | 536 | path, |
435 | (unsigned int) i); | 537 | (unsigned int) i, |
538 | GNUNET_NO); | ||
436 | if (NULL != hn) | 539 | if (NULL != hn) |
437 | break; | 540 | break; |
541 | GCP_path_entry_remove (entry->peer, | ||
542 | entry, | ||
543 | i); | ||
544 | GNUNET_free (entry); | ||
545 | path->entries[i] = NULL; | ||
438 | } | 546 | } |
439 | if (NULL == hn) | 547 | if (NULL == hn) |
440 | { | 548 | { |
441 | /* None of the peers on the path care about it. */ | 549 | /* None of the peers on the path care about it. */ |
550 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
551 | "Path discovered from DHT is not interesting to us\n"); | ||
552 | GNUNET_free (path->entries); | ||
442 | GNUNET_free (path); | 553 | GNUNET_free (path); |
443 | return; | 554 | return; |
444 | } | 555 | } |
445 | path->hn = hn; | 556 | path->hn = hn; |
446 | path->entries_length = i; | 557 | /* Shrink path to actual useful length */ |
447 | path->entries = GNUNET_new_array (path->entries_length, | 558 | GNUNET_array_grow (path->entries, |
448 | struct CadetPeerPathEntry); | 559 | path->entries_length, |
449 | for (;i>=0;i--) | 560 | i + 1); |
450 | { | 561 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
451 | struct CadetPeerPathEntry *entry = &path->entries[i]; | 562 | "Created new path %s based on information from DHT\n", |
452 | 563 | GCPP_2s (path)); | |
453 | entry->peer = cpath[i]; | ||
454 | entry->path = path; | ||
455 | GCP_path_entry_add (entry->peer, | ||
456 | entry, | ||
457 | i); | ||
458 | } | ||
459 | } | 564 | } |
460 | 565 | ||
461 | 566 | ||
@@ -463,15 +568,93 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
463 | * We got an incoming connection, obtain the corresponding path. | 568 | * We got an incoming connection, obtain the corresponding path. |
464 | * | 569 | * |
465 | * @param path_length number of segments on the @a path | 570 | * @param path_length number of segments on the @a path |
466 | * @param path through the network, in reverse order (we are at the end!) | 571 | * @param pids path through the network, in reverse order (we are at the end at index @a path_length) |
467 | * @return corresponding path object | 572 | * @return corresponding path object |
468 | */ | 573 | */ |
469 | struct CadetPeerPath * | 574 | struct CadetPeerPath * |
470 | GCPP_get_path_from_route (unsigned int path_length, | 575 | GCPP_get_path_from_route (unsigned int path_length, |
471 | const struct GNUNET_PeerIdentity *pids) | 576 | const struct GNUNET_PeerIdentity *pids) |
472 | { | 577 | { |
473 | GNUNET_assert (0); // FIXME! | 578 | struct CheckMatchContext cm_ctx; |
474 | return NULL; | 579 | struct CadetPeer *cpath[path_length]; |
580 | struct CadetPeerPath *path; | ||
581 | |||
582 | /* precompute inverted 'cpath' so we can avoid doing the lookups and | ||
583 | have the correct order */ | ||
584 | for (unsigned int off=0;off<path_length;off++) | ||
585 | cpath[off] = GCP_get (&pids[path_length - 1 - off], | ||
586 | GNUNET_YES); | ||
587 | |||
588 | /* First figure out if this path is a subset of an existing path, an | ||
589 | extension of an existing path, or a new path. */ | ||
590 | cm_ctx.cpath = cpath; | ||
591 | cm_ctx.cpath_length = path_length; | ||
592 | cm_ctx.match = NULL; | ||
593 | for (int i=path_length-1;i>=0;i--) | ||
594 | { | ||
595 | GCP_iterate_paths_at (cpath[i], | ||
596 | (unsigned int) i, | ||
597 | &check_match, | ||
598 | &cm_ctx); | ||
599 | if (NULL != cm_ctx.match) | ||
600 | { | ||
601 | if (i == path_length - 1) | ||
602 | { | ||
603 | /* Existing path includes this one, return the match! */ | ||
604 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
605 | "Returning existing path %s as inverse for incoming connection\n", | ||
606 | GCPP_2s (cm_ctx.match)); | ||
607 | return cm_ctx.match; | ||
608 | } | ||
609 | if (cm_ctx.match->entries_length == i + 1) | ||
610 | { | ||
611 | /* Existing path ends in the middle of new path, extend it! */ | ||
612 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
613 | "Extending existing path %s to create inverse for incoming connection\n", | ||
614 | GCPP_2s (cm_ctx.match)); | ||
615 | extend_path (cm_ctx.match, | ||
616 | &cpath[i], | ||
617 | path_length - i, | ||
618 | GNUNET_YES); | ||
619 | /* Check that extension was successful */ | ||
620 | GNUNET_assert (cm_ctx.match->entries_length == path_length); | ||
621 | return cm_ctx.match; | ||
622 | } | ||
623 | /* Eh, we found a match but couldn't use it? Something is wrong. */ | ||
624 | GNUNET_break (0); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | /* No match at all, create completely new path */ | ||
629 | path = GNUNET_new (struct CadetPeerPath); | ||
630 | path->entries_length = path_length; | ||
631 | path->entries = GNUNET_new_array (path->entries_length, | ||
632 | struct CadetPeerPathEntry *); | ||
633 | for (int i=path_length-1;i>=0;i--) | ||
634 | { | ||
635 | struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry); | ||
636 | |||
637 | path->entries[i] = entry; | ||
638 | entry->peer = cpath[i]; | ||
639 | entry->path = path; | ||
640 | } | ||
641 | for (int i=path_length-1;i>=0;i--) | ||
642 | { | ||
643 | struct CadetPeerPathEntry *entry = path->entries[i]; | ||
644 | |||
645 | GCP_path_entry_add (entry->peer, | ||
646 | entry, | ||
647 | i); | ||
648 | } | ||
649 | recalculate_path_desirability (path); | ||
650 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
651 | "Created new path %s to create inverse for incoming connection\n", | ||
652 | GCPP_2s (path)); | ||
653 | path->hn = GCP_attach_path (cpath[path_length - 1], | ||
654 | path, | ||
655 | path_length - 1, | ||
656 | GNUNET_YES); | ||
657 | return path; | ||
475 | } | 658 | } |
476 | 659 | ||
477 | 660 | ||
@@ -521,7 +704,8 @@ struct CadetPeer * | |||
521 | GCPP_get_peer_at_offset (struct CadetPeerPath *path, | 704 | GCPP_get_peer_at_offset (struct CadetPeerPath *path, |
522 | unsigned int off) | 705 | unsigned int off) |
523 | { | 706 | { |
524 | return path->entries[off].peer; | 707 | GNUNET_assert (off < path->entries_length); |
708 | return path->entries[off]->peer; | ||
525 | } | 709 | } |
526 | 710 | ||
527 | 711 | ||
@@ -531,26 +715,39 @@ GCPP_get_peer_at_offset (struct CadetPeerPath *path, | |||
531 | * @param path path to convert | 715 | * @param path path to convert |
532 | * @return string, to be freed by caller (unlike other *_2s APIs!) | 716 | * @return string, to be freed by caller (unlike other *_2s APIs!) |
533 | */ | 717 | */ |
534 | char * | 718 | const char * |
535 | GCPP_2s (struct CadetPeerPath *path) | 719 | GCPP_2s (struct CadetPeerPath *path) |
536 | { | 720 | { |
537 | char *s; | 721 | static char buf[2048]; |
538 | char *old; | 722 | size_t off; |
723 | const unsigned int max_plen = (sizeof(buf) - 16) / 5 - 2; /* 5 characters per entry */ | ||
539 | 724 | ||
540 | old = GNUNET_strdup (""); | 725 | off = 0; |
541 | for (unsigned int i = 0; | 726 | for (unsigned int i = 0; |
542 | i < path->entries_length; | 727 | i < path->entries_length; |
543 | i++) | 728 | i++) |
544 | { | 729 | { |
545 | GNUNET_asprintf (&s, | 730 | if ( (path->entries_length > max_plen) && |
546 | "%s %s", | 731 | (i == max_plen / 2) ) |
547 | old, | 732 | off += GNUNET_snprintf (&buf[off], |
548 | GCP_2s (GCPP_get_peer_at_offset (path, | 733 | sizeof (buf) - off, |
549 | i))); | 734 | "...-"); |
550 | GNUNET_free_non_null (old); | 735 | if ( (path->entries_length > max_plen) && |
551 | old = s; | 736 | (i > max_plen / 2) && |
737 | (i < path->entries_length - max_plen / 2) ) | ||
738 | continue; | ||
739 | off += GNUNET_snprintf (&buf[off], | ||
740 | sizeof (buf) - off, | ||
741 | "%s%s", | ||
742 | GNUNET_i2s (GCP_get_id (GCPP_get_peer_at_offset (path, | ||
743 | i))), | ||
744 | (i == path->entries_length -1) ? "" : "-"); | ||
552 | } | 745 | } |
553 | return old; | 746 | GNUNET_snprintf (&buf[off], |
747 | sizeof (buf) - off, | ||
748 | "(%p)", | ||
749 | path); | ||
750 | return buf; | ||
554 | } | 751 | } |
555 | 752 | ||
556 | 753 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_paths.h b/src/cadet/gnunet-service-cadet-new_paths.h index 5714368c7..7310d75e6 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.h +++ b/src/cadet/gnunet-service-cadet-new_paths.h | |||
@@ -173,9 +173,9 @@ GCPP_get_peer_at_offset (struct CadetPeerPath *path, | |||
173 | * Convert a path to a human-readable string. | 173 | * Convert a path to a human-readable string. |
174 | * | 174 | * |
175 | * @param path path to convert | 175 | * @param path path to convert |
176 | * @return string, to be freed by caller (unlike other *_2s APIs!) | 176 | * @return string, statically allocated |
177 | */ | 177 | */ |
178 | char * | 178 | const char * |
179 | GCPP_2s (struct CadetPeerPath *p); | 179 | GCPP_2s (struct CadetPeerPath *p); |
180 | 180 | ||
181 | 181 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c index 47f725e09..fe40d76b6 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.c +++ b/src/cadet/gnunet-service-cadet-new_peer.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
4 | Copyright (C) 2001-2017 GNUnet e.V. | 3 | Copyright (C) 2001-2017 GNUnet e.V. |
@@ -26,7 +25,6 @@ | |||
26 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
27 | * | 26 | * |
28 | * TODO: | 27 | * TODO: |
29 | * - implement GCP_set_hello() / do HELLO advertising properly | ||
30 | * - optimize stopping/restarting DHT search to situations | 28 | * - optimize stopping/restarting DHT search to situations |
31 | * where we actually need it (i.e. not if we have a direct connection, | 29 | * where we actually need it (i.e. not if we have a direct connection, |
32 | * or if we already have plenty of good short ones, or maybe even | 30 | * or if we already have plenty of good short ones, or maybe even |
@@ -35,13 +33,13 @@ | |||
35 | */ | 33 | */ |
36 | #include "platform.h" | 34 | #include "platform.h" |
37 | #include "gnunet_util_lib.h" | 35 | #include "gnunet_util_lib.h" |
36 | #include "gnunet_hello_lib.h" | ||
38 | #include "gnunet_signatures.h" | 37 | #include "gnunet_signatures.h" |
39 | #include "gnunet_transport_service.h" | 38 | #include "gnunet_transport_service.h" |
40 | #include "gnunet_ats_service.h" | 39 | #include "gnunet_ats_service.h" |
41 | #include "gnunet_core_service.h" | 40 | #include "gnunet_core_service.h" |
42 | #include "gnunet_statistics_service.h" | 41 | #include "gnunet_statistics_service.h" |
43 | #include "cadet_protocol.h" | 42 | #include "cadet_protocol.h" |
44 | #include "cadet_path.h" | ||
45 | #include "gnunet-service-cadet-new.h" | 43 | #include "gnunet-service-cadet-new.h" |
46 | #include "gnunet-service-cadet-new_connection.h" | 44 | #include "gnunet-service-cadet-new_connection.h" |
47 | #include "gnunet-service-cadet-new_dht.h" | 45 | #include "gnunet-service-cadet-new_dht.h" |
@@ -49,6 +47,10 @@ | |||
49 | #include "gnunet-service-cadet-new_paths.h" | 47 | #include "gnunet-service-cadet-new_paths.h" |
50 | #include "gnunet-service-cadet-new_tunnels.h" | 48 | #include "gnunet-service-cadet-new_tunnels.h" |
51 | 49 | ||
50 | |||
51 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-per",__VA_ARGS__) | ||
52 | |||
53 | |||
52 | /** | 54 | /** |
53 | * How long do we wait until tearing down an idle peer? | 55 | * How long do we wait until tearing down an idle peer? |
54 | */ | 56 | */ |
@@ -222,16 +224,19 @@ struct CadetPeer | |||
222 | /** | 224 | /** |
223 | * Get the static string for a peer ID. | 225 | * Get the static string for a peer ID. |
224 | * | 226 | * |
225 | * @param peer Peer. | 227 | * @param cp Peer. |
226 | * | ||
227 | * @return Static string for it's ID. | 228 | * @return Static string for it's ID. |
228 | */ | 229 | */ |
229 | const char * | 230 | const char * |
230 | GCP_2s (const struct CadetPeer *peer) | 231 | GCP_2s (const struct CadetPeer *cp) |
231 | { | 232 | { |
232 | if (NULL == peer) | 233 | static char buf[32]; |
233 | return "PEER(NULL)"; | 234 | |
234 | return GNUNET_i2s (&peer->pid); | 235 | GNUNET_snprintf (buf, |
236 | sizeof (buf), | ||
237 | "P(%s)", | ||
238 | GNUNET_i2s (&cp->pid)); | ||
239 | return buf; | ||
235 | } | 240 | } |
236 | 241 | ||
237 | 242 | ||
@@ -245,10 +250,14 @@ destroy_peer (void *cls) | |||
245 | { | 250 | { |
246 | struct CadetPeer *cp = cls; | 251 | struct CadetPeer *cp = cls; |
247 | 252 | ||
253 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
254 | "Destroying state about peer %s\n", | ||
255 | GCP_2s (cp)); | ||
248 | cp->destroy_task = NULL; | 256 | cp->destroy_task = NULL; |
249 | GNUNET_assert (NULL == cp->t); | 257 | GNUNET_assert (NULL == cp->t); |
250 | GNUNET_assert (NULL == cp->core_mq); | 258 | GNUNET_assert (NULL == cp->core_mq); |
251 | GNUNET_assert (0 == cp->path_dll_length); | 259 | for (unsigned int i=0;i<cp->path_dll_length;i++) |
260 | GNUNET_assert (NULL == cp->path_heads[i]); | ||
252 | GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)); | 261 | GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)); |
253 | GNUNET_assert (GNUNET_YES == | 262 | GNUNET_assert (GNUNET_YES == |
254 | GNUNET_CONTAINER_multipeermap_remove (peers, | 263 | GNUNET_CONTAINER_multipeermap_remove (peers, |
@@ -275,7 +284,11 @@ destroy_peer (void *cls) | |||
275 | cp->connectivity_suggestion = NULL; | 284 | cp->connectivity_suggestion = NULL; |
276 | } | 285 | } |
277 | GNUNET_CONTAINER_multishortmap_destroy (cp->connections); | 286 | GNUNET_CONTAINER_multishortmap_destroy (cp->connections); |
278 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); | 287 | if (NULL != cp->path_heap) |
288 | { | ||
289 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); | ||
290 | cp->path_heap = NULL; | ||
291 | } | ||
279 | GNUNET_free_non_null (cp->hello); | 292 | GNUNET_free_non_null (cp->hello); |
280 | /* Peer should not be freed if paths exist; if there are no paths, | 293 | /* Peer should not be freed if paths exist; if there are no paths, |
281 | there ought to be no connections, and without connections, no | 294 | there ought to be no connections, and without connections, no |
@@ -287,6 +300,147 @@ destroy_peer (void *cls) | |||
287 | 300 | ||
288 | 301 | ||
289 | /** | 302 | /** |
303 | * This peer is now on more "active" duty, activate processes related to it. | ||
304 | * | ||
305 | * @param cp the more-active peer | ||
306 | */ | ||
307 | static void | ||
308 | consider_peer_activate (struct CadetPeer *cp) | ||
309 | { | ||
310 | uint32_t strength; | ||
311 | |||
312 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
313 | "Updating peer %s activation state (%u connections)%s%s\n", | ||
314 | GCP_2s (cp), | ||
315 | GNUNET_CONTAINER_multishortmap_size (cp->connections), | ||
316 | (NULL == cp->t) ? "" : " with tunnel", | ||
317 | (NULL == cp->core_mq) ? "" : " with CORE link"); | ||
318 | if (NULL != cp->destroy_task) | ||
319 | { | ||
320 | /* It's active, do not destory! */ | ||
321 | GNUNET_SCHEDULER_cancel (cp->destroy_task); | ||
322 | cp->destroy_task = NULL; | ||
323 | } | ||
324 | if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) && | ||
325 | (NULL == cp->t) ) | ||
326 | { | ||
327 | /* We're just on a path or directly connected; don't bother too much */ | ||
328 | if (NULL != cp->connectivity_suggestion) | ||
329 | { | ||
330 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); | ||
331 | cp->connectivity_suggestion = NULL; | ||
332 | } | ||
333 | if (NULL != cp->search_h) | ||
334 | { | ||
335 | GCD_search_stop (cp->search_h); | ||
336 | cp->search_h = NULL; | ||
337 | } | ||
338 | return; | ||
339 | } | ||
340 | if (NULL == cp->core_mq) | ||
341 | { | ||
342 | /* Lacks direct connection, try to create one by querying the DHT */ | ||
343 | if ( (NULL == cp->search_h) && | ||
344 | (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) ) | ||
345 | cp->search_h | ||
346 | = GCD_search (&cp->pid); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | /* Have direct connection, stop DHT search if active */ | ||
351 | if (NULL != cp->search_h) | ||
352 | { | ||
353 | GCD_search_stop (cp->search_h); | ||
354 | cp->search_h = NULL; | ||
355 | } | ||
356 | } | ||
357 | |||
358 | /* If we have a tunnel, our urge for connections is much bigger */ | ||
359 | strength = (NULL != cp->t) ? 32 : 1; | ||
360 | if (NULL != cp->connectivity_suggestion) | ||
361 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); | ||
362 | cp->connectivity_suggestion | ||
363 | = GNUNET_ATS_connectivity_suggest (ats_ch, | ||
364 | &cp->pid, | ||
365 | strength); | ||
366 | } | ||
367 | |||
368 | |||
369 | /** | ||
370 | * This peer may no longer be needed, consider cleaning it up. | ||
371 | * | ||
372 | * @param cp peer to clean up | ||
373 | */ | ||
374 | static void | ||
375 | consider_peer_destroy (struct CadetPeer *cp); | ||
376 | |||
377 | |||
378 | /** | ||
379 | * We really no longere care about a peer, stop hogging memory with paths to it. | ||
380 | * Afterwards, see if there is more to be cleaned up about this peer. | ||
381 | * | ||
382 | * @param cls a `struct CadetPeer`. | ||
383 | */ | ||
384 | static void | ||
385 | drop_paths (void *cls) | ||
386 | { | ||
387 | struct CadetPeer *cp = cls; | ||
388 | struct CadetPeerPath *path; | ||
389 | |||
390 | cp->destroy_task = NULL; | ||
391 | while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap))) | ||
392 | GCPP_release (path); | ||
393 | consider_peer_destroy (cp); | ||
394 | } | ||
395 | |||
396 | |||
397 | /** | ||
398 | * This peer may no longer be needed, consider cleaning it up. | ||
399 | * | ||
400 | * @param cp peer to clean up | ||
401 | */ | ||
402 | static void | ||
403 | consider_peer_destroy (struct CadetPeer *cp) | ||
404 | { | ||
405 | struct GNUNET_TIME_Relative exp; | ||
406 | |||
407 | if (NULL != cp->destroy_task) | ||
408 | { | ||
409 | GNUNET_SCHEDULER_cancel (cp->destroy_task); | ||
410 | cp->destroy_task = NULL; | ||
411 | } | ||
412 | if (NULL != cp->t) | ||
413 | return; /* still relevant! */ | ||
414 | if (NULL != cp->core_mq) | ||
415 | return; /* still relevant! */ | ||
416 | if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections)) | ||
417 | return; /* still relevant! */ | ||
418 | if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap)) | ||
419 | { | ||
420 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT, | ||
421 | &drop_paths, | ||
422 | cp); | ||
423 | return; | ||
424 | } | ||
425 | for (unsigned int i=0;i<cp->path_dll_length;i++) | ||
426 | if (NULL != cp->path_heads[i]) | ||
427 | return; /* still relevant! */ | ||
428 | if (NULL != cp->hello) | ||
429 | { | ||
430 | /* relevant only until HELLO expires */ | ||
431 | exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello)); | ||
432 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp, | ||
433 | &destroy_peer, | ||
434 | cp); | ||
435 | return; | ||
436 | } | ||
437 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT, | ||
438 | &destroy_peer, | ||
439 | cp); | ||
440 | } | ||
441 | |||
442 | |||
443 | /** | ||
290 | * Set the message queue to @a mq for peer @a cp and notify watchers. | 444 | * Set the message queue to @a mq for peer @a cp and notify watchers. |
291 | * | 445 | * |
292 | * @param cp peer to modify | 446 | * @param cp peer to modify |
@@ -296,8 +450,11 @@ void | |||
296 | GCP_set_mq (struct CadetPeer *cp, | 450 | GCP_set_mq (struct CadetPeer *cp, |
297 | struct GNUNET_MQ_Handle *mq) | 451 | struct GNUNET_MQ_Handle *mq) |
298 | { | 452 | { |
453 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
454 | "Message queue for peer %s is now %p\n", | ||
455 | GCP_2s (cp), | ||
456 | mq); | ||
299 | cp->core_mq = mq; | 457 | cp->core_mq = mq; |
300 | |||
301 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; | 458 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; |
302 | NULL != mqm; | 459 | NULL != mqm; |
303 | mqm = mqm->next) | 460 | mqm = mqm->next) |
@@ -324,6 +481,24 @@ GCP_set_mq (struct CadetPeer *cp, | |||
324 | GNUNET_YES); | 481 | GNUNET_YES); |
325 | } | 482 | } |
326 | } | 483 | } |
484 | if ( (NULL != mq) || | ||
485 | (NULL != cp->t) ) | ||
486 | consider_peer_activate (cp); | ||
487 | else | ||
488 | consider_peer_destroy (cp); | ||
489 | |||
490 | if ( (NULL != mq) && | ||
491 | (NULL != cp->t) ) | ||
492 | { | ||
493 | /* have a new, direct path to the target, notify tunnel */ | ||
494 | struct CadetPeerPath *path; | ||
495 | |||
496 | path = GCPP_get_path_from_route (1, | ||
497 | &cp->pid); | ||
498 | GCT_consider_path (cp->t, | ||
499 | path, | ||
500 | 0); | ||
501 | } | ||
327 | } | 502 | } |
328 | 503 | ||
329 | 504 | ||
@@ -337,6 +512,10 @@ mqm_execute (struct GCP_MessageQueueManager *mqm) | |||
337 | { | 512 | { |
338 | struct CadetPeer *cp = mqm->cp; | 513 | struct CadetPeer *cp = mqm->cp; |
339 | 514 | ||
515 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
516 | "Sending to peer %s from MQM %p\n", | ||
517 | GCP_2s (cp), | ||
518 | mqm); | ||
340 | /* Move entry to the end of the DLL, to be fair. */ | 519 | /* Move entry to the end of the DLL, to be fair. */ |
341 | if (mqm != cp->mqm_tail) | 520 | if (mqm != cp->mqm_tail) |
342 | { | 521 | { |
@@ -351,6 +530,8 @@ mqm_execute (struct GCP_MessageQueueManager *mqm) | |||
351 | mqm->env); | 530 | mqm->env); |
352 | mqm->env = NULL; | 531 | mqm->env = NULL; |
353 | cp->mqm_ready_counter--; | 532 | cp->mqm_ready_counter--; |
533 | mqm->cb (mqm->cb_cls, | ||
534 | GNUNET_YES); | ||
354 | } | 535 | } |
355 | 536 | ||
356 | 537 | ||
@@ -365,6 +546,9 @@ mqm_send_done (void *cls) | |||
365 | { | 546 | { |
366 | struct CadetPeer *cp = cls; | 547 | struct CadetPeer *cp = cls; |
367 | 548 | ||
549 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
550 | "Sending to peer %s completed\n", | ||
551 | GCP_2s (cp)); | ||
368 | if (0 == cp->mqm_ready_counter) | 552 | if (0 == cp->mqm_ready_counter) |
369 | return; /* nothing to do */ | 553 | return; /* nothing to do */ |
370 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; | 554 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; |
@@ -392,6 +576,10 @@ GCP_send (struct GCP_MessageQueueManager *mqm, | |||
392 | { | 576 | { |
393 | struct CadetPeer *cp = mqm->cp; | 577 | struct CadetPeer *cp = mqm->cp; |
394 | 578 | ||
579 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
580 | "Queueing message to peer %s in MQM %p\n", | ||
581 | GCP_2s (cp), | ||
582 | mqm); | ||
395 | GNUNET_assert (NULL != cp->core_mq); | 583 | GNUNET_assert (NULL != cp->core_mq); |
396 | GNUNET_assert (NULL == mqm->env); | 584 | GNUNET_assert (NULL == mqm->env); |
397 | GNUNET_MQ_notify_sent (env, | 585 | GNUNET_MQ_notify_sent (env, |
@@ -438,6 +626,8 @@ destroy_iterator_cb (void *cls, | |||
438 | void | 626 | void |
439 | GCP_destroy_all_peers () | 627 | GCP_destroy_all_peers () |
440 | { | 628 | { |
629 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
630 | "Destroying all peers now\n"); | ||
441 | GNUNET_CONTAINER_multipeermap_iterate (peers, | 631 | GNUNET_CONTAINER_multipeermap_iterate (peers, |
442 | &destroy_iterator_cb, | 632 | &destroy_iterator_cb, |
443 | NULL); | 633 | NULL); |
@@ -445,75 +635,24 @@ GCP_destroy_all_peers () | |||
445 | 635 | ||
446 | 636 | ||
447 | /** | 637 | /** |
448 | * This peer may no longer be needed, consider cleaning it up. | 638 | * Drop all paths owned by this peer, and do not |
449 | * | 639 | * allow new ones to be added: We are shutting down. |
450 | * @param cp peer to clean up | ||
451 | */ | ||
452 | static void | ||
453 | consider_peer_destroy (struct CadetPeer *cp); | ||
454 | |||
455 | |||
456 | /** | ||
457 | * We really no longere care about a peer, stop hogging memory with paths to it. | ||
458 | * Afterwards, see if there is more to be cleaned up about this peer. | ||
459 | * | 640 | * |
460 | * @param cls a `struct CadetPeer`. | 641 | * @param cp peer to drop paths to |
461 | */ | 642 | */ |
462 | static void | 643 | void |
463 | drop_paths (void *cls) | 644 | GCP_drop_owned_paths (struct CadetPeer *cp) |
464 | { | 645 | { |
465 | struct CadetPeer *cp = cls; | ||
466 | struct CadetPeerPath *path; | 646 | struct CadetPeerPath *path; |
467 | 647 | ||
468 | cp->destroy_task = NULL; | 648 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
469 | while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap))) | 649 | "Destroying all paths to %s\n", |
650 | GCP_2s (cp)); | ||
651 | while (NULL != (path = | ||
652 | GNUNET_CONTAINER_heap_remove_root (cp->path_heap))) | ||
470 | GCPP_release (path); | 653 | GCPP_release (path); |
471 | consider_peer_destroy (cp); | 654 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); |
472 | } | 655 | cp->path_heap = NULL; |
473 | |||
474 | |||
475 | /** | ||
476 | * This peer may no longer be needed, consider cleaning it up. | ||
477 | * | ||
478 | * @param cp peer to clean up | ||
479 | */ | ||
480 | static void | ||
481 | consider_peer_destroy (struct CadetPeer *cp) | ||
482 | { | ||
483 | struct GNUNET_TIME_Relative exp; | ||
484 | |||
485 | if (NULL != cp->destroy_task) | ||
486 | { | ||
487 | GNUNET_SCHEDULER_cancel (cp->destroy_task); | ||
488 | cp->destroy_task = NULL; | ||
489 | } | ||
490 | if (NULL != cp->t) | ||
491 | return; /* still relevant! */ | ||
492 | if (NULL != cp->core_mq) | ||
493 | return; /* still relevant! */ | ||
494 | if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections)) | ||
495 | return; /* still relevant! */ | ||
496 | if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap)) | ||
497 | { | ||
498 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT, | ||
499 | &drop_paths, | ||
500 | cp); | ||
501 | return; | ||
502 | } | ||
503 | if (0 < cp->path_dll_length) | ||
504 | return; /* still relevant! */ | ||
505 | if (NULL != cp->hello) | ||
506 | { | ||
507 | /* relevant only until HELLO expires */ | ||
508 | exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello)); | ||
509 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp, | ||
510 | &destroy_peer, | ||
511 | cp); | ||
512 | return; | ||
513 | } | ||
514 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT, | ||
515 | &destroy_peer, | ||
516 | cp); | ||
517 | } | 656 | } |
518 | 657 | ||
519 | 658 | ||
@@ -529,6 +668,13 @@ GCP_path_entry_add (struct CadetPeer *cp, | |||
529 | struct CadetPeerPathEntry *entry, | 668 | struct CadetPeerPathEntry *entry, |
530 | unsigned int off) | 669 | unsigned int off) |
531 | { | 670 | { |
671 | GNUNET_assert (cp == GCPP_get_peer_at_offset (entry->path, | ||
672 | off)); | ||
673 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
674 | "Discovered that peer %s is on path %s at offset %u\n", | ||
675 | GCP_2s (cp), | ||
676 | GCPP_2s (entry->path), | ||
677 | off); | ||
532 | if (off >= cp->path_dll_length) | 678 | if (off >= cp->path_dll_length) |
533 | { | 679 | { |
534 | unsigned int len = cp->path_dll_length; | 680 | unsigned int len = cp->path_dll_length; |
@@ -551,6 +697,14 @@ GCP_path_entry_add (struct CadetPeer *cp, | |||
551 | GCT_consider_path (cp->t, | 697 | GCT_consider_path (cp->t, |
552 | entry->path, | 698 | entry->path, |
553 | off); | 699 | off); |
700 | |||
701 | if ( (NULL != cp->search_h) && | ||
702 | (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) ) | ||
703 | { | ||
704 | /* Now I have enough paths, stop search */ | ||
705 | GCD_search_stop (cp->search_h); | ||
706 | cp->search_h = NULL; | ||
707 | } | ||
554 | } | 708 | } |
555 | 709 | ||
556 | 710 | ||
@@ -566,11 +720,22 @@ GCP_path_entry_remove (struct CadetPeer *cp, | |||
566 | struct CadetPeerPathEntry *entry, | 720 | struct CadetPeerPathEntry *entry, |
567 | unsigned int off) | 721 | unsigned int off) |
568 | { | 722 | { |
723 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
724 | "Removing knowledge about peer %s beging on path %s at offset %u\n", | ||
725 | GCP_2s (cp), | ||
726 | GCPP_2s (entry->path), | ||
727 | off); | ||
569 | GNUNET_CONTAINER_DLL_remove (cp->path_heads[off], | 728 | GNUNET_CONTAINER_DLL_remove (cp->path_heads[off], |
570 | cp->path_tails[off], | 729 | cp->path_tails[off], |
571 | entry); | 730 | entry); |
572 | GNUNET_assert (0 < cp->num_paths); | 731 | GNUNET_assert (0 < cp->num_paths); |
573 | cp->num_paths--; | 732 | cp->num_paths--; |
733 | if ( (NULL == cp->core_mq) && | ||
734 | (NULL != cp->t) && | ||
735 | (NULL == cp->search_h) && | ||
736 | (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) ) | ||
737 | cp->search_h | ||
738 | = GCD_search (&cp->pid); | ||
574 | } | 739 | } |
575 | 740 | ||
576 | 741 | ||
@@ -581,37 +746,62 @@ GCP_path_entry_remove (struct CadetPeer *cp, | |||
581 | * @param cp peer to which the @a path leads to | 746 | * @param cp peer to which the @a path leads to |
582 | * @param path a path looking for an owner; may not be fully initialized yet! | 747 | * @param path a path looking for an owner; may not be fully initialized yet! |
583 | * @param off offset of @a cp in @a path | 748 | * @param off offset of @a cp in @a path |
749 | * @param force force attaching the path | ||
584 | * @return NULL if this peer does not care to become a new owner, | 750 | * @return NULL if this peer does not care to become a new owner, |
585 | * otherwise the node in the peer's path heap for the @a path. | 751 | * otherwise the node in the peer's path heap for the @a path. |
586 | */ | 752 | */ |
587 | struct GNUNET_CONTAINER_HeapNode * | 753 | struct GNUNET_CONTAINER_HeapNode * |
588 | GCP_attach_path (struct CadetPeer *cp, | 754 | GCP_attach_path (struct CadetPeer *cp, |
589 | struct CadetPeerPath *path, | 755 | struct CadetPeerPath *path, |
590 | unsigned int off) | 756 | unsigned int off, |
757 | int force) | ||
591 | { | 758 | { |
592 | GNUNET_CONTAINER_HeapCostType desirability; | 759 | GNUNET_CONTAINER_HeapCostType desirability; |
593 | struct CadetPeerPath *root; | 760 | struct CadetPeerPath *root; |
594 | GNUNET_CONTAINER_HeapCostType root_desirability; | 761 | GNUNET_CONTAINER_HeapCostType root_desirability; |
595 | struct GNUNET_CONTAINER_HeapNode *hn; | 762 | struct GNUNET_CONTAINER_HeapNode *hn; |
596 | 763 | ||
597 | /* FIXME: desirability is not yet initialized; tricky! */ | 764 | GNUNET_assert (cp == GCPP_get_peer_at_offset (path, |
765 | off)); | ||
766 | if (NULL == cp->path_heap) | ||
767 | { | ||
768 | /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */ | ||
769 | GNUNET_assert (GNUNET_NO == force); | ||
770 | return NULL; | ||
771 | } | ||
598 | desirability = GCPP_get_desirability (path); | 772 | desirability = GCPP_get_desirability (path); |
599 | if (GNUNET_NO == | 773 | if (GNUNET_NO == force) |
600 | GNUNET_CONTAINER_heap_peek2 (cp->path_heap, | ||
601 | (void **) &root, | ||
602 | &root_desirability)) | ||
603 | { | 774 | { |
604 | root = NULL; | 775 | /* FIXME: desirability is not yet initialized; tricky! */ |
605 | root_desirability = 0; | 776 | if (GNUNET_NO == |
777 | GNUNET_CONTAINER_heap_peek2 (cp->path_heap, | ||
778 | (void **) &root, | ||
779 | &root_desirability)) | ||
780 | { | ||
781 | root = NULL; | ||
782 | root_desirability = 0; | ||
783 | } | ||
784 | |||
785 | if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) && | ||
786 | (desirability < root_desirability) ) | ||
787 | { | ||
788 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
789 | "Decided to not attach path %p to peer %s due to undesirability\n", | ||
790 | GCPP_2s (path), | ||
791 | GCP_2s (cp)); | ||
792 | return NULL; | ||
793 | } | ||
606 | } | 794 | } |
607 | 795 | ||
608 | if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) && | 796 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
609 | (desirability < root_desirability) ) | 797 | "Attaching path %s to peer %s (%s)\n", |
610 | return NULL; | 798 | GCPP_2s (path), |
799 | GCP_2s (cp), | ||
800 | (GNUNET_NO == force) ? "desirable" : "forced"); | ||
611 | 801 | ||
612 | /* Yes, we'd like to add this path, add to our heap */ | 802 | /* Yes, we'd like to add this path, add to our heap */ |
613 | hn = GNUNET_CONTAINER_heap_insert (cp->path_heap, | 803 | hn = GNUNET_CONTAINER_heap_insert (cp->path_heap, |
614 | (void *) cp, | 804 | path, |
615 | desirability); | 805 | desirability); |
616 | 806 | ||
617 | /* Consider maybe dropping other paths because of the new one */ | 807 | /* Consider maybe dropping other paths because of the new one */ |
@@ -623,10 +813,11 @@ GCP_attach_path (struct CadetPeer *cp, | |||
623 | unused paths around in the hope that we might be able to switch, even | 813 | unused paths around in the hope that we might be able to switch, even |
624 | if the number of paths exceeds the threshold.) */ | 814 | if the number of paths exceeds the threshold.) */ |
625 | root = GNUNET_CONTAINER_heap_peek (cp->path_heap); | 815 | root = GNUNET_CONTAINER_heap_peek (cp->path_heap); |
626 | if (NULL == | 816 | if ( (path != root) && |
627 | GCPP_get_connection (root, | 817 | (NULL == |
628 | cp, | 818 | GCPP_get_connection (root, |
629 | GCPP_get_length (root) - 1)) | 819 | cp, |
820 | GCPP_get_length (root) - 1)) ) | ||
630 | { | 821 | { |
631 | /* Got plenty of paths to this destination, and this is a low-quality | 822 | /* Got plenty of paths to this destination, and this is a low-quality |
632 | one that we don't care, allow it to die. */ | 823 | one that we don't care, allow it to die. */ |
@@ -653,6 +844,10 @@ GCP_detach_path (struct CadetPeer *cp, | |||
653 | struct CadetPeerPath *path, | 844 | struct CadetPeerPath *path, |
654 | struct GNUNET_CONTAINER_HeapNode *hn) | 845 | struct GNUNET_CONTAINER_HeapNode *hn) |
655 | { | 846 | { |
847 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
848 | "Detatching path %s from peer %s\n", | ||
849 | GCPP_2s (path), | ||
850 | GCP_2s (cp)); | ||
656 | GNUNET_assert (path == | 851 | GNUNET_assert (path == |
657 | GNUNET_CONTAINER_heap_remove_node (hn)); | 852 | GNUNET_CONTAINER_heap_remove_node (hn)); |
658 | } | 853 | } |
@@ -668,6 +863,10 @@ void | |||
668 | GCP_add_connection (struct CadetPeer *cp, | 863 | GCP_add_connection (struct CadetPeer *cp, |
669 | struct CadetConnection *cc) | 864 | struct CadetConnection *cc) |
670 | { | 865 | { |
866 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
867 | "Adding connection %s to peer %s\n", | ||
868 | GCC_2s (cc), | ||
869 | GCP_2s (cp)); | ||
671 | GNUNET_assert (GNUNET_OK == | 870 | GNUNET_assert (GNUNET_OK == |
672 | GNUNET_CONTAINER_multishortmap_put (cp->connections, | 871 | GNUNET_CONTAINER_multishortmap_put (cp->connections, |
673 | &GCC_get_id (cc)->connection_of_tunnel, | 872 | &GCC_get_id (cc)->connection_of_tunnel, |
@@ -686,6 +885,10 @@ void | |||
686 | GCP_remove_connection (struct CadetPeer *cp, | 885 | GCP_remove_connection (struct CadetPeer *cp, |
687 | struct CadetConnection *cc) | 886 | struct CadetConnection *cc) |
688 | { | 887 | { |
888 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
889 | "Removing connection %s from peer %s\n", | ||
890 | GCC_2s (cc), | ||
891 | GCP_2s (cp)); | ||
689 | GNUNET_assert (GNUNET_YES == | 892 | GNUNET_assert (GNUNET_YES == |
690 | GNUNET_CONTAINER_multishortmap_remove (cp->connections, | 893 | GNUNET_CONTAINER_multishortmap_remove (cp->connections, |
691 | &GCC_get_id (cc)->connection_of_tunnel, | 894 | &GCC_get_id (cc)->connection_of_tunnel, |
@@ -694,67 +897,6 @@ GCP_remove_connection (struct CadetPeer *cp, | |||
694 | 897 | ||
695 | 898 | ||
696 | /** | 899 | /** |
697 | * This peer is now on more "active" duty, activate processes related to it. | ||
698 | * | ||
699 | * @param cp the more-active peer | ||
700 | */ | ||
701 | static void | ||
702 | consider_peer_activate (struct CadetPeer *cp) | ||
703 | { | ||
704 | uint32_t strength; | ||
705 | |||
706 | if (NULL != cp->destroy_task) | ||
707 | { | ||
708 | /* It's active, do not destory! */ | ||
709 | GNUNET_SCHEDULER_cancel (cp->destroy_task); | ||
710 | cp->destroy_task = NULL; | ||
711 | } | ||
712 | if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) && | ||
713 | (NULL == cp->t) ) | ||
714 | { | ||
715 | /* We're just on a path or directly connected; don't bother too much */ | ||
716 | if (NULL != cp->connectivity_suggestion) | ||
717 | { | ||
718 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); | ||
719 | cp->connectivity_suggestion = NULL; | ||
720 | } | ||
721 | if (NULL != cp->search_h) | ||
722 | { | ||
723 | GCD_search_stop (cp->search_h); | ||
724 | cp->search_h = NULL; | ||
725 | } | ||
726 | return; | ||
727 | } | ||
728 | if (NULL == cp->core_mq) | ||
729 | { | ||
730 | /* Lacks direct connection, try to create one by querying the DHT */ | ||
731 | if ( (NULL == cp->search_h) && | ||
732 | (DESIRED_CONNECTIONS_PER_TUNNEL < cp->num_paths) ) | ||
733 | cp->search_h | ||
734 | = GCD_search (&cp->pid); | ||
735 | } | ||
736 | else | ||
737 | { | ||
738 | /* Have direct connection, stop DHT search if active */ | ||
739 | if (NULL != cp->search_h) | ||
740 | { | ||
741 | GCD_search_stop (cp->search_h); | ||
742 | cp->search_h = NULL; | ||
743 | } | ||
744 | } | ||
745 | |||
746 | /* If we have a tunnel, our urge for connections is much bigger */ | ||
747 | strength = (NULL != cp->t) ? 32 : 1; | ||
748 | if (NULL != cp->connectivity_suggestion) | ||
749 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); | ||
750 | cp->connectivity_suggestion | ||
751 | = GNUNET_ATS_connectivity_suggest (ats_ch, | ||
752 | &cp->pid, | ||
753 | strength); | ||
754 | } | ||
755 | |||
756 | |||
757 | /** | ||
758 | * Retrieve the CadetPeer stucture associated with the | 900 | * Retrieve the CadetPeer stucture associated with the |
759 | * peer. Optionally create one and insert it in the appropriate | 901 | * peer. Optionally create one and insert it in the appropriate |
760 | * structures if the peer is not known yet. | 902 | * structures if the peer is not known yet. |
@@ -787,6 +929,9 @@ GCP_get (const struct GNUNET_PeerIdentity *peer_id, | |||
787 | &cp->pid, | 929 | &cp->pid, |
788 | cp, | 930 | cp, |
789 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 931 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
932 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
933 | "Creating peer %s\n", | ||
934 | GCP_2s (cp)); | ||
790 | return cp; | 935 | return cp; |
791 | } | 936 | } |
792 | 937 | ||
@@ -823,43 +968,60 @@ GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, | |||
823 | /** | 968 | /** |
824 | * Count the number of known paths toward the peer. | 969 | * Count the number of known paths toward the peer. |
825 | * | 970 | * |
826 | * @param peer Peer to get path info. | 971 | * @param cp Peer to get path info. |
827 | * @return Number of known paths. | 972 | * @return Number of known paths. |
828 | */ | 973 | */ |
829 | unsigned int | 974 | unsigned int |
830 | GCP_count_paths (const struct CadetPeer *peer) | 975 | GCP_count_paths (const struct CadetPeer *cp) |
831 | { | 976 | { |
832 | return peer->num_paths; | 977 | return cp->num_paths; |
833 | } | 978 | } |
834 | 979 | ||
835 | 980 | ||
836 | /** | 981 | /** |
837 | * Iterate over the paths to a peer. | 982 | * Iterate over the paths to a peer. |
838 | * | 983 | * |
839 | * @param peer Peer to get path info. | 984 | * @param cp Peer to get path info. |
840 | * @param callback Function to call for every path. | 985 | * @param callback Function to call for every path. |
841 | * @param callback_cls Closure for @a callback. | 986 | * @param callback_cls Closure for @a callback. |
842 | * @return Number of iterated paths. | 987 | * @return Number of iterated paths. |
843 | */ | 988 | */ |
844 | unsigned int | 989 | unsigned int |
845 | GCP_iterate_paths (struct CadetPeer *peer, | 990 | GCP_iterate_paths (struct CadetPeer *cp, |
846 | GCP_PathIterator callback, | 991 | GCP_PathIterator callback, |
847 | void *callback_cls) | 992 | void *callback_cls) |
848 | { | 993 | { |
849 | unsigned int ret = 0; | 994 | unsigned int ret = 0; |
850 | 995 | ||
851 | for (unsigned int i=0;i<peer->path_dll_length;i++) | 996 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
997 | "Iterating over paths to peer %s%s\n", | ||
998 | GCP_2s (cp), | ||
999 | (NULL == cp->core_mq) ? "" : " including direct link"); | ||
1000 | if (NULL != cp->core_mq) | ||
1001 | { | ||
1002 | struct CadetPeerPath *path; | ||
1003 | |||
1004 | path = GCPP_get_path_from_route (1, | ||
1005 | &cp->pid); | ||
1006 | ret++; | ||
1007 | if (GNUNET_NO == | ||
1008 | callback (callback_cls, | ||
1009 | path, | ||
1010 | 1)) | ||
1011 | return ret; | ||
1012 | } | ||
1013 | for (unsigned int i=0;i<cp->path_dll_length;i++) | ||
852 | { | 1014 | { |
853 | for (struct CadetPeerPathEntry *pe = peer->path_heads[i]; | 1015 | for (struct CadetPeerPathEntry *pe = cp->path_heads[i]; |
854 | NULL != pe; | 1016 | NULL != pe; |
855 | pe = pe->next) | 1017 | pe = pe->next) |
856 | { | 1018 | { |
1019 | ret++; | ||
857 | if (GNUNET_NO == | 1020 | if (GNUNET_NO == |
858 | callback (callback_cls, | 1021 | callback (callback_cls, |
859 | pe->path, | 1022 | pe->path, |
860 | i)) | 1023 | i)) |
861 | return ret; | 1024 | return ret; |
862 | ret++; | ||
863 | } | 1025 | } |
864 | } | 1026 | } |
865 | return ret; | 1027 | return ret; |
@@ -867,26 +1029,32 @@ GCP_iterate_paths (struct CadetPeer *peer, | |||
867 | 1029 | ||
868 | 1030 | ||
869 | /** | 1031 | /** |
870 | * Iterate over the paths to @a peer where | 1032 | * Iterate over the paths to @a cp where |
871 | * @a peer is at distance @a dist from us. | 1033 | * @a cp is at distance @a dist from us. |
872 | * | 1034 | * |
873 | * @param peer Peer to get path info. | 1035 | * @param cp Peer to get path info. |
874 | * @param dist desired distance of @a peer to us on the path | 1036 | * @param dist desired distance of @a cp to us on the path |
875 | * @param callback Function to call for every path. | 1037 | * @param callback Function to call for every path. |
876 | * @param callback_cls Closure for @a callback. | 1038 | * @param callback_cls Closure for @a callback. |
877 | * @return Number of iterated paths. | 1039 | * @return Number of iterated paths. |
878 | */ | 1040 | */ |
879 | unsigned int | 1041 | unsigned int |
880 | GCP_iterate_paths_at (struct CadetPeer *peer, | 1042 | GCP_iterate_paths_at (struct CadetPeer *cp, |
881 | unsigned int dist, | 1043 | unsigned int dist, |
882 | GCP_PathIterator callback, | 1044 | GCP_PathIterator callback, |
883 | void *callback_cls) | 1045 | void *callback_cls) |
884 | { | 1046 | { |
885 | unsigned int ret = 0; | 1047 | unsigned int ret = 0; |
886 | 1048 | ||
887 | if (dist<peer->path_dll_length) | 1049 | if (dist >= cp->path_dll_length) |
1050 | { | ||
1051 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1052 | "Asked to look for paths at distance %u, but maximum for me is < %u\n", | ||
1053 | dist, | ||
1054 | cp->path_dll_length); | ||
888 | return 0; | 1055 | return 0; |
889 | for (struct CadetPeerPathEntry *pe = peer->path_heads[dist]; | 1056 | } |
1057 | for (struct CadetPeerPathEntry *pe = cp->path_heads[dist]; | ||
890 | NULL != pe; | 1058 | NULL != pe; |
891 | pe = pe->next) | 1059 | pe = pe->next) |
892 | { | 1060 | { |
@@ -904,22 +1072,37 @@ GCP_iterate_paths_at (struct CadetPeer *peer, | |||
904 | /** | 1072 | /** |
905 | * Get the tunnel towards a peer. | 1073 | * Get the tunnel towards a peer. |
906 | * | 1074 | * |
907 | * @param peer Peer to get from. | 1075 | * @param cp Peer to get from. |
908 | * @param create #GNUNET_YES to create a tunnel if we do not have one | 1076 | * @param create #GNUNET_YES to create a tunnel if we do not have one |
909 | * @return Tunnel towards peer. | 1077 | * @return Tunnel towards peer. |
910 | */ | 1078 | */ |
911 | struct CadetTunnel * | 1079 | struct CadetTunnel * |
912 | GCP_get_tunnel (struct CadetPeer *peer, | 1080 | GCP_get_tunnel (struct CadetPeer *cp, |
913 | int create) | 1081 | int create) |
914 | { | 1082 | { |
915 | if (NULL == peer) | 1083 | if (NULL == cp) |
916 | return NULL; | 1084 | return NULL; |
917 | if ( (NULL != peer->t) || | 1085 | if ( (NULL != cp->t) || |
918 | (GNUNET_NO == create) ) | 1086 | (GNUNET_NO == create) ) |
919 | return peer->t; | 1087 | return cp->t; |
920 | peer->t = GCT_create_tunnel (peer); | 1088 | cp->t = GCT_create_tunnel (cp); |
921 | consider_peer_activate (peer); | 1089 | consider_peer_activate (cp); |
922 | return peer->t; | 1090 | return cp->t; |
1091 | } | ||
1092 | |||
1093 | |||
1094 | /** | ||
1095 | * Hello offer was passed to the transport service. Mark it | ||
1096 | * as done. | ||
1097 | * | ||
1098 | * @param cls the `struct CadetPeer` where the offer completed | ||
1099 | */ | ||
1100 | static void | ||
1101 | hello_offer_done (void *cls) | ||
1102 | { | ||
1103 | struct CadetPeer *cp = cls; | ||
1104 | |||
1105 | cp->hello_offer = NULL; | ||
923 | } | 1106 | } |
924 | 1107 | ||
925 | 1108 | ||
@@ -927,16 +1110,43 @@ GCP_get_tunnel (struct CadetPeer *peer, | |||
927 | * We got a HELLO for a @a peer, remember it, and possibly | 1110 | * We got a HELLO for a @a peer, remember it, and possibly |
928 | * trigger adequate actions (like trying to connect). | 1111 | * trigger adequate actions (like trying to connect). |
929 | * | 1112 | * |
930 | * @param peer the peer we got a HELLO for | 1113 | * @param cp the peer we got a HELLO for |
931 | * @param hello the HELLO to remember | 1114 | * @param hello the HELLO to remember |
932 | */ | 1115 | */ |
933 | void | 1116 | void |
934 | GCP_set_hello (struct CadetPeer *peer, | 1117 | GCP_set_hello (struct CadetPeer *cp, |
935 | const struct GNUNET_HELLO_Message *hello) | 1118 | const struct GNUNET_HELLO_Message *hello) |
936 | { | 1119 | { |
937 | /* FIXME: keep HELLO, possibly offer to TRANSPORT... */ | 1120 | struct GNUNET_HELLO_Message *mrg; |
938 | 1121 | ||
939 | consider_peer_destroy (peer); | 1122 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1123 | "Got %u byte HELLO for peer %s\n", | ||
1124 | (unsigned int) GNUNET_HELLO_size (hello), | ||
1125 | GCP_2s (cp)); | ||
1126 | if (NULL != cp->hello_offer) | ||
1127 | { | ||
1128 | GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer); | ||
1129 | cp->hello_offer = NULL; | ||
1130 | } | ||
1131 | if (NULL != cp->hello) | ||
1132 | { | ||
1133 | mrg = GNUNET_HELLO_merge (hello, | ||
1134 | cp->hello); | ||
1135 | GNUNET_free (cp->hello); | ||
1136 | cp->hello = mrg; | ||
1137 | } | ||
1138 | else | ||
1139 | { | ||
1140 | cp->hello = GNUNET_memdup (hello, | ||
1141 | GNUNET_HELLO_size (hello)); | ||
1142 | } | ||
1143 | cp->hello_offer | ||
1144 | = GNUNET_TRANSPORT_offer_hello (cfg, | ||
1145 | GNUNET_HELLO_get_header (cp->hello) , | ||
1146 | &hello_offer_done, | ||
1147 | cp); | ||
1148 | /* New HELLO means cp's destruction time may change... */ | ||
1149 | consider_peer_destroy (cp); | ||
940 | } | 1150 | } |
941 | 1151 | ||
942 | 1152 | ||
@@ -944,16 +1154,20 @@ GCP_set_hello (struct CadetPeer *peer, | |||
944 | * The tunnel to the given peer no longer exists, remove it from our | 1154 | * The tunnel to the given peer no longer exists, remove it from our |
945 | * data structures, and possibly clean up the peer itself. | 1155 | * data structures, and possibly clean up the peer itself. |
946 | * | 1156 | * |
947 | * @param peer the peer affected | 1157 | * @param cp the peer affected |
948 | * @param t the dead tunnel | 1158 | * @param t the dead tunnel |
949 | */ | 1159 | */ |
950 | void | 1160 | void |
951 | GCP_drop_tunnel (struct CadetPeer *peer, | 1161 | GCP_drop_tunnel (struct CadetPeer *cp, |
952 | struct CadetTunnel *t) | 1162 | struct CadetTunnel *t) |
953 | { | 1163 | { |
954 | GNUNET_assert (peer->t == t); | 1164 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
955 | peer->t = NULL; | 1165 | "Dropping tunnel %s to peer %s\n", |
956 | consider_peer_destroy (peer); | 1166 | GCT_2s (t), |
1167 | GCP_2s (cp)); | ||
1168 | GNUNET_assert (cp->t == t); | ||
1169 | cp->t = NULL; | ||
1170 | consider_peer_destroy (cp); | ||
957 | } | 1171 | } |
958 | 1172 | ||
959 | 1173 | ||
@@ -992,6 +1206,10 @@ GCP_request_mq (struct CadetPeer *cp, | |||
992 | GNUNET_CONTAINER_DLL_insert (cp->mqm_head, | 1206 | GNUNET_CONTAINER_DLL_insert (cp->mqm_head, |
993 | cp->mqm_tail, | 1207 | cp->mqm_tail, |
994 | mqm); | 1208 | mqm); |
1209 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1210 | "Creating MQM %p for peer %s\n", | ||
1211 | mqm, | ||
1212 | GCP_2s (cp)); | ||
995 | if (NULL != cp->core_mq) | 1213 | if (NULL != cp->core_mq) |
996 | cb (cb_cls, | 1214 | cb (cb_cls, |
997 | GNUNET_YES); | 1215 | GNUNET_YES); |
@@ -1011,6 +1229,11 @@ GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm, | |||
1011 | { | 1229 | { |
1012 | struct CadetPeer *cp = mqm->cp; | 1230 | struct CadetPeer *cp = mqm->cp; |
1013 | 1231 | ||
1232 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1233 | "Destroying MQM %p for peer %s%s\n", | ||
1234 | mqm, | ||
1235 | GCP_2s (cp), | ||
1236 | (NULL == last_env) ? "" : " with last ditch transmission"); | ||
1014 | if (NULL != mqm->env) | 1237 | if (NULL != mqm->env) |
1015 | GNUNET_MQ_discard (mqm->env); | 1238 | GNUNET_MQ_discard (mqm->env); |
1016 | if (NULL != last_env) | 1239 | if (NULL != last_env) |
@@ -1041,6 +1264,9 @@ void | |||
1041 | GCP_send_ooo (struct CadetPeer *cp, | 1264 | GCP_send_ooo (struct CadetPeer *cp, |
1042 | struct GNUNET_MQ_Envelope *env) | 1265 | struct GNUNET_MQ_Envelope *env) |
1043 | { | 1266 | { |
1267 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1268 | "Sending message to %s out of management\n", | ||
1269 | GCP_2s (cp)); | ||
1044 | if (NULL == cp->core_mq) | 1270 | if (NULL == cp->core_mq) |
1045 | { | 1271 | { |
1046 | GNUNET_MQ_discard (env); | 1272 | GNUNET_MQ_discard (env); |
diff --git a/src/cadet/gnunet-service-cadet-new_peer.h b/src/cadet/gnunet-service-cadet-new_peer.h index c633f47e5..aaaef15b8 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.h +++ b/src/cadet/gnunet-service-cadet-new_peer.h | |||
@@ -91,6 +91,16 @@ GCP_count_paths (const struct CadetPeer *cp); | |||
91 | 91 | ||
92 | 92 | ||
93 | /** | 93 | /** |
94 | * Drop all paths owned by this peer, and do not | ||
95 | * allow new ones to be added: We are shutting down. | ||
96 | * | ||
97 | * @param cp peer to drop paths to | ||
98 | */ | ||
99 | void | ||
100 | GCP_drop_owned_paths (struct CadetPeer *cp); | ||
101 | |||
102 | |||
103 | /** | ||
94 | * Peer path iterator. | 104 | * Peer path iterator. |
95 | * | 105 | * |
96 | * @param cls Closure. | 106 | * @param cls Closure. |
@@ -123,14 +133,14 @@ GCP_iterate_paths (struct CadetPeer *cp, | |||
123 | * Iterate over the paths to @a peer where | 133 | * Iterate over the paths to @a peer where |
124 | * @a peer is at distance @a dist from us. | 134 | * @a peer is at distance @a dist from us. |
125 | * | 135 | * |
126 | * @param peer Peer to get path info. | 136 | * @param cp Peer to get path info. |
127 | * @param dist desired distance of @a peer to us on the path | 137 | * @param dist desired distance of @a peer to us on the path |
128 | * @param callback Function to call for every path. | 138 | * @param callback Function to call for every path. |
129 | * @param callback_cls Closure for @a callback. | 139 | * @param callback_cls Closure for @a callback. |
130 | * @return Number of iterated paths. | 140 | * @return Number of iterated paths. |
131 | */ | 141 | */ |
132 | unsigned int | 142 | unsigned int |
133 | GCP_iterate_paths_at (struct CadetPeer *peer, | 143 | GCP_iterate_paths_at (struct CadetPeer *cp, |
134 | unsigned int dist, | 144 | unsigned int dist, |
135 | GCP_PathIterator callback, | 145 | GCP_PathIterator callback, |
136 | void *callback_cls); | 146 | void *callback_cls); |
@@ -193,13 +203,15 @@ GCP_drop_tunnel (struct CadetPeer *cp, | |||
193 | * @param cp peer to which the @a path leads to | 203 | * @param cp peer to which the @a path leads to |
194 | * @param path a path looking for an owner; may not be fully initialized yet! | 204 | * @param path a path looking for an owner; may not be fully initialized yet! |
195 | * @param off offset of @a cp in @a path | 205 | * @param off offset of @a cp in @a path |
206 | * @param force for attaching the path | ||
196 | * @return NULL if this peer does not care to become a new owner, | 207 | * @return NULL if this peer does not care to become a new owner, |
197 | * otherwise the node in the peer's path heap for the @a path. | 208 | * otherwise the node in the peer's path heap for the @a path. |
198 | */ | 209 | */ |
199 | struct GNUNET_CONTAINER_HeapNode * | 210 | struct GNUNET_CONTAINER_HeapNode * |
200 | GCP_attach_path (struct CadetPeer *cp, | 211 | GCP_attach_path (struct CadetPeer *cp, |
201 | struct CadetPeerPath *path, | 212 | struct CadetPeerPath *path, |
202 | unsigned int off); | 213 | unsigned int off, |
214 | int force); | ||
203 | 215 | ||
204 | 216 | ||
205 | /** | 217 | /** |
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index 23b270b82..fd8335486 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
4 | Copyright (C) 2013, 2017 GNUnet e.V. | 3 | Copyright (C) 2013, 2017 GNUnet e.V. |
@@ -18,7 +17,6 @@ | |||
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
20 | */ | 19 | */ |
21 | |||
22 | /** | 20 | /** |
23 | * @file cadet/gnunet-service-cadet-new_tunnels.c | 21 | * @file cadet/gnunet-service-cadet-new_tunnels.c |
24 | * @brief Information we track per tunnel. | 22 | * @brief Information we track per tunnel. |
@@ -26,20 +24,20 @@ | |||
26 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
27 | * | 25 | * |
28 | * FIXME: | 26 | * FIXME: |
27 | * - check KX estate machine -- make sure it is never stuck! | ||
28 | * - clean up KX logic, including adding sender authentication | ||
29 | * - implement connection management (evaluate, kill old ones, | ||
30 | * search for new ones) | ||
29 | * - when managing connections, distinguish those that | 31 | * - when managing connections, distinguish those that |
30 | * have (recently) had traffic from those that were | 32 | * have (recently) had traffic from those that were |
31 | * never ready (or not recently) | 33 | * never ready (or not recently) |
32 | * - implement sending and receiving KX messages | ||
33 | * - implement processing of incoming decrypted plaintext messages | ||
34 | * - clean up KX logic! | ||
35 | */ | 34 | */ |
36 | #include "platform.h" | 35 | #include "platform.h" |
37 | #include "gnunet_util_lib.h" | 36 | #include "gnunet_util_lib.h" |
38 | #include "gnunet_statistics_service.h" | 37 | #include "gnunet_statistics_service.h" |
39 | #include "gnunet_signatures.h" | 38 | #include "gnunet_signatures.h" |
40 | #include "cadet_protocol.h" | ||
41 | #include "cadet_path.h" | ||
42 | #include "gnunet-service-cadet-new.h" | 39 | #include "gnunet-service-cadet-new.h" |
40 | #include "cadet_protocol.h" | ||
43 | #include "gnunet-service-cadet-new_channel.h" | 41 | #include "gnunet-service-cadet-new_channel.h" |
44 | #include "gnunet-service-cadet-new_connection.h" | 42 | #include "gnunet-service-cadet-new_connection.h" |
45 | #include "gnunet-service-cadet-new_tunnels.h" | 43 | #include "gnunet-service-cadet-new_tunnels.h" |
@@ -301,19 +299,24 @@ struct CadetTunnel | |||
301 | struct CadetTunnelAxolotl ax; | 299 | struct CadetTunnelAxolotl ax; |
302 | 300 | ||
303 | /** | 301 | /** |
304 | * State of the tunnel connectivity. | 302 | * Task scheduled if there are no more channels using the tunnel. |
305 | */ | 303 | */ |
306 | enum CadetTunnelCState cstate; | 304 | struct GNUNET_SCHEDULER_Task *destroy_task; |
307 | 305 | ||
308 | /** | 306 | /** |
309 | * State of the tunnel encryption. | 307 | * Task to trim connections if too many are present. |
310 | */ | 308 | */ |
311 | enum CadetTunnelEState estate; | 309 | struct GNUNET_SCHEDULER_Task *maintain_connections_task; |
310 | |||
311 | /** | ||
312 | * Task to send messages from queue (if possible). | ||
313 | */ | ||
314 | struct GNUNET_SCHEDULER_Task *send_task; | ||
312 | 315 | ||
313 | /** | 316 | /** |
314 | * Task to start the rekey process. | 317 | * Task to trigger KX. |
315 | */ | 318 | */ |
316 | struct GNUNET_SCHEDULER_Task *rekey_task; | 319 | struct GNUNET_SCHEDULER_Task *kx_task; |
317 | 320 | ||
318 | /** | 321 | /** |
319 | * Tokenizer for decrypted messages. | 322 | * Tokenizer for decrypted messages. |
@@ -344,7 +347,7 @@ struct CadetTunnel | |||
344 | /** | 347 | /** |
345 | * Channel ID for the next created channel in this tunnel. | 348 | * Channel ID for the next created channel in this tunnel. |
346 | */ | 349 | */ |
347 | struct GNUNET_CADET_ChannelTunnelNumber next_chid; | 350 | struct GNUNET_CADET_ChannelTunnelNumber next_ctn; |
348 | 351 | ||
349 | /** | 352 | /** |
350 | * Queued messages, to transmit once tunnel gets connected. | 353 | * Queued messages, to transmit once tunnel gets connected. |
@@ -356,25 +359,26 @@ struct CadetTunnel | |||
356 | */ | 359 | */ |
357 | struct CadetTunnelQueueEntry *tq_tail; | 360 | struct CadetTunnelQueueEntry *tq_tail; |
358 | 361 | ||
362 | |||
359 | /** | 363 | /** |
360 | * Task scheduled if there are no more channels using the tunnel. | 364 | * Ephemeral message in the queue (to avoid queueing more than one). |
361 | */ | 365 | */ |
362 | struct GNUNET_SCHEDULER_Task *destroy_task; | 366 | struct CadetConnectionQueue *ephm_hKILL; |
363 | 367 | ||
364 | /** | 368 | /** |
365 | * Task to trim connections if too many are present. | 369 | * Pong message in the queue. |
366 | */ | 370 | */ |
367 | struct GNUNET_SCHEDULER_Task *maintain_connections_task; | 371 | struct CadetConnectionQueue *pong_hKILL; |
368 | 372 | ||
369 | /** | 373 | /** |
370 | * Ephemeral message in the queue (to avoid queueing more than one). | 374 | * How long do we wait until we retry the KX? |
371 | */ | 375 | */ |
372 | struct CadetConnectionQueue *ephm_hKILL; | 376 | struct GNUNET_TIME_Relative kx_retry_delay; |
373 | 377 | ||
374 | /** | 378 | /** |
375 | * Pong message in the queue. | 379 | * When do we try the next KX? |
376 | */ | 380 | */ |
377 | struct CadetConnectionQueue *pong_hKILL; | 381 | struct GNUNET_TIME_Absolute next_kx_attempt; |
378 | 382 | ||
379 | /** | 383 | /** |
380 | * Number of connections in the @e connection_head DLL. | 384 | * Number of connections in the @e connection_head DLL. |
@@ -385,6 +389,12 @@ struct CadetTunnel | |||
385 | * Number of entries in the @e tq_head DLL. | 389 | * Number of entries in the @e tq_head DLL. |
386 | */ | 390 | */ |
387 | unsigned int tq_len; | 391 | unsigned int tq_len; |
392 | |||
393 | /** | ||
394 | * State of the tunnel encryption. | ||
395 | */ | ||
396 | enum CadetTunnelEState estate; | ||
397 | |||
388 | }; | 398 | }; |
389 | 399 | ||
390 | 400 | ||
@@ -401,17 +411,47 @@ GCT_2s (const struct CadetTunnel *t) | |||
401 | static char buf[64]; | 411 | static char buf[64]; |
402 | 412 | ||
403 | if (NULL == t) | 413 | if (NULL == t) |
404 | return "T(NULL)"; | 414 | return "Tunnel(NULL)"; |
405 | |||
406 | GNUNET_snprintf (buf, | 415 | GNUNET_snprintf (buf, |
407 | sizeof (buf), | 416 | sizeof (buf), |
408 | "T(%s)", | 417 | "Tunnel %s", |
409 | GCP_2s (t->destination)); | 418 | GNUNET_i2s (GCP_get_id (t->destination))); |
410 | return buf; | 419 | return buf; |
411 | } | 420 | } |
412 | 421 | ||
413 | 422 | ||
414 | /** | 423 | /** |
424 | * Get string description for tunnel encryption state. | ||
425 | * | ||
426 | * @param es Tunnel state. | ||
427 | * | ||
428 | * @return String representation. | ||
429 | */ | ||
430 | static const char * | ||
431 | estate2s (enum CadetTunnelEState es) | ||
432 | { | ||
433 | static char buf[32]; | ||
434 | |||
435 | switch (es) | ||
436 | { | ||
437 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
438 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | ||
439 | case CADET_TUNNEL_KEY_SENT: | ||
440 | return "CADET_TUNNEL_KEY_SENT"; | ||
441 | case CADET_TUNNEL_KEY_PING: | ||
442 | return "CADET_TUNNEL_KEY_PING"; | ||
443 | case CADET_TUNNEL_KEY_OK: | ||
444 | return "CADET_TUNNEL_KEY_OK"; | ||
445 | case CADET_TUNNEL_KEY_REKEY: | ||
446 | return "CADET_TUNNEL_KEY_REKEY"; | ||
447 | default: | ||
448 | SPRINTF (buf, "%u (UNKNOWN STATE)", es); | ||
449 | return buf; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | |||
454 | /** | ||
415 | * Return the peer to which this tunnel goes. | 455 | * Return the peer to which this tunnel goes. |
416 | * | 456 | * |
417 | * @param t a tunnel | 457 | * @param t a tunnel |
@@ -439,18 +479,18 @@ GCT_count_channels (struct CadetTunnel *t) | |||
439 | 479 | ||
440 | 480 | ||
441 | /** | 481 | /** |
442 | * Lookup a channel by its @a chid. | 482 | * Lookup a channel by its @a ctn. |
443 | * | 483 | * |
444 | * @param t tunnel to look in | 484 | * @param t tunnel to look in |
445 | * @param chid number of channel to find | 485 | * @param ctn number of channel to find |
446 | * @return NULL if channel does not exist | 486 | * @return NULL if channel does not exist |
447 | */ | 487 | */ |
448 | struct CadetChannel * | 488 | struct CadetChannel * |
449 | lookup_channel (struct CadetTunnel *t, | 489 | lookup_channel (struct CadetTunnel *t, |
450 | struct GNUNET_CADET_ChannelTunnelNumber chid) | 490 | struct GNUNET_CADET_ChannelTunnelNumber ctn) |
451 | { | 491 | { |
452 | return GNUNET_CONTAINER_multihashmap32_get (t->channels, | 492 | return GNUNET_CONTAINER_multihashmap32_get (t->channels, |
453 | ntohl (chid.cn)); | 493 | ntohl (ctn.cn)); |
454 | } | 494 | } |
455 | 495 | ||
456 | 496 | ||
@@ -469,16 +509,34 @@ GCT_count_any_connections (struct CadetTunnel *t) | |||
469 | 509 | ||
470 | 510 | ||
471 | /** | 511 | /** |
472 | * Get the connectivity state of a tunnel. | 512 | * Find first connection that is ready in the list of |
513 | * our connections. Picks ready connections round-robin. | ||
473 | * | 514 | * |
474 | * @param t Tunnel. | 515 | * @param t tunnel to search |
475 | * | 516 | * @return NULL if we have no connection that is ready |
476 | * @return Tunnel's connectivity state. | ||
477 | */ | 517 | */ |
478 | enum CadetTunnelCState | 518 | static struct CadetTConnection * |
479 | GCT_get_cstate (struct CadetTunnel *t) | 519 | get_ready_connection (struct CadetTunnel *t) |
480 | { | 520 | { |
481 | return t->cstate; | 521 | for (struct CadetTConnection *pos = t->connection_head; |
522 | NULL != pos; | ||
523 | pos = pos->next) | ||
524 | if (GNUNET_YES == pos->is_ready) | ||
525 | { | ||
526 | if (pos != t->connection_tail) | ||
527 | { | ||
528 | /* move 'pos' to the end, so we try other ready connections | ||
529 | first next time (round-robin, modulo availability) */ | ||
530 | GNUNET_CONTAINER_DLL_remove (t->connection_head, | ||
531 | t->connection_tail, | ||
532 | pos); | ||
533 | GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, | ||
534 | t->connection_tail, | ||
535 | pos); | ||
536 | } | ||
537 | return pos; | ||
538 | } | ||
539 | return NULL; | ||
482 | } | 540 | } |
483 | 541 | ||
484 | 542 | ||
@@ -509,6 +567,19 @@ new_ephemeral (struct CadetTunnel *t) | |||
509 | } | 567 | } |
510 | 568 | ||
511 | 569 | ||
570 | |||
571 | /** | ||
572 | * Called when either we have a new connection, or a new message in the | ||
573 | * queue, or some existing connection has transmission capacity. Looks | ||
574 | * at our message queue and if there is a message, picks a connection | ||
575 | * to send it on. | ||
576 | * | ||
577 | * @param cls the `struct CadetTunnel` to process messages on | ||
578 | */ | ||
579 | static void | ||
580 | trigger_transmissions (void *cls); | ||
581 | |||
582 | |||
512 | /* ************************************** start core crypto ***************************** */ | 583 | /* ************************************** start core crypto ***************************** */ |
513 | 584 | ||
514 | 585 | ||
@@ -1107,6 +1178,68 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, | |||
1107 | 1178 | ||
1108 | 1179 | ||
1109 | /** | 1180 | /** |
1181 | * Our tunnel became ready for the first time, notify channels | ||
1182 | * that have been waiting. | ||
1183 | * | ||
1184 | * @param cls our tunnel, not used | ||
1185 | * @param key unique ID of the channel, not used | ||
1186 | * @param value the `struct CadetChannel` to notify | ||
1187 | * @return #GNUNET_OK (continue to iterate) | ||
1188 | */ | ||
1189 | static int | ||
1190 | notify_tunnel_up_cb (void *cls, | ||
1191 | uint32_t key, | ||
1192 | void *value) | ||
1193 | { | ||
1194 | struct CadetChannel *ch = value; | ||
1195 | |||
1196 | GCCH_tunnel_up (ch); | ||
1197 | return GNUNET_OK; | ||
1198 | } | ||
1199 | |||
1200 | |||
1201 | /** | ||
1202 | * Change the tunnel encryption state. | ||
1203 | * If the encryption state changes to OK, stop the rekey task. | ||
1204 | * | ||
1205 | * @param t Tunnel whose encryption state to change, or NULL. | ||
1206 | * @param state New encryption state. | ||
1207 | */ | ||
1208 | void | ||
1209 | GCT_change_estate (struct CadetTunnel *t, | ||
1210 | enum CadetTunnelEState state) | ||
1211 | { | ||
1212 | enum CadetTunnelEState old = t->estate; | ||
1213 | |||
1214 | t->estate = state; | ||
1215 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1216 | "Tunnel %s estate changed from %d to %d\n", | ||
1217 | GCT_2s (t), | ||
1218 | old, | ||
1219 | state); | ||
1220 | |||
1221 | if ( (CADET_TUNNEL_KEY_OK != old) && | ||
1222 | (CADET_TUNNEL_KEY_OK == t->estate) ) | ||
1223 | { | ||
1224 | if (NULL != t->kx_task) | ||
1225 | { | ||
1226 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1227 | t->kx_task = NULL; | ||
1228 | } | ||
1229 | if (CADET_TUNNEL_KEY_REKEY != old) | ||
1230 | { | ||
1231 | /* notify all channels that have been waiting */ | ||
1232 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
1233 | ¬ify_tunnel_up_cb, | ||
1234 | t); | ||
1235 | } | ||
1236 | |||
1237 | /* FIXME: schedule rekey task! */ | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | /** | ||
1110 | * Send a KX message. | 1243 | * Send a KX message. |
1111 | * | 1244 | * |
1112 | * FIXME: does not take care of sender-authentication yet! | 1245 | * FIXME: does not take care of sender-authentication yet! |
@@ -1119,20 +1252,25 @@ send_kx (struct CadetTunnel *t, | |||
1119 | int force_reply) | 1252 | int force_reply) |
1120 | { | 1253 | { |
1121 | struct CadetTunnelAxolotl *ax = &t->ax; | 1254 | struct CadetTunnelAxolotl *ax = &t->ax; |
1122 | struct CadetConnection *c; | 1255 | struct CadetTConnection *ct; |
1256 | struct CadetConnection *cc; | ||
1123 | struct GNUNET_MQ_Envelope *env; | 1257 | struct GNUNET_MQ_Envelope *env; |
1124 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | 1258 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; |
1125 | enum GNUNET_CADET_KX_Flags flags; | 1259 | enum GNUNET_CADET_KX_Flags flags; |
1126 | 1260 | ||
1127 | #if FIXME | 1261 | ct = get_ready_connection (t); |
1128 | if (NULL != t->ephm_h) | 1262 | if (NULL == ct) |
1129 | { | 1263 | { |
1130 | LOG (GNUNET_ERROR_TYPE_INFO, | 1264 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1131 | " already queued, nop\n"); | 1265 | "Wanted to send KX on tunnel %s, but no connection is ready, deferring\n", |
1266 | GCT_2s (t)); | ||
1132 | return; | 1267 | return; |
1133 | } | 1268 | } |
1134 | #endif | 1269 | cc = ct->cc; |
1135 | c = NULL; // FIXME: figure out where to transmit... | 1270 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1271 | "Sending KX on tunnel %s using connection %s\n", | ||
1272 | GCT_2s (t), | ||
1273 | GCC_2s (ct->cc)); | ||
1136 | 1274 | ||
1137 | // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | 1275 | // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); |
1138 | env = GNUNET_MQ_msg (msg, | 1276 | env = GNUNET_MQ_msg (msg, |
@@ -1141,23 +1279,19 @@ send_kx (struct CadetTunnel *t, | |||
1141 | if (GNUNET_YES == force_reply) | 1279 | if (GNUNET_YES == force_reply) |
1142 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | 1280 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; |
1143 | msg->flags = htonl (flags); | 1281 | msg->flags = htonl (flags); |
1144 | msg->cid = *GCC_get_id (c); | 1282 | msg->cid = *GCC_get_id (cc); |
1145 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, | 1283 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, |
1146 | &msg->ephemeral_key); | 1284 | &msg->ephemeral_key); |
1147 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, | 1285 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, |
1148 | &msg->ratchet_key); | 1286 | &msg->ratchet_key); |
1149 | 1287 | ct->is_ready = GNUNET_NO; | |
1150 | // FIXME: send 'env'. | 1288 | GCC_transmit (cc, |
1151 | #if FIXME | 1289 | env); |
1152 | t->ephm_h = GCC_send_prebuilt_message (&msg.header, | 1290 | t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); |
1153 | UINT16_MAX, | 1291 | t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); |
1154 | zero, | ||
1155 | c, | ||
1156 | GCC_is_origin (c, GNUNET_YES), | ||
1157 | GNUNET_YES, &ephm_sent, t); | ||
1158 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | 1292 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) |
1159 | GCT_change_estate (t, CADET_TUNNEL_KEY_SENT); | 1293 | GCT_change_estate (t, |
1160 | #endif | 1294 | CADET_TUNNEL_KEY_SENT); |
1161 | } | 1295 | } |
1162 | 1296 | ||
1163 | 1297 | ||
@@ -1196,10 +1330,10 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1196 | 1330 | ||
1197 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) | 1331 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) |
1198 | { | 1332 | { |
1199 | if (NULL != t->rekey_task) | 1333 | if (NULL != t->kx_task) |
1200 | { | 1334 | { |
1201 | GNUNET_SCHEDULER_cancel (t->rekey_task); | 1335 | GNUNET_SCHEDULER_cancel (t->kx_task); |
1202 | t->rekey_task = NULL; | 1336 | t->kx_task = NULL; |
1203 | } | 1337 | } |
1204 | send_kx (t, | 1338 | send_kx (t, |
1205 | GNUNET_NO); | 1339 | GNUNET_NO); |
@@ -1209,7 +1343,7 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1209 | &msg->ratchet_key, | 1343 | &msg->ratchet_key, |
1210 | sizeof (msg->ratchet_key))) | 1344 | sizeof (msg->ratchet_key))) |
1211 | { | 1345 | { |
1212 | LOG (GNUNET_ERROR_TYPE_INFO, | 1346 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1213 | " known ratchet key, exit\n"); | 1347 | " known ratchet key, exit\n"); |
1214 | return; | 1348 | return; |
1215 | } | 1349 | } |
@@ -1267,6 +1401,10 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1267 | " known handshake key, exit\n"); | 1401 | " known handshake key, exit\n"); |
1268 | return; | 1402 | return; |
1269 | } | 1403 | } |
1404 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1405 | "Handling KX message for tunnel %s\n", | ||
1406 | GCT_2s (t)); | ||
1407 | |||
1270 | ax->RK = keys[0]; | 1408 | ax->RK = keys[0]; |
1271 | if (GNUNET_YES == am_I_alice) | 1409 | if (GNUNET_YES == am_I_alice) |
1272 | { | 1410 | { |
@@ -1293,12 +1431,32 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1293 | ax->Nr = 0; | 1431 | ax->Nr = 0; |
1294 | ax->Ns = 0; | 1432 | ax->Ns = 0; |
1295 | 1433 | ||
1296 | #if FIXME | 1434 | switch (t->estate) |
1297 | /* After KX is done, update state machine and begin transmissions... */ | 1435 | { |
1298 | GCT_change_estate (t, | 1436 | case CADET_TUNNEL_KEY_UNINITIALIZED: |
1299 | CADET_TUNNEL_KEY_PING); | 1437 | GCT_change_estate (t, |
1300 | send_queued_data (t); | 1438 | CADET_TUNNEL_KEY_PING); |
1301 | #endif | 1439 | break; |
1440 | case CADET_TUNNEL_KEY_SENT: | ||
1441 | /* Got a response to us sending our key; now | ||
1442 | we can start transmitting! */ | ||
1443 | GCT_change_estate (t, | ||
1444 | CADET_TUNNEL_KEY_OK); | ||
1445 | if (NULL != t->send_task) | ||
1446 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
1447 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
1448 | t); | ||
1449 | break; | ||
1450 | case CADET_TUNNEL_KEY_PING: | ||
1451 | /* Got a key yet again; need encrypted payload to advance */ | ||
1452 | break; | ||
1453 | case CADET_TUNNEL_KEY_OK: | ||
1454 | /* Did not expect a key, but so what. */ | ||
1455 | break; | ||
1456 | case CADET_TUNNEL_KEY_REKEY: | ||
1457 | /* Got a key yet again; need encrypted payload to advance */ | ||
1458 | break; | ||
1459 | } | ||
1302 | } | 1460 | } |
1303 | 1461 | ||
1304 | 1462 | ||
@@ -1306,7 +1464,45 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1306 | 1464 | ||
1307 | 1465 | ||
1308 | /** | 1466 | /** |
1309 | * Add a channel to a tunnel. | 1467 | * Compute the next free channel tunnel number for this tunnel. |
1468 | * | ||
1469 | * @param t the tunnel | ||
1470 | * @return unused number that can uniquely identify a channel in the tunnel | ||
1471 | */ | ||
1472 | static struct GNUNET_CADET_ChannelTunnelNumber | ||
1473 | get_next_free_ctn (struct CadetTunnel *t) | ||
1474 | { | ||
1475 | #define HIGH_BIT 0x8000000 | ||
1476 | struct GNUNET_CADET_ChannelTunnelNumber ret; | ||
1477 | uint32_t ctn; | ||
1478 | int cmp; | ||
1479 | uint32_t highbit; | ||
1480 | |||
1481 | cmp = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, | ||
1482 | GCP_get_id (GCT_get_destination (t))); | ||
1483 | if (0 < cmp) | ||
1484 | highbit = HIGH_BIT; | ||
1485 | else if (0 > cmp) | ||
1486 | highbit = 0; | ||
1487 | else | ||
1488 | GNUNET_assert (0); // loopback must never go here! | ||
1489 | ctn = ntohl (t->next_ctn.cn); | ||
1490 | while (NULL != | ||
1491 | GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
1492 | ctn)) | ||
1493 | { | ||
1494 | ctn = ((ctn + 1) & (~ HIGH_BIT)) | highbit; | ||
1495 | } | ||
1496 | t->next_ctn.cn = htonl (((ctn + 1) & (~ HIGH_BIT)) | highbit); | ||
1497 | ret.cn = ntohl (ctn); | ||
1498 | return ret; | ||
1499 | } | ||
1500 | |||
1501 | |||
1502 | /** | ||
1503 | * Add a channel to a tunnel, and notify channel that we are ready | ||
1504 | * for transmission if we are already up. Otherwise that notification | ||
1505 | * will be done later in #notify_tunnel_up_cb(). | ||
1310 | * | 1506 | * |
1311 | * @param t Tunnel. | 1507 | * @param t Tunnel. |
1312 | * @param ch Channel | 1508 | * @param ch Channel |
@@ -1316,22 +1512,22 @@ struct GNUNET_CADET_ChannelTunnelNumber | |||
1316 | GCT_add_channel (struct CadetTunnel *t, | 1512 | GCT_add_channel (struct CadetTunnel *t, |
1317 | struct CadetChannel *ch) | 1513 | struct CadetChannel *ch) |
1318 | { | 1514 | { |
1319 | struct GNUNET_CADET_ChannelTunnelNumber ret; | 1515 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
1320 | uint32_t chid; | ||
1321 | 1516 | ||
1322 | chid = ntohl (t->next_chid.cn); | 1517 | ctn = get_next_free_ctn (t); |
1323 | while (NULL != | ||
1324 | GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
1325 | chid)) | ||
1326 | chid++; | ||
1327 | GNUNET_assert (GNUNET_YES == | 1518 | GNUNET_assert (GNUNET_YES == |
1328 | GNUNET_CONTAINER_multihashmap32_put (t->channels, | 1519 | GNUNET_CONTAINER_multihashmap32_put (t->channels, |
1329 | chid, | 1520 | ntohl (ctn.cn), |
1330 | ch, | 1521 | ch, |
1331 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 1522 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
1332 | t->next_chid.cn = htonl (chid + 1); | 1523 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1333 | ret.cn = htonl (chid); | 1524 | "Adding channel %s to tunnel %s\n", |
1334 | return ret; | 1525 | GCCH_2s (ch), |
1526 | GCT_2s (t)); | ||
1527 | if ( (CADET_TUNNEL_KEY_OK == t->estate) || | ||
1528 | (CADET_TUNNEL_KEY_REKEY == t->estate) ) | ||
1529 | GCCH_tunnel_up (ch); | ||
1530 | return ctn; | ||
1335 | } | 1531 | } |
1336 | 1532 | ||
1337 | 1533 | ||
@@ -1345,9 +1541,12 @@ destroy_tunnel (void *cls) | |||
1345 | { | 1541 | { |
1346 | struct CadetTunnel *t = cls; | 1542 | struct CadetTunnel *t = cls; |
1347 | struct CadetTConnection *ct; | 1543 | struct CadetTConnection *ct; |
1348 | struct CadetTunnelQueueEntry *tqe; | 1544 | struct CadetTunnelQueueEntry *tq; |
1349 | 1545 | ||
1350 | t->destroy_task = NULL; | 1546 | t->destroy_task = NULL; |
1547 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1548 | "Destroying idle tunnel %s\n", | ||
1549 | GCT_2s (t)); | ||
1351 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)); | 1550 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)); |
1352 | while (NULL != (ct = t->connection_head)) | 1551 | while (NULL != (ct = t->connection_head)) |
1353 | { | 1552 | { |
@@ -1358,13 +1557,11 @@ destroy_tunnel (void *cls) | |||
1358 | GCC_destroy (ct->cc); | 1557 | GCC_destroy (ct->cc); |
1359 | GNUNET_free (ct); | 1558 | GNUNET_free (ct); |
1360 | } | 1559 | } |
1361 | while (NULL != (tqe = t->tq_head)) | 1560 | while (NULL != (tq = t->tq_head)) |
1362 | { | 1561 | { |
1363 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | 1562 | if (NULL != tq->cont) |
1364 | t->tq_tail, | 1563 | tq->cont (tq->cont_cls); |
1365 | tqe); | 1564 | GCT_send_cancel (tq); |
1366 | GNUNET_MQ_discard (tqe->env); | ||
1367 | GNUNET_free (tqe); | ||
1368 | } | 1565 | } |
1369 | GCP_drop_tunnel (t->destination, | 1566 | GCP_drop_tunnel (t->destination, |
1370 | t); | 1567 | t); |
@@ -1374,37 +1571,144 @@ destroy_tunnel (void *cls) | |||
1374 | GNUNET_SCHEDULER_cancel (t->maintain_connections_task); | 1571 | GNUNET_SCHEDULER_cancel (t->maintain_connections_task); |
1375 | t->maintain_connections_task = NULL; | 1572 | t->maintain_connections_task = NULL; |
1376 | } | 1573 | } |
1574 | if (NULL != t->send_task) | ||
1575 | { | ||
1576 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
1577 | t->send_task = NULL; | ||
1578 | } | ||
1579 | if (NULL != t->kx_task) | ||
1580 | { | ||
1581 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1582 | t->kx_task = NULL; | ||
1583 | } | ||
1377 | GNUNET_MST_destroy (t->mst); | 1584 | GNUNET_MST_destroy (t->mst); |
1378 | GNUNET_MQ_destroy (t->mq); | 1585 | GNUNET_MQ_destroy (t->mq); |
1586 | while (NULL != t->ax.skipped_head) | ||
1587 | delete_skipped_key (t, | ||
1588 | t->ax.skipped_head); | ||
1589 | GNUNET_assert (0 == t->ax.skipped); | ||
1590 | GNUNET_free_non_null (t->ax.kx_0); | ||
1591 | GNUNET_free_non_null (t->ax.DHRs); | ||
1379 | GNUNET_free (t); | 1592 | GNUNET_free (t); |
1380 | } | 1593 | } |
1381 | 1594 | ||
1382 | 1595 | ||
1383 | /** | 1596 | /** |
1384 | * A connection is @a is_ready for transmission. Looks at our message | 1597 | * Remove a channel from a tunnel. |
1385 | * queue and if there is a message, sends it out via the connection. | ||
1386 | * | 1598 | * |
1387 | * @param cls the `struct CadetTConnection` that is @a is_ready | 1599 | * @param t Tunnel. |
1388 | * @param is_ready #GNUNET_YES if connection are now ready, | 1600 | * @param ch Channel |
1389 | * #GNUNET_NO if connection are no longer ready | 1601 | * @param ctn unique number identifying @a ch within @a t |
1602 | */ | ||
1603 | void | ||
1604 | GCT_remove_channel (struct CadetTunnel *t, | ||
1605 | struct CadetChannel *ch, | ||
1606 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | ||
1607 | { | ||
1608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1609 | "Removing channel %s from tunnel %s\n", | ||
1610 | GCCH_2s (ch), | ||
1611 | GCT_2s (t)); | ||
1612 | GNUNET_assert (GNUNET_YES == | ||
1613 | GNUNET_CONTAINER_multihashmap32_remove (t->channels, | ||
1614 | ntohl (ctn.cn), | ||
1615 | ch)); | ||
1616 | if (0 == | ||
1617 | GNUNET_CONTAINER_multihashmap32_size (t->channels)) | ||
1618 | { | ||
1619 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | ||
1620 | &destroy_tunnel, | ||
1621 | t); | ||
1622 | } | ||
1623 | } | ||
1624 | |||
1625 | |||
1626 | /** | ||
1627 | * Destroy remaining channels during shutdown. | ||
1628 | * | ||
1629 | * @param cls the `struct CadetTunnel` of the channel | ||
1630 | * @param key key of the channel | ||
1631 | * @param value the `struct CadetChannel` | ||
1632 | * @return #GNUNET_OK (continue to iterate) | ||
1633 | */ | ||
1634 | static int | ||
1635 | destroy_remaining_channels (void *cls, | ||
1636 | uint32_t key, | ||
1637 | void *value) | ||
1638 | { | ||
1639 | struct CadetChannel *ch = value; | ||
1640 | |||
1641 | GCCH_handle_remote_destroy (ch); | ||
1642 | return GNUNET_OK; | ||
1643 | } | ||
1644 | |||
1645 | |||
1646 | /** | ||
1647 | * Destroys the tunnel @a t now, without delay. Used during shutdown. | ||
1648 | * | ||
1649 | * @param t tunnel to destroy | ||
1650 | */ | ||
1651 | void | ||
1652 | GCT_destroy_tunnel_now (struct CadetTunnel *t) | ||
1653 | { | ||
1654 | GNUNET_assert (GNUNET_YES == shutting_down); | ||
1655 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | ||
1656 | &destroy_remaining_channels, | ||
1657 | t); | ||
1658 | GNUNET_assert (0 == | ||
1659 | GNUNET_CONTAINER_multihashmap32_size (t->channels)); | ||
1660 | if (NULL != t->destroy_task) | ||
1661 | { | ||
1662 | GNUNET_SCHEDULER_cancel (t->destroy_task); | ||
1663 | t->destroy_task = NULL; | ||
1664 | } | ||
1665 | destroy_tunnel (t); | ||
1666 | } | ||
1667 | |||
1668 | |||
1669 | /** | ||
1670 | * It's been a while, we should try to redo the KX, if we can. | ||
1671 | * | ||
1672 | * @param cls the `struct CadetTunnel` to do KX for. | ||
1390 | */ | 1673 | */ |
1391 | static void | 1674 | static void |
1392 | connection_ready_cb (void *cls, | 1675 | retry_kx (void *cls) |
1393 | int is_ready) | ||
1394 | { | 1676 | { |
1395 | struct CadetTConnection *ct = cls; | 1677 | struct CadetTunnel *t = cls; |
1396 | struct CadetTunnel *t = ct->t; | 1678 | |
1397 | struct CadetTunnelQueueEntry *tq = t->tq_head; | 1679 | t->kx_task = NULL; |
1680 | send_kx (t, | ||
1681 | ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || | ||
1682 | (CADET_TUNNEL_KEY_SENT == t->estate) ) | ||
1683 | ? GNUNET_YES | ||
1684 | : GNUNET_NO); | ||
1685 | } | ||
1686 | |||
1687 | |||
1688 | /** | ||
1689 | * Send normal payload from queue in @a t via connection @a ct. | ||
1690 | * Does nothing if our payload queue is empty. | ||
1691 | * | ||
1692 | * @param t tunnel to send data from | ||
1693 | * @param ct connection to use for transmission (is ready) | ||
1694 | */ | ||
1695 | static void | ||
1696 | try_send_normal_payload (struct CadetTunnel *t, | ||
1697 | struct CadetTConnection *ct) | ||
1698 | { | ||
1699 | struct CadetTunnelQueueEntry *tq; | ||
1398 | 1700 | ||
1399 | if (GNUNET_NO == ct->is_ready) | 1701 | GNUNET_assert (GNUNET_YES == ct->is_ready); |
1702 | tq = t->tq_head; | ||
1703 | if (NULL == tq) | ||
1400 | { | 1704 | { |
1401 | ct->is_ready = GNUNET_NO; | 1705 | /* no messages pending right now */ |
1706 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1707 | "Not sending payload of %s on ready %s (nothing pending)\n", | ||
1708 | GCT_2s (t), | ||
1709 | GCC_2s (ct->cc)); | ||
1402 | return; | 1710 | return; |
1403 | } | 1711 | } |
1404 | ct->is_ready = GNUNET_YES; | ||
1405 | if (NULL == tq) | ||
1406 | return; /* no messages pending right now */ | ||
1407 | |||
1408 | /* ready to send message 'tq' on tunnel 'ct' */ | 1712 | /* ready to send message 'tq' on tunnel 'ct' */ |
1409 | GNUNET_assert (t == tq->t); | 1713 | GNUNET_assert (t == tq->t); |
1410 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | 1714 | GNUNET_CONTAINER_DLL_remove (t->tq_head, |
@@ -1413,63 +1717,100 @@ connection_ready_cb (void *cls, | |||
1413 | if (NULL != tq->cid) | 1717 | if (NULL != tq->cid) |
1414 | *tq->cid = *GCC_get_id (ct->cc); | 1718 | *tq->cid = *GCC_get_id (ct->cc); |
1415 | ct->is_ready = GNUNET_NO; | 1719 | ct->is_ready = GNUNET_NO; |
1720 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1721 | "Sending payload of %s on %s\n", | ||
1722 | GCT_2s (t), | ||
1723 | GCC_2s (ct->cc)); | ||
1416 | GCC_transmit (ct->cc, | 1724 | GCC_transmit (ct->cc, |
1417 | tq->env); | 1725 | tq->env); |
1418 | tq->cont (tq->cont_cls); | 1726 | if (NULL != tq->cont) |
1727 | tq->cont (tq->cont_cls); | ||
1419 | GNUNET_free (tq); | 1728 | GNUNET_free (tq); |
1420 | } | 1729 | } |
1421 | 1730 | ||
1422 | 1731 | ||
1423 | /** | 1732 | /** |
1424 | * Called when either we have a new connection, or a new message in the | 1733 | * A connection is @a is_ready for transmission. Looks at our message |
1425 | * queue, or some existing connection has transmission capacity. Looks | 1734 | * queue and if there is a message, sends it out via the connection. |
1426 | * at our message queue and if there is a message, picks a connection | ||
1427 | * to send it on. | ||
1428 | * | ||
1429 | * FIXME: yuck... Need better selection logic! | ||
1430 | * | 1735 | * |
1431 | * @param t tunnel to process messages on | 1736 | * @param cls the `struct CadetTConnection` that is @a is_ready |
1737 | * @param is_ready #GNUNET_YES if connection are now ready, | ||
1738 | * #GNUNET_NO if connection are no longer ready | ||
1432 | */ | 1739 | */ |
1433 | static void | 1740 | static void |
1434 | trigger_transmissions (struct CadetTunnel *t) | 1741 | connection_ready_cb (void *cls, |
1742 | int is_ready) | ||
1435 | { | 1743 | { |
1436 | struct CadetTConnection *ct; | 1744 | struct CadetTConnection *ct = cls; |
1437 | 1745 | struct CadetTunnel *t = ct->t; | |
1438 | if (NULL == t->tq_head) | ||
1439 | return; /* no messages pending right now */ | ||
1440 | for (ct = t->connection_head; | ||
1441 | NULL != ct; | ||
1442 | ct = ct->next) | ||
1443 | if (GNUNET_YES == ct->is_ready) | ||
1444 | break; | ||
1445 | if (NULL == ct) | ||
1446 | return; /* no connections ready */ | ||
1447 | 1746 | ||
1448 | /* FIXME: a bit hackish to do it like this... */ | 1747 | if (GNUNET_NO == is_ready) |
1449 | connection_ready_cb (ct, | 1748 | { |
1450 | GNUNET_YES); | 1749 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1750 | "Connection %s no longer ready for tunnel %s\n", | ||
1751 | GCC_2s (ct->cc), | ||
1752 | GCT_2s (t)); | ||
1753 | ct->is_ready = GNUNET_NO; | ||
1754 | return; | ||
1755 | } | ||
1756 | ct->is_ready = GNUNET_YES; | ||
1757 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1758 | "Connection %s now ready for tunnel %s in state %s\n", | ||
1759 | GCC_2s (ct->cc), | ||
1760 | GCT_2s (t), | ||
1761 | estate2s (t->estate)); | ||
1762 | switch (t->estate) | ||
1763 | { | ||
1764 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
1765 | send_kx (t, | ||
1766 | GNUNET_YES); | ||
1767 | break; | ||
1768 | case CADET_TUNNEL_KEY_SENT: | ||
1769 | case CADET_TUNNEL_KEY_PING: | ||
1770 | /* opportunity to #retry_kx() starts now, schedule job */ | ||
1771 | if (NULL == t->kx_task) | ||
1772 | { | ||
1773 | t->kx_task | ||
1774 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | ||
1775 | &retry_kx, | ||
1776 | t); | ||
1777 | } | ||
1778 | break; | ||
1779 | case CADET_TUNNEL_KEY_OK: | ||
1780 | try_send_normal_payload (t, | ||
1781 | ct); | ||
1782 | break; | ||
1783 | case CADET_TUNNEL_KEY_REKEY: | ||
1784 | send_kx (t, | ||
1785 | GNUNET_NO); | ||
1786 | t->estate = CADET_TUNNEL_KEY_OK; | ||
1787 | break; | ||
1788 | } | ||
1451 | } | 1789 | } |
1452 | 1790 | ||
1453 | 1791 | ||
1454 | /** | 1792 | /** |
1455 | * Function called to maintain the connections underlying our tunnel. | 1793 | * Called when either we have a new connection, or a new message in the |
1456 | * Tries to maintain (incl. tear down) connections for the tunnel, and | 1794 | * queue, or some existing connection has transmission capacity. Looks |
1457 | * if there is a significant change, may trigger transmissions. | 1795 | * at our message queue and if there is a message, picks a connection |
1458 | * | 1796 | * to send it on. |
1459 | * Basically, needs to check if there are connections that perform | ||
1460 | * badly, and if so eventually kill them and trigger a replacement. | ||
1461 | * The strategy is to open one more connection than | ||
1462 | * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the | ||
1463 | * least-performing one, and then inquire for new ones. | ||
1464 | * | 1797 | * |
1465 | * @param cls the `struct CadetTunnel` | 1798 | * @param cls the `struct CadetTunnel` to process messages on |
1466 | */ | 1799 | */ |
1467 | static void | 1800 | static void |
1468 | maintain_connections_cb (void *cls) | 1801 | trigger_transmissions (void *cls) |
1469 | { | 1802 | { |
1470 | struct CadetTunnel *t = cls; | 1803 | struct CadetTunnel *t = cls; |
1804 | struct CadetTConnection *ct; | ||
1471 | 1805 | ||
1472 | GNUNET_break (0); // FIXME: implement! | 1806 | t->send_task = NULL; |
1807 | if (NULL == t->tq_head) | ||
1808 | return; /* no messages pending right now */ | ||
1809 | ct = get_ready_connection (t); | ||
1810 | if (NULL == ct) | ||
1811 | return; /* no connections ready */ | ||
1812 | try_send_normal_payload (t, | ||
1813 | ct); | ||
1473 | } | 1814 | } |
1474 | 1815 | ||
1475 | 1816 | ||
@@ -1501,7 +1842,13 @@ consider_path_cb (void *cls, | |||
1501 | 1842 | ||
1502 | ps = GCC_get_path (ct->cc); | 1843 | ps = GCC_get_path (ct->cc); |
1503 | if (ps == path) | 1844 | if (ps == path) |
1845 | { | ||
1846 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1847 | "Ignoring duplicate path %s for tunnel %s.\n", | ||
1848 | GCPP_2s (path), | ||
1849 | GCT_2s (t)); | ||
1504 | return GNUNET_YES; /* duplicate */ | 1850 | return GNUNET_YES; /* duplicate */ |
1851 | } | ||
1505 | min_length = GNUNET_MIN (min_length, | 1852 | min_length = GNUNET_MIN (min_length, |
1506 | GCPP_get_length (ps)); | 1853 | GCPP_get_length (ps)); |
1507 | max_desire = GNUNET_MAX (max_desire, | 1854 | max_desire = GNUNET_MAX (max_desire, |
@@ -1518,9 +1865,9 @@ consider_path_cb (void *cls, | |||
1518 | if ( (t->num_connections > DESIRED_CONNECTIONS_PER_TUNNEL) && | 1865 | if ( (t->num_connections > DESIRED_CONNECTIONS_PER_TUNNEL) && |
1519 | (min_length * 2 < off) ) | 1866 | (min_length * 2 < off) ) |
1520 | { | 1867 | { |
1521 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1868 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1522 | "Ignoring paths of length %u, they are way too long.\n", | 1869 | "Ignoring paths of length %u, they are way too long.\n", |
1523 | min_length * 2); | 1870 | min_length * 2); |
1524 | return GNUNET_NO; | 1871 | return GNUNET_NO; |
1525 | } | 1872 | } |
1526 | /* If we have enough paths and this one looks no better, ignore it. */ | 1873 | /* If we have enough paths and this one looks no better, ignore it. */ |
@@ -1528,11 +1875,11 @@ consider_path_cb (void *cls, | |||
1528 | (min_length < GCPP_get_length (path)) && | 1875 | (min_length < GCPP_get_length (path)) && |
1529 | (max_desire > GCPP_get_desirability (path)) ) | 1876 | (max_desire > GCPP_get_desirability (path)) ) |
1530 | { | 1877 | { |
1531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1878 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1532 | "Ignoring path (%u/%llu) to %s, got something better already.\n", | 1879 | "Ignoring path (%u/%llu) to %s, got something better already.\n", |
1533 | GCPP_get_length (path), | 1880 | GCPP_get_length (path), |
1534 | (unsigned long long) GCPP_get_desirability (path), | 1881 | (unsigned long long) GCPP_get_desirability (path), |
1535 | GCP_2s (t->destination)); | 1882 | GCP_2s (t->destination)); |
1536 | return GNUNET_YES; | 1883 | return GNUNET_YES; |
1537 | } | 1884 | } |
1538 | 1885 | ||
@@ -1554,11 +1901,47 @@ consider_path_cb (void *cls, | |||
1554 | t->connection_tail, | 1901 | t->connection_tail, |
1555 | ct); | 1902 | ct); |
1556 | t->num_connections++; | 1903 | t->num_connections++; |
1904 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1905 | "Found interesting path %s for tunnel %s, created connection %s\n", | ||
1906 | GCPP_2s (path), | ||
1907 | GCT_2s (t), | ||
1908 | GCC_2s (ct->cc)); | ||
1557 | return GNUNET_YES; | 1909 | return GNUNET_YES; |
1558 | } | 1910 | } |
1559 | 1911 | ||
1560 | 1912 | ||
1561 | /** | 1913 | /** |
1914 | * Function called to maintain the connections underlying our tunnel. | ||
1915 | * Tries to maintain (incl. tear down) connections for the tunnel, and | ||
1916 | * if there is a significant change, may trigger transmissions. | ||
1917 | * | ||
1918 | * Basically, needs to check if there are connections that perform | ||
1919 | * badly, and if so eventually kill them and trigger a replacement. | ||
1920 | * The strategy is to open one more connection than | ||
1921 | * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the | ||
1922 | * least-performing one, and then inquire for new ones. | ||
1923 | * | ||
1924 | * @param cls the `struct CadetTunnel` | ||
1925 | */ | ||
1926 | static void | ||
1927 | maintain_connections_cb (void *cls) | ||
1928 | { | ||
1929 | struct CadetTunnel *t = cls; | ||
1930 | |||
1931 | t->maintain_connections_task = NULL; | ||
1932 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1933 | "Performing connection maintenance for tunnel %s.\n", | ||
1934 | GCT_2s (t)); | ||
1935 | |||
1936 | (void) GCP_iterate_paths (t->destination, | ||
1937 | &consider_path_cb, | ||
1938 | t); | ||
1939 | |||
1940 | GNUNET_break (0); // FIXME: implement! | ||
1941 | } | ||
1942 | |||
1943 | |||
1944 | /** | ||
1562 | * Consider using the path @a p for the tunnel @a t. | 1945 | * Consider using the path @a p for the tunnel @a t. |
1563 | * The tunnel destination is at offset @a off in path @a p. | 1946 | * The tunnel destination is at offset @a off in path @a p. |
1564 | * | 1947 | * |
@@ -1578,7 +1961,7 @@ GCT_consider_path (struct CadetTunnel *t, | |||
1578 | 1961 | ||
1579 | 1962 | ||
1580 | /** | 1963 | /** |
1581 | * | 1964 | * NOT IMPLEMENTED. |
1582 | * | 1965 | * |
1583 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 1966 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1584 | * @param msg the message we received on the tunnel | 1967 | * @param msg the message we received on the tunnel |
@@ -1588,6 +1971,7 @@ handle_plaintext_keepalive (void *cls, | |||
1588 | const struct GNUNET_MessageHeader *msg) | 1971 | const struct GNUNET_MessageHeader *msg) |
1589 | { | 1972 | { |
1590 | struct CadetTunnel *t = cls; | 1973 | struct CadetTunnel *t = cls; |
1974 | |||
1591 | GNUNET_break (0); // FIXME | 1975 | GNUNET_break (0); // FIXME |
1592 | } | 1976 | } |
1593 | 1977 | ||
@@ -1608,7 +1992,8 @@ check_plaintext_data (void *cls, | |||
1608 | 1992 | ||
1609 | 1993 | ||
1610 | /** | 1994 | /** |
1611 | * | 1995 | * We received payload data for a channel. Locate the channel |
1996 | * and process the data, or return an error if the channel is unknown. | ||
1612 | * | 1997 | * |
1613 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 1998 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1614 | * @param msg the message we received on the tunnel | 1999 | * @param msg the message we received on the tunnel |
@@ -1618,12 +2003,31 @@ handle_plaintext_data (void *cls, | |||
1618 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) | 2003 | const struct GNUNET_CADET_ChannelAppDataMessage *msg) |
1619 | { | 2004 | { |
1620 | struct CadetTunnel *t = cls; | 2005 | struct CadetTunnel *t = cls; |
1621 | GNUNET_break (0); // FIXME! | 2006 | struct CadetChannel *ch; |
2007 | |||
2008 | ch = lookup_channel (t, | ||
2009 | msg->ctn); | ||
2010 | if (NULL == ch) | ||
2011 | { | ||
2012 | /* We don't know about such a channel, might have been destroyed on our | ||
2013 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
2014 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2015 | "Receicved %u bytes of application data for unknown channel %u, sending DESTROY\n", | ||
2016 | (unsigned int) (ntohs (msg->header.size) - sizeof (*msg)), | ||
2017 | ntohl (msg->ctn.cn)); | ||
2018 | GCT_send_channel_destroy (t, | ||
2019 | msg->ctn); | ||
2020 | return; | ||
2021 | } | ||
2022 | GCCH_handle_channel_plaintext_data (ch, | ||
2023 | msg); | ||
1622 | } | 2024 | } |
1623 | 2025 | ||
1624 | 2026 | ||
1625 | /** | 2027 | /** |
1626 | * | 2028 | * We received an acknowledgement for data we sent on a channel. |
2029 | * Locate the channel and process it, or return an error if the | ||
2030 | * channel is unknown. | ||
1627 | * | 2031 | * |
1628 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 2032 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1629 | * @param ack the message we received on the tunnel | 2033 | * @param ack the message we received on the tunnel |
@@ -1633,52 +2037,127 @@ handle_plaintext_data_ack (void *cls, | |||
1633 | const struct GNUNET_CADET_ChannelDataAckMessage *ack) | 2037 | const struct GNUNET_CADET_ChannelDataAckMessage *ack) |
1634 | { | 2038 | { |
1635 | struct CadetTunnel *t = cls; | 2039 | struct CadetTunnel *t = cls; |
1636 | GNUNET_break (0); // FIXME! | 2040 | struct CadetChannel *ch; |
2041 | |||
2042 | ch = lookup_channel (t, | ||
2043 | ack->ctn); | ||
2044 | if (NULL == ch) | ||
2045 | { | ||
2046 | /* We don't know about such a channel, might have been destroyed on our | ||
2047 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
2048 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2049 | "Receicved DATA_ACK for unknown channel %u, sending DESTROY\n", | ||
2050 | ntohl (ack->ctn.cn)); | ||
2051 | GCT_send_channel_destroy (t, | ||
2052 | ack->ctn); | ||
2053 | return; | ||
2054 | } | ||
2055 | GCCH_handle_channel_plaintext_data_ack (ch, | ||
2056 | ack); | ||
1637 | } | 2057 | } |
1638 | 2058 | ||
1639 | 2059 | ||
1640 | /** | 2060 | /** |
1641 | * | 2061 | * We have received a request to open a channel to a port from |
2062 | * another peer. Creates the incoming channel. | ||
1642 | * | 2063 | * |
1643 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 2064 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1644 | * @param cc the message we received on the tunnel | 2065 | * @param copen the message we received on the tunnel |
1645 | */ | 2066 | */ |
1646 | static void | 2067 | static void |
1647 | handle_plaintext_channel_create (void *cls, | 2068 | handle_plaintext_channel_open (void *cls, |
1648 | const struct GNUNET_CADET_ChannelOpenMessage *cc) | 2069 | const struct GNUNET_CADET_ChannelOpenMessage *copen) |
1649 | { | 2070 | { |
1650 | struct CadetTunnel *t = cls; | 2071 | struct CadetTunnel *t = cls; |
1651 | GNUNET_break (0); // FIXME! | 2072 | struct CadetChannel *ch; |
2073 | |||
2074 | ch = GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
2075 | ntohl (copen->ctn.cn)); | ||
2076 | if (NULL != ch) | ||
2077 | { | ||
2078 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2079 | "Receicved duplicate channel OPEN on port %s from %s (%s), resending ACK\n", | ||
2080 | GNUNET_h2s (&copen->port), | ||
2081 | GCT_2s (t), | ||
2082 | GCCH_2s (ch)); | ||
2083 | GCCH_handle_duplicate_open (ch); | ||
2084 | return; | ||
2085 | } | ||
2086 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2087 | "Receicved channel OPEN on port %s from %s\n", | ||
2088 | GNUNET_h2s (&copen->port), | ||
2089 | GCT_2s (t)); | ||
2090 | ch = GCCH_channel_incoming_new (t, | ||
2091 | copen->ctn, | ||
2092 | &copen->port, | ||
2093 | ntohl (copen->opt)); | ||
2094 | GNUNET_assert (GNUNET_OK == | ||
2095 | GNUNET_CONTAINER_multihashmap32_put (t->channels, | ||
2096 | ntohl (copen->ctn.cn), | ||
2097 | ch, | ||
2098 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1652 | } | 2099 | } |
1653 | 2100 | ||
1654 | 2101 | ||
1655 | /** | 2102 | /** |
2103 | * Send a DESTROY message via the tunnel. | ||
1656 | * | 2104 | * |
1657 | * | 2105 | * @param t the tunnel to transmit over |
1658 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 2106 | * @param ctn ID of the channel to destroy |
1659 | * @param cm the message we received on the tunnel | ||
1660 | */ | 2107 | */ |
1661 | static void | 2108 | void |
1662 | handle_plaintext_channel_nack (void *cls, | 2109 | GCT_send_channel_destroy (struct CadetTunnel *t, |
1663 | const struct GNUNET_CADET_ChannelManageMessage *cm) | 2110 | struct GNUNET_CADET_ChannelTunnelNumber ctn) |
1664 | { | 2111 | { |
1665 | struct CadetTunnel *t = cls; | 2112 | struct GNUNET_CADET_ChannelManageMessage msg; |
1666 | GNUNET_break (0); // FIXME! | 2113 | |
2114 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2115 | "Sending DESTORY message for channel ID %u\n", | ||
2116 | ntohl (ctn.cn)); | ||
2117 | msg.header.size = htons (sizeof (msg)); | ||
2118 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
2119 | msg.reserved = htonl (0); | ||
2120 | msg.ctn = ctn; | ||
2121 | GCT_send (t, | ||
2122 | &msg.header, | ||
2123 | NULL, | ||
2124 | NULL); | ||
1667 | } | 2125 | } |
1668 | 2126 | ||
1669 | 2127 | ||
1670 | /** | 2128 | /** |
1671 | * | 2129 | * We have received confirmation from the target peer that the |
2130 | * given channel could be established (the port is open). | ||
2131 | * Tell the client. | ||
1672 | * | 2132 | * |
1673 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 2133 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1674 | * @param cm the message we received on the tunnel | 2134 | * @param cm the message we received on the tunnel |
1675 | */ | 2135 | */ |
1676 | static void | 2136 | static void |
1677 | handle_plaintext_channel_ack (void *cls, | 2137 | handle_plaintext_channel_open_ack (void *cls, |
1678 | const struct GNUNET_CADET_ChannelManageMessage *cm) | 2138 | const struct GNUNET_CADET_ChannelManageMessage *cm) |
1679 | { | 2139 | { |
1680 | struct CadetTunnel *t = cls; | 2140 | struct CadetTunnel *t = cls; |
1681 | GNUNET_break (0); // FIXME! | 2141 | struct CadetChannel *ch; |
2142 | |||
2143 | ch = lookup_channel (t, | ||
2144 | cm->ctn); | ||
2145 | if (NULL == ch) | ||
2146 | { | ||
2147 | /* We don't know about such a channel, might have been destroyed on our | ||
2148 | end in the meantime, or never existed. Send back a DESTROY. */ | ||
2149 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2150 | "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n", | ||
2151 | ntohl (cm->ctn.cn)); | ||
2152 | GCT_send_channel_destroy (t, | ||
2153 | cm->ctn); | ||
2154 | return; | ||
2155 | } | ||
2156 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2157 | "Received channel OPEN_ACK on channel %s from %s\n", | ||
2158 | GCCH_2s (ch), | ||
2159 | GCT_2s (t)); | ||
2160 | GCCH_handle_channel_open_ack (ch); | ||
1682 | } | 2161 | } |
1683 | 2162 | ||
1684 | 2163 | ||
@@ -1694,10 +2173,24 @@ handle_plaintext_channel_destroy (void *cls, | |||
1694 | const struct GNUNET_CADET_ChannelManageMessage *cm) | 2173 | const struct GNUNET_CADET_ChannelManageMessage *cm) |
1695 | { | 2174 | { |
1696 | struct CadetTunnel *t = cls; | 2175 | struct CadetTunnel *t = cls; |
1697 | struct CadetChannel *cc = lookup_channel (t, | 2176 | struct CadetChannel *ch; |
1698 | cm->chid); | ||
1699 | 2177 | ||
1700 | GCCH_channel_remote_destroy (cc); | 2178 | ch = lookup_channel (t, |
2179 | cm->ctn); | ||
2180 | if (NULL == ch) | ||
2181 | { | ||
2182 | /* We don't know about such a channel, might have been destroyed on our | ||
2183 | end in the meantime, or never existed. */ | ||
2184 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2185 | "Received channel DESTORY for unknown channel %u. Ignoring.\n", | ||
2186 | ntohl (cm->ctn.cn)); | ||
2187 | return; | ||
2188 | } | ||
2189 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2190 | "Receicved channel DESTROY on %s from %s\n", | ||
2191 | GCCH_2s (ch), | ||
2192 | GCT_2s (t)); | ||
2193 | GCCH_handle_remote_destroy (ch); | ||
1701 | } | 2194 | } |
1702 | 2195 | ||
1703 | 2196 | ||
@@ -1746,45 +2239,39 @@ decrypted_error_cb (void *cls, | |||
1746 | struct CadetTunnel * | 2239 | struct CadetTunnel * |
1747 | GCT_create_tunnel (struct CadetPeer *destination) | 2240 | GCT_create_tunnel (struct CadetPeer *destination) |
1748 | { | 2241 | { |
2242 | struct CadetTunnel *t = GNUNET_new (struct CadetTunnel); | ||
1749 | struct GNUNET_MQ_MessageHandler handlers[] = { | 2243 | struct GNUNET_MQ_MessageHandler handlers[] = { |
1750 | GNUNET_MQ_hd_fixed_size (plaintext_keepalive, | 2244 | GNUNET_MQ_hd_fixed_size (plaintext_keepalive, |
1751 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, | 2245 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, |
1752 | struct GNUNET_MessageHeader, | 2246 | struct GNUNET_MessageHeader, |
1753 | NULL), | 2247 | t), |
1754 | GNUNET_MQ_hd_var_size (plaintext_data, | 2248 | GNUNET_MQ_hd_var_size (plaintext_data, |
1755 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, | 2249 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, |
1756 | struct GNUNET_CADET_ChannelAppDataMessage, | 2250 | struct GNUNET_CADET_ChannelAppDataMessage, |
1757 | NULL), | 2251 | t), |
1758 | GNUNET_MQ_hd_fixed_size (plaintext_data_ack, | 2252 | GNUNET_MQ_hd_fixed_size (plaintext_data_ack, |
1759 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, | 2253 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, |
1760 | struct GNUNET_CADET_ChannelDataAckMessage, | 2254 | struct GNUNET_CADET_ChannelDataAckMessage, |
1761 | NULL), | 2255 | t), |
1762 | GNUNET_MQ_hd_fixed_size (plaintext_channel_create, | 2256 | GNUNET_MQ_hd_fixed_size (plaintext_channel_open, |
1763 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | 2257 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, |
1764 | struct GNUNET_CADET_ChannelOpenMessage, | 2258 | struct GNUNET_CADET_ChannelOpenMessage, |
1765 | NULL), | 2259 | t), |
1766 | GNUNET_MQ_hd_fixed_size (plaintext_channel_nack, | 2260 | GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack, |
1767 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED, | ||
1768 | struct GNUNET_CADET_ChannelManageMessage, | ||
1769 | NULL), | ||
1770 | GNUNET_MQ_hd_fixed_size (plaintext_channel_ack, | ||
1771 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, | 2261 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, |
1772 | struct GNUNET_CADET_ChannelManageMessage, | 2262 | struct GNUNET_CADET_ChannelManageMessage, |
1773 | NULL), | 2263 | t), |
1774 | GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy, | 2264 | GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy, |
1775 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | 2265 | GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, |
1776 | struct GNUNET_CADET_ChannelManageMessage, | 2266 | struct GNUNET_CADET_ChannelManageMessage, |
1777 | NULL), | 2267 | t), |
1778 | GNUNET_MQ_handler_end () | 2268 | GNUNET_MQ_handler_end () |
1779 | }; | 2269 | }; |
1780 | struct CadetTunnel *t; | ||
1781 | 2270 | ||
1782 | t = GNUNET_new (struct CadetTunnel); | 2271 | new_ephemeral (t); |
2272 | t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); | ||
1783 | t->destination = destination; | 2273 | t->destination = destination; |
1784 | t->channels = GNUNET_CONTAINER_multihashmap32_create (8); | 2274 | t->channels = GNUNET_CONTAINER_multihashmap32_create (8); |
1785 | (void) GCP_iterate_paths (destination, | ||
1786 | &consider_path_cb, | ||
1787 | t); | ||
1788 | t->maintain_connections_task | 2275 | t->maintain_connections_task |
1789 | = GNUNET_SCHEDULER_add_now (&maintain_connections_cb, | 2276 | = GNUNET_SCHEDULER_add_now (&maintain_connections_cb, |
1790 | t); | 2277 | t); |
@@ -1802,69 +2289,6 @@ GCT_create_tunnel (struct CadetPeer *destination) | |||
1802 | 2289 | ||
1803 | 2290 | ||
1804 | /** | 2291 | /** |
1805 | * Remove a channel from a tunnel. | ||
1806 | * | ||
1807 | * @param t Tunnel. | ||
1808 | * @param ch Channel | ||
1809 | * @param gid unique number identifying @a ch within @a t | ||
1810 | */ | ||
1811 | void | ||
1812 | GCT_remove_channel (struct CadetTunnel *t, | ||
1813 | struct CadetChannel *ch, | ||
1814 | struct GNUNET_CADET_ChannelTunnelNumber gid) | ||
1815 | { | ||
1816 | GNUNET_assert (GNUNET_YES == | ||
1817 | GNUNET_CONTAINER_multihashmap32_remove (t->channels, | ||
1818 | ntohl (gid.cn), | ||
1819 | ch)); | ||
1820 | if (0 == | ||
1821 | GNUNET_CONTAINER_multihashmap32_size (t->channels)) | ||
1822 | { | ||
1823 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | ||
1824 | &destroy_tunnel, | ||
1825 | t); | ||
1826 | } | ||
1827 | } | ||
1828 | |||
1829 | |||
1830 | /** | ||
1831 | * Change the tunnel encryption state. | ||
1832 | * If the encryption state changes to OK, stop the rekey task. | ||
1833 | * | ||
1834 | * @param t Tunnel whose encryption state to change, or NULL. | ||
1835 | * @param state New encryption state. | ||
1836 | */ | ||
1837 | void | ||
1838 | GCT_change_estate (struct CadetTunnel *t, | ||
1839 | enum CadetTunnelEState state) | ||
1840 | { | ||
1841 | enum CadetTunnelEState old = t->estate; | ||
1842 | |||
1843 | t->estate = state; | ||
1844 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1845 | "Tunnel %s estate changed from %d to %d\n", | ||
1846 | GCT_2s (t), | ||
1847 | old, | ||
1848 | state); | ||
1849 | |||
1850 | if ( (CADET_TUNNEL_KEY_OK != old) && | ||
1851 | (CADET_TUNNEL_KEY_OK == t->estate) ) | ||
1852 | { | ||
1853 | if (NULL != t->rekey_task) | ||
1854 | { | ||
1855 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1856 | t->rekey_task = NULL; | ||
1857 | } | ||
1858 | #if FIXME | ||
1859 | /* Send queued data if tunnel is not loopback */ | ||
1860 | if (myid != GCP_get_short_id (t->peer)) | ||
1861 | send_queued_data (t); | ||
1862 | #endif | ||
1863 | } | ||
1864 | } | ||
1865 | |||
1866 | |||
1867 | /** | ||
1868 | * Add a @a connection to the @a tunnel. | 2292 | * Add a @a connection to the @a tunnel. |
1869 | * | 2293 | * |
1870 | * @param t a tunnel | 2294 | * @param t a tunnel |
@@ -1876,7 +2300,6 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
1876 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, | 2300 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, |
1877 | struct CadetPeerPath *path) | 2301 | struct CadetPeerPath *path) |
1878 | { | 2302 | { |
1879 | struct CadetConnection *cc; | ||
1880 | struct CadetTConnection *ct; | 2303 | struct CadetTConnection *ct; |
1881 | 2304 | ||
1882 | ct = GNUNET_new (struct CadetTConnection); | 2305 | ct = GNUNET_new (struct CadetTConnection); |
@@ -1887,7 +2310,7 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
1887 | ct, | 2310 | ct, |
1888 | cid, | 2311 | cid, |
1889 | &connection_ready_cb, | 2312 | &connection_ready_cb, |
1890 | t); | 2313 | ct); |
1891 | /* FIXME: schedule job to kill connection (and path?) if it takes | 2314 | /* FIXME: schedule job to kill connection (and path?) if it takes |
1892 | too long to get ready! (And track performance data on how long | 2315 | too long to get ready! (And track performance data on how long |
1893 | other connections took with the tunnel!) | 2316 | other connections took with the tunnel!) |
@@ -1896,6 +2319,10 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
1896 | t->connection_tail, | 2319 | t->connection_tail, |
1897 | ct); | 2320 | ct); |
1898 | t->num_connections++; | 2321 | t->num_connections++; |
2322 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2323 | "Tunnel %s has new connection %s\n", | ||
2324 | GCT_2s (t), | ||
2325 | GCC_2s (ct->cc)); | ||
1899 | } | 2326 | } |
1900 | 2327 | ||
1901 | 2328 | ||
@@ -1914,11 +2341,42 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
1914 | char cbuf [size] GNUNET_ALIGN; | 2341 | char cbuf [size] GNUNET_ALIGN; |
1915 | ssize_t decrypted_size; | 2342 | ssize_t decrypted_size; |
1916 | 2343 | ||
2344 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2345 | "Tunnel %s received %u bytes of encrypted data in state %d\n", | ||
2346 | GCT_2s (t), | ||
2347 | (unsigned int) size, | ||
2348 | t->estate); | ||
2349 | |||
2350 | switch (t->estate) | ||
2351 | { | ||
2352 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2353 | /* We did not even SEND our KX, how can the other peer | ||
2354 | send us encrypted data? */ | ||
2355 | GNUNET_break_op (0); | ||
2356 | return; | ||
2357 | case CADET_TUNNEL_KEY_SENT: | ||
2358 | /* We did not get the KX of the other peer, but that | ||
2359 | might have been lost. Ask for KX again. */ | ||
2360 | GNUNET_STATISTICS_update (stats, | ||
2361 | "# received encrypted without KX", | ||
2362 | 1, | ||
2363 | GNUNET_NO); | ||
2364 | if (NULL != t->kx_task) | ||
2365 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2366 | t->kx_task = GNUNET_SCHEDULER_add_now (&retry_kx, | ||
2367 | t); | ||
2368 | return; | ||
2369 | case CADET_TUNNEL_KEY_PING: | ||
2370 | /* Great, first payload, we might graduate to OK */ | ||
2371 | case CADET_TUNNEL_KEY_OK: | ||
2372 | case CADET_TUNNEL_KEY_REKEY: | ||
2373 | break; | ||
2374 | } | ||
2375 | |||
1917 | GNUNET_STATISTICS_update (stats, | 2376 | GNUNET_STATISTICS_update (stats, |
1918 | "# received encrypted", | 2377 | "# received encrypted", |
1919 | 1, | 2378 | 1, |
1920 | GNUNET_NO); | 2379 | GNUNET_NO); |
1921 | |||
1922 | decrypted_size = t_ax_decrypt_and_validate (t, | 2380 | decrypted_size = t_ax_decrypt_and_validate (t, |
1923 | cbuf, | 2381 | cbuf, |
1924 | msg, | 2382 | msg, |
@@ -1926,24 +2384,25 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
1926 | 2384 | ||
1927 | if (-1 == decrypted_size) | 2385 | if (-1 == decrypted_size) |
1928 | { | 2386 | { |
2387 | GNUNET_break_op (0); | ||
2388 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2389 | "Tunnel %s failed to decrypt and validate encrypted data\n", | ||
2390 | GCT_2s (t)); | ||
1929 | GNUNET_STATISTICS_update (stats, | 2391 | GNUNET_STATISTICS_update (stats, |
1930 | "# unable to decrypt", | 2392 | "# unable to decrypt", |
1931 | 1, | 2393 | 1, |
1932 | GNUNET_NO); | 2394 | GNUNET_NO); |
1933 | if (CADET_TUNNEL_KEY_PING <= t->estate) | ||
1934 | { | ||
1935 | GNUNET_break_op (0); | ||
1936 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1937 | "Wrong crypto, tunnel %s\n", | ||
1938 | GCT_2s (t)); | ||
1939 | GCT_debug (t, | ||
1940 | GNUNET_ERROR_TYPE_WARNING); | ||
1941 | } | ||
1942 | return; | 2395 | return; |
1943 | } | 2396 | } |
1944 | 2397 | if (CADET_TUNNEL_KEY_PING == t->estate) | |
1945 | GCT_change_estate (t, | 2398 | { |
1946 | CADET_TUNNEL_KEY_OK); | 2399 | GCT_change_estate (t, |
2400 | CADET_TUNNEL_KEY_OK); | ||
2401 | if (NULL != t->send_task) | ||
2402 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
2403 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
2404 | t); | ||
2405 | } | ||
1947 | /* The MST will ultimately call #handle_decrypted() on each message. */ | 2406 | /* The MST will ultimately call #handle_decrypted() on each message. */ |
1948 | GNUNET_break_op (GNUNET_OK == | 2407 | GNUNET_break_op (GNUNET_OK == |
1949 | GNUNET_MST_from_buffer (t->mst, | 2408 | GNUNET_MST_from_buffer (t->mst, |
@@ -1975,9 +2434,11 @@ GCT_send (struct CadetTunnel *t, | |||
1975 | struct GNUNET_MQ_Envelope *env; | 2434 | struct GNUNET_MQ_Envelope *env; |
1976 | struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; | 2435 | struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; |
1977 | 2436 | ||
1978 | /* FIXME: what about KX not yet being ready? (see "is_ready()" check in old code!) */ | ||
1979 | |||
1980 | payload_size = ntohs (message->size); | 2437 | payload_size = ntohs (message->size); |
2438 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2439 | "Encrypting %u bytes for tunnel %s\n", | ||
2440 | (unsigned int) payload_size, | ||
2441 | GCT_2s (t)); | ||
1981 | env = GNUNET_MQ_msg_extra (ax_msg, | 2442 | env = GNUNET_MQ_msg_extra (ax_msg, |
1982 | payload_size, | 2443 | payload_size, |
1983 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); | 2444 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); |
@@ -1996,18 +2457,21 @@ GCT_send (struct CadetTunnel *t, | |||
1996 | 0, | 2457 | 0, |
1997 | &t->ax.HKs, | 2458 | &t->ax.HKs, |
1998 | &ax_msg->hmac); | 2459 | &ax_msg->hmac); |
1999 | // ax_msg->pid = htonl (GCC_get_pid (c, fwd)); // FIXME: connection flow-control not (re)implemented yet! | ||
2000 | 2460 | ||
2001 | tq = GNUNET_malloc (sizeof (*tq)); | 2461 | tq = GNUNET_malloc (sizeof (*tq)); |
2002 | tq->t = t; | 2462 | tq->t = t; |
2003 | tq->env = env; | 2463 | tq->env = env; |
2004 | tq->cid = &ax_msg->cid; | 2464 | tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */ |
2005 | tq->cont = cont; | 2465 | tq->cont = cont; |
2006 | tq->cont_cls = cont_cls; | 2466 | tq->cont_cls = cont_cls; |
2007 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, | 2467 | GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, |
2008 | t->tq_tail, | 2468 | t->tq_tail, |
2009 | tq); | 2469 | tq); |
2010 | trigger_transmissions (t); | 2470 | if (NULL != t->send_task) |
2471 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
2472 | t->send_task | ||
2473 | = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
2474 | t); | ||
2011 | return tq; | 2475 | return tq; |
2012 | } | 2476 | } |
2013 | 2477 | ||
@@ -2019,17 +2483,18 @@ GCT_send (struct CadetTunnel *t, | |||
2019 | * function is called. Once the continuation is called, the message is | 2483 | * function is called. Once the continuation is called, the message is |
2020 | * no longer in the queue! | 2484 | * no longer in the queue! |
2021 | * | 2485 | * |
2022 | * @param q Handle to the queue entry to cancel. | 2486 | * @param tq Handle to the queue entry to cancel. |
2023 | */ | 2487 | */ |
2024 | void | 2488 | void |
2025 | GCT_send_cancel (struct CadetTunnelQueueEntry *q) | 2489 | GCT_send_cancel (struct CadetTunnelQueueEntry *tq) |
2026 | { | 2490 | { |
2027 | struct CadetTunnel *t = q->t; | 2491 | struct CadetTunnel *t = tq->t; |
2028 | 2492 | ||
2029 | GNUNET_CONTAINER_DLL_remove (t->tq_head, | 2493 | GNUNET_CONTAINER_DLL_remove (t->tq_head, |
2030 | t->tq_tail, | 2494 | t->tq_tail, |
2031 | q); | 2495 | tq); |
2032 | GNUNET_free (q); | 2496 | GNUNET_MQ_discard (tq->env); |
2497 | GNUNET_free (tq); | ||
2033 | } | 2498 | } |
2034 | 2499 | ||
2035 | 2500 | ||
@@ -2136,68 +2601,6 @@ debug_channel (void *cls, | |||
2136 | } | 2601 | } |
2137 | 2602 | ||
2138 | 2603 | ||
2139 | /** | ||
2140 | * Get string description for tunnel connectivity state. | ||
2141 | * | ||
2142 | * @param cs Tunnel state. | ||
2143 | * | ||
2144 | * @return String representation. | ||
2145 | */ | ||
2146 | static const char * | ||
2147 | cstate2s (enum CadetTunnelCState cs) | ||
2148 | { | ||
2149 | static char buf[32]; | ||
2150 | |||
2151 | switch (cs) | ||
2152 | { | ||
2153 | case CADET_TUNNEL_NEW: | ||
2154 | return "CADET_TUNNEL_NEW"; | ||
2155 | case CADET_TUNNEL_SEARCHING: | ||
2156 | return "CADET_TUNNEL_SEARCHING"; | ||
2157 | case CADET_TUNNEL_WAITING: | ||
2158 | return "CADET_TUNNEL_WAITING"; | ||
2159 | case CADET_TUNNEL_READY: | ||
2160 | return "CADET_TUNNEL_READY"; | ||
2161 | case CADET_TUNNEL_SHUTDOWN: | ||
2162 | return "CADET_TUNNEL_SHUTDOWN"; | ||
2163 | default: | ||
2164 | SPRINTF (buf, "%u (UNKNOWN STATE)", cs); | ||
2165 | return buf; | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | |||
2170 | /** | ||
2171 | * Get string description for tunnel encryption state. | ||
2172 | * | ||
2173 | * @param es Tunnel state. | ||
2174 | * | ||
2175 | * @return String representation. | ||
2176 | */ | ||
2177 | static const char * | ||
2178 | estate2s (enum CadetTunnelEState es) | ||
2179 | { | ||
2180 | static char buf[32]; | ||
2181 | |||
2182 | switch (es) | ||
2183 | { | ||
2184 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
2185 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | ||
2186 | case CADET_TUNNEL_KEY_SENT: | ||
2187 | return "CADET_TUNNEL_KEY_SENT"; | ||
2188 | case CADET_TUNNEL_KEY_PING: | ||
2189 | return "CADET_TUNNEL_KEY_PING"; | ||
2190 | case CADET_TUNNEL_KEY_OK: | ||
2191 | return "CADET_TUNNEL_KEY_OK"; | ||
2192 | case CADET_TUNNEL_KEY_REKEY: | ||
2193 | return "CADET_TUNNEL_KEY_REKEY"; | ||
2194 | default: | ||
2195 | SPRINTF (buf, "%u (UNKNOWN STATE)", es); | ||
2196 | return buf; | ||
2197 | } | ||
2198 | } | ||
2199 | |||
2200 | |||
2201 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-tun",__VA_ARGS__) | 2604 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-tun",__VA_ARGS__) |
2202 | 2605 | ||
2203 | 2606 | ||
@@ -2221,9 +2624,8 @@ GCT_debug (const struct CadetTunnel *t, | |||
2221 | return; | 2624 | return; |
2222 | 2625 | ||
2223 | LOG2 (level, | 2626 | LOG2 (level, |
2224 | "TTT TUNNEL TOWARDS %s in cstate %s, estate %s tq_len: %u #cons: %u\n", | 2627 | "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n", |
2225 | GCT_2s (t), | 2628 | GCT_2s (t), |
2226 | cstate2s (t->cstate), | ||
2227 | estate2s (t->estate), | 2629 | estate2s (t->estate), |
2228 | t->tq_len, | 2630 | t->tq_len, |
2229 | t->num_connections); | 2631 | t->num_connections); |
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.h b/src/cadet/gnunet-service-cadet-new_tunnels.h index 82e4b0da6..c867a9e82 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.h +++ b/src/cadet/gnunet-service-cadet-new_tunnels.h | |||
@@ -39,45 +39,13 @@ | |||
39 | 39 | ||
40 | 40 | ||
41 | /** | 41 | /** |
42 | * All the connectivity states a tunnel can be in. | ||
43 | */ | ||
44 | enum CadetTunnelCState | ||
45 | { | ||
46 | /** | ||
47 | * Uninitialized status, should never appear in operation. | ||
48 | */ | ||
49 | CADET_TUNNEL_NEW, | ||
50 | |||
51 | /** | ||
52 | * No path to the peer known yet. | ||
53 | */ | ||
54 | CADET_TUNNEL_SEARCHING, | ||
55 | |||
56 | /** | ||
57 | * Request sent, not yet answered. | ||
58 | */ | ||
59 | CADET_TUNNEL_WAITING, | ||
60 | |||
61 | /** | ||
62 | * Peer connected and ready to accept data. | ||
63 | */ | ||
64 | CADET_TUNNEL_READY, | ||
65 | |||
66 | /** | ||
67 | * Tunnel being shut down, don't try to keep it alive. | ||
68 | */ | ||
69 | CADET_TUNNEL_SHUTDOWN | ||
70 | }; | ||
71 | |||
72 | |||
73 | |||
74 | /** | ||
75 | * All the encryption states a tunnel can be in. | 42 | * All the encryption states a tunnel can be in. |
76 | */ | 43 | */ |
77 | enum CadetTunnelEState | 44 | enum CadetTunnelEState |
78 | { | 45 | { |
79 | /** | 46 | /** |
80 | * Uninitialized status, should never appear in operation. | 47 | * Uninitialized status, we need to send KX. We will stay |
48 | * in this state until the first connection is up. | ||
81 | */ | 49 | */ |
82 | CADET_TUNNEL_KEY_UNINITIALIZED, | 50 | CADET_TUNNEL_KEY_UNINITIALIZED, |
83 | 51 | ||
@@ -87,19 +55,10 @@ enum CadetTunnelEState | |||
87 | CADET_TUNNEL_KEY_SENT, | 55 | CADET_TUNNEL_KEY_SENT, |
88 | 56 | ||
89 | /** | 57 | /** |
90 | * In OTR: New ephemeral key and ping sent, waiting for pong. | 58 | * Key received and we sent ours back, but we got no traffic yet. |
91 | * | 59 | * We will not yet send traffic, as this might have been a replay. |
92 | * This means that we DO have the peer's ephemeral key, otherwise the | 60 | * The other (initiating) peer should send a CHANNEL_OPEN next |
93 | * state would be KEY_SENT. We DO NOT have a valid session key (either no | 61 | * anyway. |
94 | * previous key or previous key expired). | ||
95 | * | ||
96 | * | ||
97 | * In Axolotl: Key sent and received but no deciphered traffic yet. | ||
98 | * | ||
99 | * This means that we can send traffic (otherwise we would never complete | ||
100 | * the handshake), but we don't have complete confirmation. Since the first | ||
101 | * traffic MUST be a complete channel creation 3-way handshake, no payload | ||
102 | * will be sent before confirmation. | ||
103 | */ | 62 | */ |
104 | CADET_TUNNEL_KEY_PING, | 63 | CADET_TUNNEL_KEY_PING, |
105 | 64 | ||
@@ -140,6 +99,15 @@ GCT_create_tunnel (struct CadetPeer *destination); | |||
140 | 99 | ||
141 | 100 | ||
142 | /** | 101 | /** |
102 | * Destroys the tunnel @a t now, without delay. Used during shutdown. | ||
103 | * | ||
104 | * @param t tunnel to destroy | ||
105 | */ | ||
106 | void | ||
107 | GCT_destroy_tunnel_now (struct CadetTunnel *t); | ||
108 | |||
109 | |||
110 | /** | ||
143 | * Add a @a connection to the @a tunnel. | 111 | * Add a @a connection to the @a tunnel. |
144 | * | 112 | * |
145 | * @param t a tunnel | 113 | * @param t a tunnel |
@@ -193,12 +161,23 @@ GCT_add_channel (struct CadetTunnel *t, | |||
193 | * | 161 | * |
194 | * @param t Tunnel. | 162 | * @param t Tunnel. |
195 | * @param ch Channel | 163 | * @param ch Channel |
196 | * @param gid unique number identifying @a ch within @a t | 164 | * @param ctn unique number identifying @a ch within @a t |
197 | */ | 165 | */ |
198 | void | 166 | void |
199 | GCT_remove_channel (struct CadetTunnel *t, | 167 | GCT_remove_channel (struct CadetTunnel *t, |
200 | struct CadetChannel *ch, | 168 | struct CadetChannel *ch, |
201 | struct GNUNET_CADET_ChannelTunnelNumber gid); | 169 | struct GNUNET_CADET_ChannelTunnelNumber ctn); |
170 | |||
171 | |||
172 | /** | ||
173 | * Send a DESTROY message via the tunnel. | ||
174 | * | ||
175 | * @param t the tunnel to transmit over | ||
176 | * @param ctn ID of the channel to destroy | ||
177 | */ | ||
178 | void | ||
179 | GCT_send_channel_destroy (struct CadetTunnel *t, | ||
180 | struct GNUNET_CADET_ChannelTunnelNumber ctn); | ||
202 | 181 | ||
203 | 182 | ||
204 | /** | 183 | /** |
@@ -300,17 +279,6 @@ GCT_iterate_channels (struct CadetTunnel *t, | |||
300 | 279 | ||
301 | 280 | ||
302 | /** | 281 | /** |
303 | * Get the connectivity state of a tunnel. | ||
304 | * | ||
305 | * @param t Tunnel. | ||
306 | * | ||
307 | * @return Tunnel's connectivity state. | ||
308 | */ | ||
309 | enum CadetTunnelCState | ||
310 | GCT_get_cstate (struct CadetTunnel *t); | ||
311 | |||
312 | |||
313 | /** | ||
314 | * Get the encryption state of a tunnel. | 282 | * Get the encryption state of a tunnel. |
315 | * | 283 | * |
316 | * @param t Tunnel. | 284 | * @param t Tunnel. |
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index dee0c37d7..7b7c6e57c 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c | |||
@@ -451,7 +451,7 @@ add_destination (struct CadetChannel *ch, struct CadetClient *c) | |||
451 | } | 451 | } |
452 | 452 | ||
453 | /* Assign local id as destination */ | 453 | /* Assign local id as destination */ |
454 | ch->lid_dest = GML_get_next_chid (c); | 454 | ch->lid_dest = GML_get_next_ccn (c); |
455 | 455 | ||
456 | /* Store in client's hashmap */ | 456 | /* Store in client's hashmap */ |
457 | GML_channel_add (c, ch->lid_dest, ch); | 457 | GML_channel_add (c, ch->lid_dest, ch); |
@@ -517,7 +517,7 @@ send_destroy (struct CadetChannel *ch, int local_only) | |||
517 | 517 | ||
518 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | 518 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); |
519 | msg.header.size = htons (sizeof (msg)); | 519 | msg.header.size = htons (sizeof (msg)); |
520 | msg.chid = ch->gid; | 520 | msg.ctn = ch->gid; |
521 | 521 | ||
522 | /* If root is not NULL, notify. | 522 | /* If root is not NULL, notify. |
523 | * If it's NULL, check lid_root. When a local destroy comes in, root | 523 | * If it's NULL, check lid_root. When a local destroy comes in, root |
@@ -886,7 +886,7 @@ send_create (struct CadetChannel *ch) | |||
886 | 886 | ||
887 | msgcc.header.size = htons (sizeof (msgcc)); | 887 | msgcc.header.size = htons (sizeof (msgcc)); |
888 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 888 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); |
889 | msgcc.chid = ch->gid; | 889 | msgcc.ctn = ch->gid; |
890 | msgcc.port = ch->port; | 890 | msgcc.port = ch->port; |
891 | msgcc.opt = htonl (channel_get_options (ch)); | 891 | msgcc.opt = htonl (channel_get_options (ch)); |
892 | 892 | ||
@@ -911,7 +911,7 @@ send_ack (struct CadetChannel *ch, int fwd) | |||
911 | " sending channel %s ack for channel %s\n", | 911 | " sending channel %s ack for channel %s\n", |
912 | GC_f2s (fwd), GCCH_2s (ch)); | 912 | GC_f2s (fwd), GCCH_2s (ch)); |
913 | 913 | ||
914 | msg.chid =ch->gid; | 914 | msg.ctn =ch->gid; |
915 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); | 915 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); |
916 | } | 916 | } |
917 | 917 | ||
@@ -951,7 +951,7 @@ send_nack (struct CadetChannel *ch) | |||
951 | " sending channel NACK for channel %s\n", | 951 | " sending channel NACK for channel %s\n", |
952 | GCCH_2s (ch)); | 952 | GCCH_2s (ch)); |
953 | 953 | ||
954 | msg.chid = ch->gid; | 954 | msg.ctn = ch->gid; |
955 | GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL); | 955 | GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL); |
956 | } | 956 | } |
957 | 957 | ||
@@ -1270,7 +1270,7 @@ channel_new (struct CadetTunnel *t, | |||
1270 | 1270 | ||
1271 | if (NULL != owner) | 1271 | if (NULL != owner) |
1272 | { | 1272 | { |
1273 | ch->gid = GCT_get_next_chid (t); | 1273 | ch->gid = GCT_get_next_ctn (t); |
1274 | GML_channel_add (owner, lid_root, ch); | 1274 | GML_channel_add (owner, lid_root, ch); |
1275 | } | 1275 | } |
1276 | GCT_add_channel (t, ch); | 1276 | GCT_add_channel (t, ch); |
@@ -1308,17 +1308,18 @@ handle_loopback (struct CadetChannel *ch, | |||
1308 | break; | 1308 | break; |
1309 | 1309 | ||
1310 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: | 1310 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK: |
1311 | GCCH_handle_data_ack (ch, (struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd); | 1311 | GCCH_handle_data_ack (ch, |
1312 | (const struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd); | ||
1312 | break; | 1313 | break; |
1313 | 1314 | ||
1314 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: | 1315 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN: |
1315 | GCCH_handle_create (ch->t, | 1316 | GCCH_handle_create (ch->t, |
1316 | (struct GNUNET_CADET_ChannelOpenMessage *) msgh); | 1317 | (const struct GNUNET_CADET_ChannelOpenMessage *) msgh); |
1317 | break; | 1318 | break; |
1318 | 1319 | ||
1319 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | 1320 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: |
1320 | GCCH_handle_ack (ch, | 1321 | GCCH_handle_ack (ch, |
1321 | (struct GNUNET_CADET_ChannelManageMessage *) msgh, | 1322 | (const struct GNUNET_CADET_ChannelManageMessage *) msgh, |
1322 | fwd); | 1323 | fwd); |
1323 | break; | 1324 | break; |
1324 | 1325 | ||
@@ -1328,7 +1329,7 @@ handle_loopback (struct CadetChannel *ch, | |||
1328 | 1329 | ||
1329 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: | 1330 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: |
1330 | GCCH_handle_destroy (ch, | 1331 | GCCH_handle_destroy (ch, |
1331 | (struct GNUNET_CADET_ChannelManageMessage *) msgh, | 1332 | (const struct GNUNET_CADET_ChannelManageMessage *) msgh, |
1332 | fwd); | 1333 | fwd); |
1333 | break; | 1334 | break; |
1334 | 1335 | ||
@@ -1538,7 +1539,7 @@ GCCH_send_data_ack (struct CadetChannel *ch, int fwd) | |||
1538 | 1539 | ||
1539 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); | 1540 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); |
1540 | msg.header.size = htons (sizeof (msg)); | 1541 | msg.header.size = htons (sizeof (msg)); |
1541 | msg.chid = ch->gid; | 1542 | msg.ctn = ch->gid; |
1542 | msg.mid = htonl (ack); | 1543 | msg.mid = htonl (ack); |
1543 | 1544 | ||
1544 | msg.futures = 0LL; | 1545 | msg.futures = 0LL; |
@@ -1781,7 +1782,7 @@ GCCH_handle_local_data (struct CadetChannel *ch, | |||
1781 | GNUNET_memcpy (&payload[1], message, size); | 1782 | GNUNET_memcpy (&payload[1], message, size); |
1782 | payload->header.size = htons (p2p_size); | 1783 | payload->header.size = htons (p2p_size); |
1783 | payload->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); | 1784 | payload->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); |
1784 | payload->chid = ch->gid; | 1785 | payload->ctn = ch->gid; |
1785 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n"); | 1786 | LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n"); |
1786 | GCCH_send_prebuilt_message (&payload->header, ch, fwd, NULL); | 1787 | GCCH_send_prebuilt_message (&payload->header, ch, fwd, NULL); |
1787 | 1788 | ||
@@ -1842,23 +1843,23 @@ GCCH_handle_local_destroy (struct CadetChannel *ch, | |||
1842 | * @param c Client that requested the creation (will be the root). | 1843 | * @param c Client that requested the creation (will be the root). |
1843 | * @param msg Create Channel message. | 1844 | * @param msg Create Channel message. |
1844 | * | 1845 | * |
1845 | * @return GNUNET_OK if everything went fine, GNUNET_SYSERR otherwise. | 1846 | * @return #GNUNET_OK if everything went fine, #GNUNET_SYSERR otherwise. |
1846 | */ | 1847 | */ |
1847 | int | 1848 | int |
1848 | GCCH_handle_local_create (struct CadetClient *c, | 1849 | GCCH_handle_local_create (struct CadetClient *c, |
1849 | struct GNUNET_CADET_ChannelOpenMessageMessage *msg) | 1850 | struct GNUNET_CADET_LocalChannelCreateMessage *msg) |
1850 | { | 1851 | { |
1851 | struct CadetChannel *ch; | 1852 | struct CadetChannel *ch; |
1852 | struct CadetTunnel *t; | 1853 | struct CadetTunnel *t; |
1853 | struct CadetPeer *peer; | 1854 | struct CadetPeer *peer; |
1854 | struct GNUNET_CADET_ClientChannelNumber chid; | 1855 | struct GNUNET_CADET_ClientChannelNumber ccn; |
1855 | 1856 | ||
1856 | LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n", | 1857 | LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n", |
1857 | GNUNET_i2s (&msg->peer), GNUNET_h2s (&msg->port)); | 1858 | GNUNET_i2s (&msg->peer), GNUNET_h2s (&msg->port)); |
1858 | chid = msg->channel_id; | 1859 | ccn = msg->ccn; |
1859 | 1860 | ||
1860 | /* Sanity check for duplicate channel IDs */ | 1861 | /* Sanity check for duplicate channel IDs */ |
1861 | if (NULL != GML_channel_get (c, chid)) | 1862 | if (NULL != GML_channel_get (c, ccn)) |
1862 | { | 1863 | { |
1863 | GNUNET_break (0); | 1864 | GNUNET_break (0); |
1864 | return GNUNET_SYSERR; | 1865 | return GNUNET_SYSERR; |
@@ -1879,7 +1880,7 @@ GCCH_handle_local_create (struct CadetClient *c, | |||
1879 | } | 1880 | } |
1880 | 1881 | ||
1881 | /* Create channel */ | 1882 | /* Create channel */ |
1882 | ch = channel_new (t, c, chid); | 1883 | ch = channel_new (t, c, ccn); |
1883 | if (NULL == ch) | 1884 | if (NULL == ch) |
1884 | { | 1885 | { |
1885 | GNUNET_break (0); | 1886 | GNUNET_break (0); |
@@ -2153,20 +2154,20 @@ struct CadetChannel * | |||
2153 | GCCH_handle_create (struct CadetTunnel *t, | 2154 | GCCH_handle_create (struct CadetTunnel *t, |
2154 | const struct GNUNET_CADET_ChannelOpenMessage *msg) | 2155 | const struct GNUNET_CADET_ChannelOpenMessage *msg) |
2155 | { | 2156 | { |
2156 | struct GNUNET_CADET_ClientChannelNumber chid; | 2157 | struct GNUNET_CADET_ClientChannelNumber ccn; |
2157 | struct GNUNET_CADET_ChannelTunnelNumber gid; | 2158 | struct GNUNET_CADET_ChannelTunnelNumber gid; |
2158 | struct CadetChannel *ch; | 2159 | struct CadetChannel *ch; |
2159 | struct CadetClient *c; | 2160 | struct CadetClient *c; |
2160 | int new_channel; | 2161 | int new_channel; |
2161 | const struct GNUNET_HashCode *port; | 2162 | const struct GNUNET_HashCode *port; |
2162 | 2163 | ||
2163 | gid = msg->chid; | 2164 | gid = msg->ctn; |
2164 | ch = GCT_get_channel (t, gid); | 2165 | ch = GCT_get_channel (t, gid); |
2165 | if (NULL == ch) | 2166 | if (NULL == ch) |
2166 | { | 2167 | { |
2167 | /* Create channel */ | 2168 | /* Create channel */ |
2168 | chid.channel_of_client = htonl (0); | 2169 | ccn.channel_of_client = htonl (0); |
2169 | ch = channel_new (t, NULL, chid); | 2170 | ch = channel_new (t, NULL, ccn); |
2170 | ch->gid = gid; | 2171 | ch->gid = gid; |
2171 | channel_set_options (ch, ntohl (msg->opt)); | 2172 | channel_set_options (ch, ntohl (msg->opt)); |
2172 | new_channel = GNUNET_YES; | 2173 | new_channel = GNUNET_YES; |
@@ -2179,7 +2180,7 @@ GCCH_handle_create (struct CadetTunnel *t, | |||
2179 | 2180 | ||
2180 | LOG (GNUNET_ERROR_TYPE_INFO, | 2181 | LOG (GNUNET_ERROR_TYPE_INFO, |
2181 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", | 2182 | "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n", |
2182 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN), chid, port, | 2183 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN), ccn, port, |
2183 | GCCH_2s (ch), ch, GC_f2s (GNUNET_YES), ntohs (msg->header.size)); | 2184 | GCCH_2s (ch), ch, GC_f2s (GNUNET_YES), ntohs (msg->header.size)); |
2184 | 2185 | ||
2185 | if (GNUNET_YES == new_channel || GCT_is_loopback (t)) | 2186 | if (GNUNET_YES == new_channel || GCT_is_loopback (t)) |
@@ -2410,7 +2411,7 @@ GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | |||
2410 | { | 2411 | { |
2411 | struct GNUNET_CADET_ChannelOpenMessage *cc_msg; | 2412 | struct GNUNET_CADET_ChannelOpenMessage *cc_msg; |
2412 | cc_msg = (struct GNUNET_CADET_ChannelOpenMessage *) message; | 2413 | cc_msg = (struct GNUNET_CADET_ChannelOpenMessage *) message; |
2413 | SPRINTF (info, " 0x%08X", ntohl (cc_msg->chid.cn)); | 2414 | SPRINTF (info, " 0x%08X", ntohl (cc_msg->ctn.cn)); |
2414 | break; | 2415 | break; |
2415 | } | 2416 | } |
2416 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: | 2417 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK: |
@@ -2419,7 +2420,7 @@ GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | |||
2419 | { | 2420 | { |
2420 | struct GNUNET_CADET_ChannelManageMessage *m_msg; | 2421 | struct GNUNET_CADET_ChannelManageMessage *m_msg; |
2421 | m_msg = (struct GNUNET_CADET_ChannelManageMessage *) message; | 2422 | m_msg = (struct GNUNET_CADET_ChannelManageMessage *) message; |
2422 | SPRINTF (info, " 0x%08X", ntohl (m_msg->chid.cn)); | 2423 | SPRINTF (info, " 0x%08X", ntohl (m_msg->ctn.cn)); |
2423 | break; | 2424 | break; |
2424 | } | 2425 | } |
2425 | default: | 2426 | default: |
diff --git a/src/cadet/gnunet-service-cadet_channel.h b/src/cadet/gnunet-service-cadet_channel.h index 1eeebf34b..9d4893269 100644 --- a/src/cadet/gnunet-service-cadet_channel.h +++ b/src/cadet/gnunet-service-cadet_channel.h | |||
@@ -72,6 +72,7 @@ GCCH_destroy (struct CadetChannel *ch); | |||
72 | struct GNUNET_CADET_ChannelTunnelNumber | 72 | struct GNUNET_CADET_ChannelTunnelNumber |
73 | GCCH_get_id (const struct CadetChannel *ch); | 73 | GCCH_get_id (const struct CadetChannel *ch); |
74 | 74 | ||
75 | |||
75 | /** | 76 | /** |
76 | * Get the channel tunnel. | 77 | * Get the channel tunnel. |
77 | * | 78 | * |
@@ -82,6 +83,7 @@ GCCH_get_id (const struct CadetChannel *ch); | |||
82 | struct CadetTunnel * | 83 | struct CadetTunnel * |
83 | GCCH_get_tunnel (const struct CadetChannel *ch); | 84 | GCCH_get_tunnel (const struct CadetChannel *ch); |
84 | 85 | ||
86 | |||
85 | /** | 87 | /** |
86 | * Get free buffer space towards the client on a specific channel. | 88 | * Get free buffer space towards the client on a specific channel. |
87 | * | 89 | * |
@@ -224,7 +226,7 @@ GCCH_handle_local_destroy (struct CadetChannel *ch, | |||
224 | */ | 226 | */ |
225 | int | 227 | int |
226 | GCCH_handle_local_create (struct CadetClient *c, | 228 | GCCH_handle_local_create (struct CadetClient *c, |
227 | struct GNUNET_CADET_ChannelOpenMessageMessage *msg); | 229 | struct GNUNET_CADET_LocalChannelCreateMessage *msg); |
228 | 230 | ||
229 | /** | 231 | /** |
230 | * Handler for cadet network payload traffic. | 232 | * Handler for cadet network payload traffic. |
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c index 931b32b95..af27647b3 100644 --- a/src/cadet/gnunet-service-cadet_connection.c +++ b/src/cadet/gnunet-service-cadet_connection.c | |||
@@ -617,7 +617,7 @@ send_ack (struct CadetConnection *c, | |||
617 | /* Build ACK message and send on conn */ | 617 | /* Build ACK message and send on conn */ |
618 | msg.header.size = htons (sizeof (msg)); | 618 | msg.header.size = htons (sizeof (msg)); |
619 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK); | 619 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK); |
620 | msg.cemi = ack_cemi; | 620 | msg.cemi_max = ack_cemi; |
621 | msg.cid = c->id; | 621 | msg.cid = c->id; |
622 | 622 | ||
623 | prev_fc->ack_msg = GCC_send_prebuilt_message (&msg.header, | 623 | prev_fc->ack_msg = GCC_send_prebuilt_message (&msg.header, |
@@ -1054,9 +1054,9 @@ static void | |||
1054 | send_connection_ack (struct CadetConnection *c, int fwd) | 1054 | send_connection_ack (struct CadetConnection *c, int fwd) |
1055 | { | 1055 | { |
1056 | static struct CadetEncryptedMessageIdentifier zero; | 1056 | static struct CadetEncryptedMessageIdentifier zero; |
1057 | struct GNUNET_CADET_ConnectionCreateMessageAckMessage msg; | 1057 | struct GNUNET_CADET_ConnectionCreateAckMessage msg; |
1058 | struct CadetTunnel *t; | 1058 | struct CadetTunnel *t; |
1059 | const uint16_t size = sizeof (struct GNUNET_CADET_ConnectionCreateMessageAckMessage); | 1059 | const uint16_t size = sizeof (struct GNUNET_CADET_ConnectionCreateAckMessage); |
1060 | const uint16_t type = GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK; | 1060 | const uint16_t type = GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK; |
1061 | 1061 | ||
1062 | GCC_check_connections (); | 1062 | GCC_check_connections (); |
@@ -2067,7 +2067,7 @@ GCC_handle_create (struct CadetPeer *peer, | |||
2067 | */ | 2067 | */ |
2068 | void | 2068 | void |
2069 | GCC_handle_confirm (struct CadetPeer *peer, | 2069 | GCC_handle_confirm (struct CadetPeer *peer, |
2070 | const struct GNUNET_CADET_ConnectionCreateMessageAckMessage *msg) | 2070 | const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) |
2071 | { | 2071 | { |
2072 | static struct CadetEncryptedMessageIdentifier zero; | 2072 | static struct CadetEncryptedMessageIdentifier zero; |
2073 | struct CadetConnection *c; | 2073 | struct CadetConnection *c; |
@@ -2373,7 +2373,7 @@ GCC_handle_ack (struct CadetPeer *peer, | |||
2373 | return; | 2373 | return; |
2374 | } | 2374 | } |
2375 | 2375 | ||
2376 | ack = msg->cemi; | 2376 | ack = msg->cemi_max; |
2377 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n", | 2377 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n", |
2378 | GC_f2s (fwd), | 2378 | GC_f2s (fwd), |
2379 | ntohl (ack.pid), | 2379 | ntohl (ack.pid), |
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h index 1c3160dfd..307cb42c2 100644 --- a/src/cadet/gnunet-service-cadet_connection.h +++ b/src/cadet/gnunet-service-cadet_connection.h | |||
@@ -136,7 +136,7 @@ GCC_handle_create (struct CadetPeer *peer, | |||
136 | */ | 136 | */ |
137 | void | 137 | void |
138 | GCC_handle_confirm (struct CadetPeer *peer, | 138 | GCC_handle_confirm (struct CadetPeer *peer, |
139 | const struct GNUNET_CADET_ConnectionCreateMessageAckMessage *msg); | 139 | const struct GNUNET_CADET_ConnectionCreateAckMessage *msg); |
140 | 140 | ||
141 | 141 | ||
142 | /** | 142 | /** |
diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c index e1f6ac4c3..dea6681df 100644 --- a/src/cadet/gnunet-service-cadet_local.c +++ b/src/cadet/gnunet-service-cadet_local.c | |||
@@ -70,7 +70,7 @@ struct CadetClient | |||
70 | /** | 70 | /** |
71 | * Channel ID for the next incoming channel. | 71 | * Channel ID for the next incoming channel. |
72 | */ | 72 | */ |
73 | struct GNUNET_CADET_ClientChannelNumber next_chid; | 73 | struct GNUNET_CADET_ClientChannelNumber next_ccn; |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * Handle to communicate with the client | 76 | * Handle to communicate with the client |
@@ -440,7 +440,7 @@ handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
440 | LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); | 440 | LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); |
441 | 441 | ||
442 | /* Message size sanity check */ | 442 | /* Message size sanity check */ |
443 | if (sizeof (struct GNUNET_CADET_ChannelOpenMessageMessage) | 443 | if (sizeof (struct GNUNET_CADET_LocalChannelCreateMessage) |
444 | != ntohs (message->size)) | 444 | != ntohs (message->size)) |
445 | { | 445 | { |
446 | GNUNET_break (0); | 446 | GNUNET_break (0); |
@@ -450,7 +450,7 @@ handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
450 | 450 | ||
451 | if (GNUNET_OK != | 451 | if (GNUNET_OK != |
452 | GCCH_handle_local_create (c, | 452 | GCCH_handle_local_create (c, |
453 | (struct GNUNET_CADET_ChannelOpenMessageMessage *) | 453 | (struct GNUNET_CADET_LocalChannelCreateMessage *) |
454 | message)) | 454 | message)) |
455 | { | 455 | { |
456 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 456 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -472,10 +472,10 @@ static void | |||
472 | handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | 472 | handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, |
473 | const struct GNUNET_MessageHeader *message) | 473 | const struct GNUNET_MessageHeader *message) |
474 | { | 474 | { |
475 | struct GNUNET_CADET_ChannelDestroyMessage *msg; | 475 | const struct GNUNET_CADET_LocalChannelDestroyMessage *msg; |
476 | struct CadetClient *c; | 476 | struct CadetClient *c; |
477 | struct CadetChannel *ch; | 477 | struct CadetChannel *ch; |
478 | struct GNUNET_CADET_ClientChannelNumber chid; | 478 | struct GNUNET_CADET_ClientChannelNumber ccn; |
479 | 479 | ||
480 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n"); | 480 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n"); |
481 | 481 | ||
@@ -489,7 +489,7 @@ handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
489 | LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); | 489 | LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); |
490 | 490 | ||
491 | /* Message sanity check */ | 491 | /* Message sanity check */ |
492 | if (sizeof (struct GNUNET_CADET_ChannelDestroyMessage) | 492 | if (sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage) |
493 | != ntohs (message->size)) | 493 | != ntohs (message->size)) |
494 | { | 494 | { |
495 | GNUNET_break (0); | 495 | GNUNET_break (0); |
@@ -497,18 +497,18 @@ handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
497 | return; | 497 | return; |
498 | } | 498 | } |
499 | 499 | ||
500 | msg = (struct GNUNET_CADET_ChannelDestroyMessage *) message; | 500 | msg = (const struct GNUNET_CADET_LocalChannelDestroyMessage *) message; |
501 | 501 | ||
502 | /* Retrieve tunnel */ | 502 | /* Retrieve tunnel */ |
503 | chid = msg->channel_id; | 503 | ccn = msg->ccn; |
504 | ch = GML_channel_get (c, chid); | 504 | ch = GML_channel_get (c, ccn); |
505 | 505 | ||
506 | LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n", | 506 | LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n", |
507 | c->id, chid); | 507 | c->id, ccn); |
508 | 508 | ||
509 | if (NULL == ch) | 509 | if (NULL == ch) |
510 | { | 510 | { |
511 | LOG (GNUNET_ERROR_TYPE_WARNING, " channel %X not found\n", chid); | 511 | LOG (GNUNET_ERROR_TYPE_WARNING, " channel %X not found\n", ccn); |
512 | GNUNET_STATISTICS_update (stats, | 512 | GNUNET_STATISTICS_update (stats, |
513 | "# client destroy messages on unknown channel", | 513 | "# client destroy messages on unknown channel", |
514 | 1, GNUNET_NO); | 514 | 1, GNUNET_NO); |
@@ -518,10 +518,9 @@ handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
518 | 518 | ||
519 | GCCH_handle_local_destroy (ch, | 519 | GCCH_handle_local_destroy (ch, |
520 | c, | 520 | c, |
521 | ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | 521 | ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); |
522 | 522 | ||
523 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 523 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
524 | return; | ||
525 | } | 524 | } |
526 | 525 | ||
527 | 526 | ||
@@ -540,7 +539,7 @@ handle_data (void *cls, struct GNUNET_SERVER_Client *client, | |||
540 | struct GNUNET_CADET_LocalData *msg; | 539 | struct GNUNET_CADET_LocalData *msg; |
541 | struct CadetClient *c; | 540 | struct CadetClient *c; |
542 | struct CadetChannel *ch; | 541 | struct CadetChannel *ch; |
543 | struct GNUNET_CADET_ClientChannelNumber chid; | 542 | struct GNUNET_CADET_ClientChannelNumber ccn; |
544 | size_t message_size; | 543 | size_t message_size; |
545 | size_t payload_size; | 544 | size_t payload_size; |
546 | size_t payload_claimed_size; | 545 | size_t payload_claimed_size; |
@@ -586,13 +585,13 @@ handle_data (void *cls, struct GNUNET_SERVER_Client *client, | |||
586 | return; | 585 | return; |
587 | } | 586 | } |
588 | 587 | ||
589 | chid = msg->id; | 588 | ccn = msg->ccn; |
590 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n", | 589 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n", |
591 | payload_size, payload_claimed_size, c->id); | 590 | payload_size, payload_claimed_size, c->id); |
592 | 591 | ||
593 | /* Channel exists? */ | 592 | /* Channel exists? */ |
594 | fwd = ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | 593 | fwd = ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; |
595 | ch = GML_channel_get (c, chid); | 594 | ch = GML_channel_get (c, ccn); |
596 | if (NULL == ch) | 595 | if (NULL == ch) |
597 | { | 596 | { |
598 | GNUNET_STATISTICS_update (stats, | 597 | GNUNET_STATISTICS_update (stats, |
@@ -629,7 +628,7 @@ handle_ack (void *cls, struct GNUNET_SERVER_Client *client, | |||
629 | struct GNUNET_CADET_LocalAck *msg; | 628 | struct GNUNET_CADET_LocalAck *msg; |
630 | struct CadetChannel *ch; | 629 | struct CadetChannel *ch; |
631 | struct CadetClient *c; | 630 | struct CadetClient *c; |
632 | struct GNUNET_CADET_ClientChannelNumber chid; | 631 | struct GNUNET_CADET_ClientChannelNumber ccn; |
633 | int fwd; | 632 | int fwd; |
634 | 633 | ||
635 | LOG (GNUNET_ERROR_TYPE_DEBUG, "\n"); | 634 | LOG (GNUNET_ERROR_TYPE_DEBUG, "\n"); |
@@ -647,16 +646,16 @@ handle_ack (void *cls, struct GNUNET_SERVER_Client *client, | |||
647 | msg = (struct GNUNET_CADET_LocalAck *) message; | 646 | msg = (struct GNUNET_CADET_LocalAck *) message; |
648 | 647 | ||
649 | /* Channel exists? */ | 648 | /* Channel exists? */ |
650 | chid = msg->channel_id; | 649 | ccn = msg->ccn; |
651 | LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", | 650 | LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", |
652 | ntohl (chid.channel_of_client)); | 651 | ntohl (ccn.channel_of_client)); |
653 | ch = GML_channel_get (c, chid); | 652 | ch = GML_channel_get (c, ccn); |
654 | LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch); | 653 | LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch); |
655 | if (NULL == ch) | 654 | if (NULL == ch) |
656 | { | 655 | { |
657 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 656 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
658 | "Channel %X unknown.\n", | 657 | "Channel %X unknown.\n", |
659 | ntohl (chid.channel_of_client)); | 658 | ntohl (ccn.channel_of_client)); |
660 | LOG (GNUNET_ERROR_TYPE_DEBUG, " for client %u.\n", c->id); | 659 | LOG (GNUNET_ERROR_TYPE_DEBUG, " for client %u.\n", c->id); |
661 | GNUNET_STATISTICS_update (stats, | 660 | GNUNET_STATISTICS_update (stats, |
662 | "# client ack messages on unknown channel", | 661 | "# client ack messages on unknown channel", |
@@ -667,7 +666,7 @@ handle_ack (void *cls, struct GNUNET_SERVER_Client *client, | |||
667 | 666 | ||
668 | /* If client is root, the ACK is going FWD, therefore this is "BCK ACK". */ | 667 | /* If client is root, the ACK is going FWD, therefore this is "BCK ACK". */ |
669 | /* If client is dest, the ACK is going BCK, therefore this is "FWD ACK" */ | 668 | /* If client is dest, the ACK is going BCK, therefore this is "FWD ACK" */ |
670 | fwd = ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | 669 | fwd = ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; |
671 | 670 | ||
672 | GCCH_handle_local_ack (ch, fwd); | 671 | GCCH_handle_local_ack (ch, fwd); |
673 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 672 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -1128,10 +1127,10 @@ static struct GNUNET_SERVER_MessageHandler client_handlers[] = { | |||
1128 | sizeof (struct GNUNET_CADET_PortMessage)}, | 1127 | sizeof (struct GNUNET_CADET_PortMessage)}, |
1129 | {&handle_port_close, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE, | 1128 | {&handle_port_close, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE, |
1130 | sizeof (struct GNUNET_CADET_PortMessage)}, | 1129 | sizeof (struct GNUNET_CADET_PortMessage)}, |
1131 | {&handle_channel_create, NULL, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, | 1130 | {&handle_channel_create, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE, |
1132 | sizeof (struct GNUNET_CADET_ChannelOpenMessageMessage)}, | 1131 | sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)}, |
1133 | {&handle_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, | 1132 | {&handle_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY, |
1134 | sizeof (struct GNUNET_CADET_ChannelDestroyMessage)}, | 1133 | sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)}, |
1135 | {&handle_data, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, 0}, | 1134 | {&handle_data, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, 0}, |
1136 | {&handle_ack, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, | 1135 | {&handle_ack, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, |
1137 | sizeof (struct GNUNET_CADET_LocalAck)}, | 1136 | sizeof (struct GNUNET_CADET_LocalAck)}, |
@@ -1214,17 +1213,17 @@ GML_shutdown (void) | |||
1214 | * Get a channel from a client. | 1213 | * Get a channel from a client. |
1215 | * | 1214 | * |
1216 | * @param c Client to check. | 1215 | * @param c Client to check. |
1217 | * @param chid Channel ID, must be local (> 0x800...). | 1216 | * @param ccn Channel ID, must be local (> 0x800...). |
1218 | * | 1217 | * |
1219 | * @return non-NULL if channel exists in the clients lists | 1218 | * @return non-NULL if channel exists in the clients lists |
1220 | */ | 1219 | */ |
1221 | struct CadetChannel * | 1220 | struct CadetChannel * |
1222 | GML_channel_get (struct CadetClient *c, | 1221 | GML_channel_get (struct CadetClient *c, |
1223 | struct GNUNET_CADET_ClientChannelNumber chid) | 1222 | struct GNUNET_CADET_ClientChannelNumber ccn) |
1224 | { | 1223 | { |
1225 | struct GNUNET_CONTAINER_MultiHashMap32 *map; | 1224 | struct GNUNET_CONTAINER_MultiHashMap32 *map; |
1226 | 1225 | ||
1227 | if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 1226 | if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
1228 | map = c->own_channels; | 1227 | map = c->own_channels; |
1229 | else | 1228 | else |
1230 | map = c->incoming_channels; | 1229 | map = c->incoming_channels; |
@@ -1233,12 +1232,12 @@ GML_channel_get (struct CadetClient *c, | |||
1233 | { | 1232 | { |
1234 | GNUNET_break (0); | 1233 | GNUNET_break (0); |
1235 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1234 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1236 | "Client %s does no t have a valid map for CHID %X\n", | 1235 | "Client %s does no t have a valid map for CCN %X\n", |
1237 | GML_2s (c), chid); | 1236 | GML_2s (c), ccn); |
1238 | return NULL; | 1237 | return NULL; |
1239 | } | 1238 | } |
1240 | return GNUNET_CONTAINER_multihashmap32_get (map, | 1239 | return GNUNET_CONTAINER_multihashmap32_get (map, |
1241 | chid.channel_of_client); | 1240 | ccn.channel_of_client); |
1242 | } | 1241 | } |
1243 | 1242 | ||
1244 | 1243 | ||
@@ -1246,22 +1245,22 @@ GML_channel_get (struct CadetClient *c, | |||
1246 | * Add a channel to a client | 1245 | * Add a channel to a client |
1247 | * | 1246 | * |
1248 | * @param client Client. | 1247 | * @param client Client. |
1249 | * @param chid Channel ID. | 1248 | * @param ccn Channel ID. |
1250 | * @param ch Channel. | 1249 | * @param ch Channel. |
1251 | */ | 1250 | */ |
1252 | void | 1251 | void |
1253 | GML_channel_add (struct CadetClient *client, | 1252 | GML_channel_add (struct CadetClient *client, |
1254 | struct GNUNET_CADET_ClientChannelNumber chid, | 1253 | struct GNUNET_CADET_ClientChannelNumber ccn, |
1255 | struct CadetChannel *ch) | 1254 | struct CadetChannel *ch) |
1256 | { | 1255 | { |
1257 | if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 1256 | if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
1258 | GNUNET_CONTAINER_multihashmap32_put (client->own_channels, | 1257 | GNUNET_CONTAINER_multihashmap32_put (client->own_channels, |
1259 | chid.channel_of_client, | 1258 | ccn.channel_of_client, |
1260 | ch, | 1259 | ch, |
1261 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1260 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
1262 | else | 1261 | else |
1263 | GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, | 1262 | GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, |
1264 | chid.channel_of_client, | 1263 | ccn.channel_of_client, |
1265 | ch, | 1264 | ch, |
1266 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1265 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
1267 | } | 1266 | } |
@@ -1271,21 +1270,21 @@ GML_channel_add (struct CadetClient *client, | |||
1271 | * Remove a channel from a client. | 1270 | * Remove a channel from a client. |
1272 | * | 1271 | * |
1273 | * @param client Client. | 1272 | * @param client Client. |
1274 | * @param chid Channel ID. | 1273 | * @param ccn Channel ID. |
1275 | * @param ch Channel. | 1274 | * @param ch Channel. |
1276 | */ | 1275 | */ |
1277 | void | 1276 | void |
1278 | GML_channel_remove (struct CadetClient *client, | 1277 | GML_channel_remove (struct CadetClient *client, |
1279 | struct GNUNET_CADET_ClientChannelNumber chid, | 1278 | struct GNUNET_CADET_ClientChannelNumber ccn, |
1280 | struct CadetChannel *ch) | 1279 | struct CadetChannel *ch) |
1281 | { | 1280 | { |
1282 | if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 1281 | if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
1283 | GNUNET_CONTAINER_multihashmap32_remove (client->own_channels, | 1282 | GNUNET_CONTAINER_multihashmap32_remove (client->own_channels, |
1284 | chid.channel_of_client, | 1283 | ccn.channel_of_client, |
1285 | ch); | 1284 | ch); |
1286 | else | 1285 | else |
1287 | GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels, | 1286 | GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels, |
1288 | chid.channel_of_client, | 1287 | ccn.channel_of_client, |
1289 | ch); | 1288 | ch); |
1290 | } | 1289 | } |
1291 | 1290 | ||
@@ -1298,27 +1297,27 @@ GML_channel_remove (struct CadetClient *client, | |||
1298 | * @return LID of a channel free to use. | 1297 | * @return LID of a channel free to use. |
1299 | */ | 1298 | */ |
1300 | struct GNUNET_CADET_ClientChannelNumber | 1299 | struct GNUNET_CADET_ClientChannelNumber |
1301 | GML_get_next_chid (struct CadetClient *c) | 1300 | GML_get_next_ccn (struct CadetClient *c) |
1302 | { | 1301 | { |
1303 | struct GNUNET_CADET_ClientChannelNumber chid; | 1302 | struct GNUNET_CADET_ClientChannelNumber ccn; |
1304 | 1303 | ||
1305 | while (NULL != GML_channel_get (c, | 1304 | while (NULL != GML_channel_get (c, |
1306 | c->next_chid)) | 1305 | c->next_ccn)) |
1307 | { | 1306 | { |
1308 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1307 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1309 | "Channel %u exists...\n", | 1308 | "Channel %u exists...\n", |
1310 | c->next_chid); | 1309 | c->next_ccn); |
1311 | c->next_chid.channel_of_client | 1310 | c->next_ccn.channel_of_client |
1312 | = htonl (1 + (ntohl (c->next_chid.channel_of_client))); | 1311 | = htonl (1 + (ntohl (c->next_ccn.channel_of_client))); |
1313 | if (ntohl (c->next_chid.channel_of_client) >= | 1312 | if (ntohl (c->next_ccn.channel_of_client) >= |
1314 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | 1313 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) |
1315 | c->next_chid.channel_of_client = htonl (0); | 1314 | c->next_ccn.channel_of_client = htonl (0); |
1316 | } | 1315 | } |
1317 | chid = c->next_chid; | 1316 | ccn = c->next_ccn; |
1318 | c->next_chid.channel_of_client | 1317 | c->next_ccn.channel_of_client |
1319 | = htonl (1 + (ntohl (c->next_chid.channel_of_client))); | 1318 | = htonl (1 + (ntohl (c->next_ccn.channel_of_client))); |
1320 | 1319 | ||
1321 | return chid; | 1320 | return ccn; |
1322 | } | 1321 | } |
1323 | 1322 | ||
1324 | 1323 | ||
@@ -1391,24 +1390,24 @@ GML_client_delete_channel (struct CadetClient *c, | |||
1391 | * If the client was already allowed to send data, do nothing. | 1390 | * If the client was already allowed to send data, do nothing. |
1392 | * | 1391 | * |
1393 | * @param c Client to whom send the ACK. | 1392 | * @param c Client to whom send the ACK. |
1394 | * @param id Channel ID to use | 1393 | * @param ccn Channel ID to use |
1395 | */ | 1394 | */ |
1396 | void | 1395 | void |
1397 | GML_send_ack (struct CadetClient *c, | 1396 | GML_send_ack (struct CadetClient *c, |
1398 | struct GNUNET_CADET_ClientChannelNumber id) | 1397 | struct GNUNET_CADET_ClientChannelNumber ccn) |
1399 | { | 1398 | { |
1400 | struct GNUNET_CADET_LocalAck msg; | 1399 | struct GNUNET_CADET_LocalAck msg; |
1401 | 1400 | ||
1402 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1401 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1403 | "send local %s ack on %X towards %p\n", | 1402 | "send local %s ack on %X towards %p\n", |
1404 | ntohl (id.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | 1403 | ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI |
1405 | ? "FWD" : "BCK", | 1404 | ? "FWD" : "BCK", |
1406 | ntohl (id.channel_of_client), | 1405 | ntohl (ccn.channel_of_client), |
1407 | c); | 1406 | c); |
1408 | 1407 | ||
1409 | msg.header.size = htons (sizeof (msg)); | 1408 | msg.header.size = htons (sizeof (msg)); |
1410 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); | 1409 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); |
1411 | msg.channel_id = id; | 1410 | msg.ccn = ccn; |
1412 | GNUNET_SERVER_notification_context_unicast (nc, | 1411 | GNUNET_SERVER_notification_context_unicast (nc, |
1413 | c->handle, | 1412 | c->handle, |
1414 | &msg.header, | 1413 | &msg.header, |
@@ -1422,23 +1421,23 @@ GML_send_ack (struct CadetClient *c, | |||
1422 | * Notify the client that a new incoming channel was created. | 1421 | * Notify the client that a new incoming channel was created. |
1423 | * | 1422 | * |
1424 | * @param c Client to notify. | 1423 | * @param c Client to notify. |
1425 | * @param id Channel ID. | 1424 | * @param ccn Channel ID. |
1426 | * @param port Channel's destination port. | 1425 | * @param port Channel's destination port. |
1427 | * @param opt Options (bit array). | 1426 | * @param opt Options (bit array). |
1428 | * @param peer Origin peer. | 1427 | * @param peer Origin peer. |
1429 | */ | 1428 | */ |
1430 | void | 1429 | void |
1431 | GML_send_channel_create (struct CadetClient *c, | 1430 | GML_send_channel_create (struct CadetClient *c, |
1432 | struct GNUNET_CADET_ClientChannelNumber id, | 1431 | struct GNUNET_CADET_ClientChannelNumber ccn, |
1433 | const struct GNUNET_HashCode *port, | 1432 | const struct GNUNET_HashCode *port, |
1434 | uint32_t opt, | 1433 | uint32_t opt, |
1435 | const struct GNUNET_PeerIdentity *peer) | 1434 | const struct GNUNET_PeerIdentity *peer) |
1436 | { | 1435 | { |
1437 | struct GNUNET_CADET_ChannelOpenMessageMessage msg; | 1436 | struct GNUNET_CADET_LocalChannelCreateMessage msg; |
1438 | 1437 | ||
1439 | msg.header.size = htons (sizeof (msg)); | 1438 | msg.header.size = htons (sizeof (msg)); |
1440 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 1439 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); |
1441 | msg.channel_id = id; | 1440 | msg.ccn = ccn; |
1442 | msg.port = *port; | 1441 | msg.port = *port; |
1443 | msg.opt = htonl (opt); | 1442 | msg.opt = htonl (opt); |
1444 | msg.peer = *peer; | 1443 | msg.peer = *peer; |
@@ -1451,22 +1450,22 @@ GML_send_channel_create (struct CadetClient *c, | |||
1451 | * Build a local channel NACK message and send it to a local client. | 1450 | * Build a local channel NACK message and send it to a local client. |
1452 | * | 1451 | * |
1453 | * @param c Client to whom send the NACK. | 1452 | * @param c Client to whom send the NACK. |
1454 | * @param id Channel ID to use | 1453 | * @param ccn Channel ID to use |
1455 | */ | 1454 | */ |
1456 | void | 1455 | void |
1457 | GML_send_channel_nack (struct CadetClient *c, | 1456 | GML_send_channel_nack (struct CadetClient *c, |
1458 | struct GNUNET_CADET_ClientChannelNumber id) | 1457 | struct GNUNET_CADET_ClientChannelNumber ccn) |
1459 | { | 1458 | { |
1460 | struct GNUNET_CADET_LocalAck msg; | 1459 | struct GNUNET_CADET_LocalAck msg; |
1461 | 1460 | ||
1462 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1461 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1463 | "send local nack on %X towards %p\n", | 1462 | "send local nack on %X towards %p\n", |
1464 | ntohl (id.channel_of_client), | 1463 | ntohl (ccn.channel_of_client), |
1465 | c); | 1464 | c); |
1466 | 1465 | ||
1467 | msg.header.size = htons (sizeof (msg)); | 1466 | msg.header.size = htons (sizeof (msg)); |
1468 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED); | 1467 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED); |
1469 | msg.channel_id = id; | 1468 | msg.ccn = ccn; |
1470 | GNUNET_SERVER_notification_context_unicast (nc, | 1469 | GNUNET_SERVER_notification_context_unicast (nc, |
1471 | c->handle, | 1470 | c->handle, |
1472 | &msg.header, | 1471 | &msg.header, |
@@ -1478,13 +1477,13 @@ GML_send_channel_nack (struct CadetClient *c, | |||
1478 | * Notify a client that a channel is no longer valid. | 1477 | * Notify a client that a channel is no longer valid. |
1479 | * | 1478 | * |
1480 | * @param c Client. | 1479 | * @param c Client. |
1481 | * @param id ID of the channel that is destroyed. | 1480 | * @param ccn ID of the channel that is destroyed. |
1482 | */ | 1481 | */ |
1483 | void | 1482 | void |
1484 | GML_send_channel_destroy (struct CadetClient *c, | 1483 | GML_send_channel_destroy (struct CadetClient *c, |
1485 | struct GNUNET_CADET_ClientChannelNumber id) | 1484 | struct GNUNET_CADET_ClientChannelNumber ccn) |
1486 | { | 1485 | { |
1487 | struct GNUNET_CADET_ChannelDestroyMessage msg; | 1486 | struct GNUNET_CADET_LocalChannelDestroyMessage msg; |
1488 | 1487 | ||
1489 | if (NULL == c) | 1488 | if (NULL == c) |
1490 | { | 1489 | { |
@@ -1494,8 +1493,8 @@ GML_send_channel_destroy (struct CadetClient *c, | |||
1494 | if (GNUNET_YES == c->shutting_down) | 1493 | if (GNUNET_YES == c->shutting_down) |
1495 | return; | 1494 | return; |
1496 | msg.header.size = htons (sizeof (msg)); | 1495 | msg.header.size = htons (sizeof (msg)); |
1497 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | 1496 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY); |
1498 | msg.channel_id = id; | 1497 | msg.ccn = ccn; |
1499 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | 1498 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, |
1500 | &msg.header, GNUNET_NO); | 1499 | &msg.header, GNUNET_NO); |
1501 | } | 1500 | } |
@@ -1506,12 +1505,12 @@ GML_send_channel_destroy (struct CadetClient *c, | |||
1506 | * | 1505 | * |
1507 | * @param c Client to send to. | 1506 | * @param c Client to send to. |
1508 | * @param msg Message to modify and send. | 1507 | * @param msg Message to modify and send. |
1509 | * @param id Channel ID to use (c can be both owner and client). | 1508 | * @param ccn Channel ID to use (c can be both owner and client). |
1510 | */ | 1509 | */ |
1511 | void | 1510 | void |
1512 | GML_send_data (struct CadetClient *c, | 1511 | GML_send_data (struct CadetClient *c, |
1513 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | 1512 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, |
1514 | struct GNUNET_CADET_ClientChannelNumber id) | 1513 | struct GNUNET_CADET_ClientChannelNumber ccn) |
1515 | { | 1514 | { |
1516 | struct GNUNET_CADET_LocalData *copy; | 1515 | struct GNUNET_CADET_LocalData *copy; |
1517 | uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_CADET_ChannelAppDataMessage); | 1516 | uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_CADET_ChannelAppDataMessage); |
@@ -1531,7 +1530,7 @@ GML_send_data (struct CadetClient *c, | |||
1531 | GNUNET_memcpy (©[1], &msg[1], size); | 1530 | GNUNET_memcpy (©[1], &msg[1], size); |
1532 | copy->header.size = htons (sizeof (struct GNUNET_CADET_LocalData) + size); | 1531 | copy->header.size = htons (sizeof (struct GNUNET_CADET_LocalData) + size); |
1533 | copy->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); | 1532 | copy->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); |
1534 | copy->id = id; | 1533 | copy->ccn = ccn; |
1535 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | 1534 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, |
1536 | ©->header, GNUNET_NO); | 1535 | ©->header, GNUNET_NO); |
1537 | } | 1536 | } |
diff --git a/src/cadet/gnunet-service-cadet_local.h b/src/cadet/gnunet-service-cadet_local.h index bf691f9c3..113c2f489 100644 --- a/src/cadet/gnunet-service-cadet_local.h +++ b/src/cadet/gnunet-service-cadet_local.h | |||
@@ -75,36 +75,36 @@ GML_shutdown (void); | |||
75 | * Get a channel from a client. | 75 | * Get a channel from a client. |
76 | * | 76 | * |
77 | * @param c Client to check. | 77 | * @param c Client to check. |
78 | * @param chid Channel ID, must be local (> 0x800...). | 78 | * @param ccn Channel ID, must be local (> 0x800...). |
79 | * | 79 | * |
80 | * @return non-NULL if channel exists in the clients lists | 80 | * @return non-NULL if channel exists in the clients lists |
81 | */ | 81 | */ |
82 | struct CadetChannel * | 82 | struct CadetChannel * |
83 | GML_channel_get (struct CadetClient *c, | 83 | GML_channel_get (struct CadetClient *c, |
84 | struct GNUNET_CADET_ClientChannelNumber chid); | 84 | struct GNUNET_CADET_ClientChannelNumber ccn); |
85 | 85 | ||
86 | /** | 86 | /** |
87 | * Add a channel to a client | 87 | * Add a channel to a client |
88 | * | 88 | * |
89 | * @param client Client. | 89 | * @param client Client. |
90 | * @param chid Channel ID. | 90 | * @param ccn Channel ID. |
91 | * @param ch Channel. | 91 | * @param ch Channel. |
92 | */ | 92 | */ |
93 | void | 93 | void |
94 | GML_channel_add (struct CadetClient *client, | 94 | GML_channel_add (struct CadetClient *client, |
95 | struct GNUNET_CADET_ClientChannelNumber chid, | 95 | struct GNUNET_CADET_ClientChannelNumber ccn, |
96 | struct CadetChannel *ch); | 96 | struct CadetChannel *ch); |
97 | 97 | ||
98 | /** | 98 | /** |
99 | * Remove a channel from a client | 99 | * Remove a channel from a client |
100 | * | 100 | * |
101 | * @param client Client. | 101 | * @param client Client. |
102 | * @param chid Channel ID. | 102 | * @param ccn Channel ID. |
103 | * @param ch Channel. | 103 | * @param ch Channel. |
104 | */ | 104 | */ |
105 | void | 105 | void |
106 | GML_channel_remove (struct CadetClient *client, | 106 | GML_channel_remove (struct CadetClient *client, |
107 | struct GNUNET_CADET_ClientChannelNumber chid, | 107 | struct GNUNET_CADET_ClientChannelNumber ccn, |
108 | struct CadetChannel *ch); | 108 | struct CadetChannel *ch); |
109 | 109 | ||
110 | /** | 110 | /** |
@@ -115,7 +115,7 @@ GML_channel_remove (struct CadetClient *client, | |||
115 | * @return LID of a channel free to use. | 115 | * @return LID of a channel free to use. |
116 | */ | 116 | */ |
117 | struct GNUNET_CADET_ClientChannelNumber | 117 | struct GNUNET_CADET_ClientChannelNumber |
118 | GML_get_next_chid (struct CadetClient *c); | 118 | GML_get_next_ccn (struct CadetClient *c); |
119 | 119 | ||
120 | /** | 120 | /** |
121 | * Check if client has registered with the service and has not disconnected | 121 | * Check if client has registered with the service and has not disconnected |
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c index 3f8b7bbb8..fa3f2be80 100644 --- a/src/cadet/gnunet-service-cadet_peer.c +++ b/src/cadet/gnunet-service-cadet_peer.c | |||
@@ -490,7 +490,7 @@ handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg | |||
490 | * @param msg Message itself. | 490 | * @param msg Message itself. |
491 | */ | 491 | */ |
492 | static void | 492 | static void |
493 | handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionCreateMessageAckMessage *msg) | 493 | handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) |
494 | { | 494 | { |
495 | struct CadetPeer *peer = cls; | 495 | struct CadetPeer *peer = cls; |
496 | GCC_handle_confirm (peer, msg); | 496 | GCC_handle_confirm (peer, msg); |
@@ -628,7 +628,7 @@ connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c) | |||
628 | NULL), | 628 | NULL), |
629 | GNUNET_MQ_hd_fixed_size (confirm, | 629 | GNUNET_MQ_hd_fixed_size (confirm, |
630 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK, | 630 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK, |
631 | struct GNUNET_CADET_ConnectionCreateMessageAckMessage, | 631 | struct GNUNET_CADET_ConnectionCreateAckMessage, |
632 | NULL), | 632 | NULL), |
633 | GNUNET_MQ_hd_fixed_size (broken, | 633 | GNUNET_MQ_hd_fixed_size (broken, |
634 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, | 634 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, |
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index 65775ce66..3b21f4107 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013 GNUnet e.V. | 3 | Copyright (C) 2013, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -17,16 +17,17 @@ | |||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | 20 | /** | |
21 | * @file cadet/gnunet-service-cadet_tunnel.c | ||
22 | * @brief logical links between CADET clients | ||
23 | * @author Bartlomiej Polot | ||
24 | */ | ||
21 | #include "platform.h" | 25 | #include "platform.h" |
22 | #include "gnunet_util_lib.h" | 26 | #include "gnunet_util_lib.h" |
23 | |||
24 | #include "gnunet_signatures.h" | 27 | #include "gnunet_signatures.h" |
25 | #include "gnunet_statistics_service.h" | 28 | #include "gnunet_statistics_service.h" |
26 | |||
27 | #include "cadet_protocol.h" | 29 | #include "cadet_protocol.h" |
28 | #include "cadet_path.h" | 30 | #include "cadet_path.h" |
29 | |||
30 | #include "gnunet-service-cadet_tunnel.h" | 31 | #include "gnunet-service-cadet_tunnel.h" |
31 | #include "gnunet-service-cadet_connection.h" | 32 | #include "gnunet-service-cadet_connection.h" |
32 | #include "gnunet-service-cadet_channel.h" | 33 | #include "gnunet-service-cadet_channel.h" |
@@ -310,7 +311,7 @@ struct CadetTunnel | |||
310 | /** | 311 | /** |
311 | * Channel ID for the next created channel. | 312 | * Channel ID for the next created channel. |
312 | */ | 313 | */ |
313 | struct GNUNET_CADET_ChannelTunnelNumber next_chid; | 314 | struct GNUNET_CADET_ChannelTunnelNumber next_ctn; |
314 | 315 | ||
315 | /** | 316 | /** |
316 | * Destroy flag: if true, destroy on last message. | 317 | * Destroy flag: if true, destroy on last message. |
@@ -1562,7 +1563,7 @@ send_channel_destroy (struct CadetTunnel *t, | |||
1562 | 1563 | ||
1563 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | 1564 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); |
1564 | msg.header.size = htons (sizeof (msg)); | 1565 | msg.header.size = htons (sizeof (msg)); |
1565 | msg.chid = gid; | 1566 | msg.ctn = gid; |
1566 | 1567 | ||
1567 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1568 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1568 | "WARNING destroying unknown channel %u on tunnel %s\n", | 1569 | "WARNING destroying unknown channel %u on tunnel %s\n", |
@@ -1608,7 +1609,7 @@ handle_data (struct CadetTunnel *t, | |||
1608 | 1609 | ||
1609 | 1610 | ||
1610 | /* Check channel */ | 1611 | /* Check channel */ |
1611 | ch = GCT_get_channel (t, msg->chid); | 1612 | ch = GCT_get_channel (t, msg->ctn); |
1612 | if (NULL == ch) | 1613 | if (NULL == ch) |
1613 | { | 1614 | { |
1614 | GNUNET_STATISTICS_update (stats, | 1615 | GNUNET_STATISTICS_update (stats, |
@@ -1617,8 +1618,8 @@ handle_data (struct CadetTunnel *t, | |||
1617 | GNUNET_NO); | 1618 | GNUNET_NO); |
1618 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1619 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1619 | "channel 0x%X unknown\n", | 1620 | "channel 0x%X unknown\n", |
1620 | ntohl (msg->chid.cn)); | 1621 | ntohl (msg->ctn.cn)); |
1621 | send_channel_destroy (t, msg->chid); | 1622 | send_channel_destroy (t, msg->ctn); |
1622 | return; | 1623 | return; |
1623 | } | 1624 | } |
1624 | 1625 | ||
@@ -1653,13 +1654,13 @@ handle_data_ack (struct CadetTunnel *t, | |||
1653 | } | 1654 | } |
1654 | 1655 | ||
1655 | /* Check channel */ | 1656 | /* Check channel */ |
1656 | ch = GCT_get_channel (t, msg->chid); | 1657 | ch = GCT_get_channel (t, msg->ctn); |
1657 | if (NULL == ch) | 1658 | if (NULL == ch) |
1658 | { | 1659 | { |
1659 | GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", | 1660 | GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", |
1660 | 1, GNUNET_NO); | 1661 | 1, GNUNET_NO); |
1661 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | 1662 | LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", |
1662 | ntohl (msg->chid.cn)); | 1663 | ntohl (msg->ctn.cn)); |
1663 | return; | 1664 | return; |
1664 | } | 1665 | } |
1665 | 1666 | ||
@@ -1689,7 +1690,7 @@ handle_ch_create (struct CadetTunnel *t, | |||
1689 | } | 1690 | } |
1690 | 1691 | ||
1691 | /* Check channel */ | 1692 | /* Check channel */ |
1692 | ch = GCT_get_channel (t, msg->chid); | 1693 | ch = GCT_get_channel (t, msg->ctn); |
1693 | if (NULL != ch && ! GCT_is_loopback (t)) | 1694 | if (NULL != ch && ! GCT_is_loopback (t)) |
1694 | { | 1695 | { |
1695 | /* Probably a retransmission, safe to ignore */ | 1696 | /* Probably a retransmission, safe to ignore */ |
@@ -1724,14 +1725,14 @@ handle_ch_nack (struct CadetTunnel *t, | |||
1724 | } | 1725 | } |
1725 | 1726 | ||
1726 | /* Check channel */ | 1727 | /* Check channel */ |
1727 | ch = GCT_get_channel (t, msg->chid); | 1728 | ch = GCT_get_channel (t, msg->ctn); |
1728 | if (NULL == ch) | 1729 | if (NULL == ch) |
1729 | { | 1730 | { |
1730 | GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel", | 1731 | GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel", |
1731 | 1, GNUNET_NO); | 1732 | 1, GNUNET_NO); |
1732 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1733 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1733 | "WARNING channel %u unknown\n", | 1734 | "WARNING channel %u unknown\n", |
1734 | ntohl (msg->chid.cn)); | 1735 | ntohl (msg->ctn.cn)); |
1735 | return; | 1736 | return; |
1736 | } | 1737 | } |
1737 | 1738 | ||
@@ -1766,7 +1767,7 @@ handle_ch_ack (struct CadetTunnel *t, | |||
1766 | } | 1767 | } |
1767 | 1768 | ||
1768 | /* Check channel */ | 1769 | /* Check channel */ |
1769 | ch = GCT_get_channel (t, msg->chid); | 1770 | ch = GCT_get_channel (t, msg->ctn); |
1770 | if (NULL == ch) | 1771 | if (NULL == ch) |
1771 | { | 1772 | { |
1772 | GNUNET_STATISTICS_update (stats, | 1773 | GNUNET_STATISTICS_update (stats, |
@@ -1775,7 +1776,7 @@ handle_ch_ack (struct CadetTunnel *t, | |||
1775 | GNUNET_NO); | 1776 | GNUNET_NO); |
1776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1777 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1777 | "WARNING channel %u unknown\n", | 1778 | "WARNING channel %u unknown\n", |
1778 | ntohl (msg->chid.cn)); | 1779 | ntohl (msg->ctn.cn)); |
1779 | return; | 1780 | return; |
1780 | } | 1781 | } |
1781 | 1782 | ||
@@ -1810,7 +1811,7 @@ handle_ch_destroy (struct CadetTunnel *t, | |||
1810 | } | 1811 | } |
1811 | 1812 | ||
1812 | /* Check channel */ | 1813 | /* Check channel */ |
1813 | ch = GCT_get_channel (t, msg->chid); | 1814 | ch = GCT_get_channel (t, msg->ctn); |
1814 | if (NULL == ch) | 1815 | if (NULL == ch) |
1815 | { | 1816 | { |
1816 | /* Probably a retransmission, safe to ignore */ | 1817 | /* Probably a retransmission, safe to ignore */ |
@@ -2203,7 +2204,7 @@ GCT_new (struct CadetPeer *destination) | |||
2203 | struct CadetTunnel *t; | 2204 | struct CadetTunnel *t; |
2204 | 2205 | ||
2205 | t = GNUNET_new (struct CadetTunnel); | 2206 | t = GNUNET_new (struct CadetTunnel); |
2206 | t->next_chid.cn = 0; | 2207 | t->next_ctn.cn = 0; |
2207 | t->peer = destination; | 2208 | t->peer = destination; |
2208 | 2209 | ||
2209 | if (GNUNET_OK != | 2210 | if (GNUNET_OK != |
@@ -2509,13 +2510,13 @@ GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch) | |||
2509 | * Search for a channel by global ID. | 2510 | * Search for a channel by global ID. |
2510 | * | 2511 | * |
2511 | * @param t Tunnel containing the channel. | 2512 | * @param t Tunnel containing the channel. |
2512 | * @param chid Public channel number. | 2513 | * @param ctn Public channel number. |
2513 | * | 2514 | * |
2514 | * @return channel handler, NULL if doesn't exist | 2515 | * @return channel handler, NULL if doesn't exist |
2515 | */ | 2516 | */ |
2516 | struct CadetChannel * | 2517 | struct CadetChannel * |
2517 | GCT_get_channel (struct CadetTunnel *t, | 2518 | GCT_get_channel (struct CadetTunnel *t, |
2518 | struct GNUNET_CADET_ChannelTunnelNumber chid) | 2519 | struct GNUNET_CADET_ChannelTunnelNumber ctn) |
2519 | { | 2520 | { |
2520 | struct CadetTChannel *iter; | 2521 | struct CadetTChannel *iter; |
2521 | 2522 | ||
@@ -2524,7 +2525,7 @@ GCT_get_channel (struct CadetTunnel *t, | |||
2524 | 2525 | ||
2525 | for (iter = t->channel_head; NULL != iter; iter = iter->next) | 2526 | for (iter = t->channel_head; NULL != iter; iter = iter->next) |
2526 | { | 2527 | { |
2527 | if (GCCH_get_id (iter->ch).cn == chid.cn) | 2528 | if (GCCH_get_id (iter->ch).cn == ctn.cn) |
2528 | break; | 2529 | break; |
2529 | } | 2530 | } |
2530 | 2531 | ||
@@ -2972,9 +2973,9 @@ GCT_get_destination (struct CadetTunnel *t) | |||
2972 | * @return GID of a channel free to use. | 2973 | * @return GID of a channel free to use. |
2973 | */ | 2974 | */ |
2974 | struct GNUNET_CADET_ChannelTunnelNumber | 2975 | struct GNUNET_CADET_ChannelTunnelNumber |
2975 | GCT_get_next_chid (struct CadetTunnel *t) | 2976 | GCT_get_next_ctn (struct CadetTunnel *t) |
2976 | { | 2977 | { |
2977 | struct GNUNET_CADET_ChannelTunnelNumber chid; | 2978 | struct GNUNET_CADET_ChannelTunnelNumber ctn; |
2978 | struct GNUNET_CADET_ChannelTunnelNumber mask; | 2979 | struct GNUNET_CADET_ChannelTunnelNumber mask; |
2979 | int result; | 2980 | int result; |
2980 | 2981 | ||
@@ -2987,21 +2988,21 @@ GCT_get_next_chid (struct CadetTunnel *t) | |||
2987 | mask.cn = htonl (0x40000000); | 2988 | mask.cn = htonl (0x40000000); |
2988 | else | 2989 | else |
2989 | mask.cn = 0x0; | 2990 | mask.cn = 0x0; |
2990 | t->next_chid.cn |= mask.cn; | 2991 | t->next_ctn.cn |= mask.cn; |
2991 | 2992 | ||
2992 | while (NULL != GCT_get_channel (t, t->next_chid)) | 2993 | while (NULL != GCT_get_channel (t, t->next_ctn)) |
2993 | { | 2994 | { |
2994 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2995 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2995 | "Channel %u exists...\n", | 2996 | "Channel %u exists...\n", |
2996 | t->next_chid.cn); | 2997 | t->next_ctn.cn); |
2997 | t->next_chid.cn = htonl ((ntohl (t->next_chid.cn) + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | 2998 | t->next_ctn.cn = htonl ((ntohl (t->next_ctn.cn) + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); |
2998 | t->next_chid.cn |= mask.cn; | 2999 | t->next_ctn.cn |= mask.cn; |
2999 | } | 3000 | } |
3000 | chid = t->next_chid; | 3001 | ctn = t->next_ctn; |
3001 | t->next_chid.cn = (t->next_chid.cn + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; | 3002 | t->next_ctn.cn = (t->next_ctn.cn + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; |
3002 | t->next_chid.cn |= mask.cn; | 3003 | t->next_ctn.cn |= mask.cn; |
3003 | 3004 | ||
3004 | return chid; | 3005 | return ctn; |
3005 | } | 3006 | } |
3006 | 3007 | ||
3007 | 3008 | ||
diff --git a/src/cadet/gnunet-service-cadet_tunnel.h b/src/cadet/gnunet-service-cadet_tunnel.h index c10815a3b..0abdc02ce 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.h +++ b/src/cadet/gnunet-service-cadet_tunnel.h | |||
@@ -286,12 +286,12 @@ GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch); | |||
286 | * Search for a channel by global ID. | 286 | * Search for a channel by global ID. |
287 | * | 287 | * |
288 | * @param t Tunnel containing the channel. | 288 | * @param t Tunnel containing the channel. |
289 | * @param chid Public channel number. | 289 | * @param ctn Public channel number. |
290 | * | 290 | * |
291 | * @return channel handler, NULL if doesn't exist | 291 | * @return channel handler, NULL if doesn't exist |
292 | */ | 292 | */ |
293 | struct CadetChannel * | 293 | struct CadetChannel * |
294 | GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber chid); | 294 | GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn); |
295 | 295 | ||
296 | 296 | ||
297 | /** | 297 | /** |
@@ -428,7 +428,7 @@ GCT_get_destination (struct CadetTunnel *t); | |||
428 | * @return ID of a channel free to use. | 428 | * @return ID of a channel free to use. |
429 | */ | 429 | */ |
430 | struct GNUNET_CADET_ChannelTunnelNumber | 430 | struct GNUNET_CADET_ChannelTunnelNumber |
431 | GCT_get_next_chid (struct CadetTunnel *t); | 431 | GCT_get_next_ctn (struct CadetTunnel *t); |
432 | 432 | ||
433 | 433 | ||
434 | /** | 434 | /** |
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c index cf18b8a90..3a1042eba 100644 --- a/src/cadet/test_cadet.c +++ b/src/cadet/test_cadet.c | |||
@@ -527,7 +527,7 @@ data_task (void *cls) | |||
527 | * @param size Size of the buffer we have. | 527 | * @param size Size of the buffer we have. |
528 | * @param buf Buffer to copy data to. | 528 | * @param buf Buffer to copy data to. |
529 | */ | 529 | */ |
530 | size_t | 530 | static size_t |
531 | tmt_rdy (void *cls, size_t size, void *buf) | 531 | tmt_rdy (void *cls, size_t size, void *buf) |
532 | { | 532 | { |
533 | struct GNUNET_MessageHeader *msg = buf; | 533 | struct GNUNET_MessageHeader *msg = buf; |
@@ -536,7 +536,9 @@ tmt_rdy (void *cls, size_t size, void *buf) | |||
536 | long id = (long) cls; | 536 | long id = (long) cls; |
537 | unsigned int counter; | 537 | unsigned int counter; |
538 | 538 | ||
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tmt_rdy on %ld, filling buffer\n", id); | 539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
540 | "tmt_rdy on %ld, filling buffer\n", | ||
541 | id); | ||
540 | if (0 == id) | 542 | if (0 == id) |
541 | th = NULL; | 543 | th = NULL; |
542 | else if ((peers_requested - 1) == id) | 544 | else if ((peers_requested - 1) == id) |
@@ -545,7 +547,9 @@ tmt_rdy (void *cls, size_t size, void *buf) | |||
545 | GNUNET_assert (0); | 547 | GNUNET_assert (0); |
546 | counter = get_expected_target () == id ? ack_sent : data_sent; | 548 | counter = get_expected_target () == id ? ack_sent : data_sent; |
547 | msg_size = size_payload + counter; | 549 | msg_size = size_payload + counter; |
548 | if (size < msg_size || NULL == buf) | 550 | GNUNET_assert (msg_size > sizeof (struct GNUNET_MessageHeader)); |
551 | if ( (size < msg_size) || | ||
552 | (NULL == buf) ) | ||
549 | { | 553 | { |
550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 554 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
551 | "size %u, buf %p, data_sent %u, ack_received %u\n", | 555 | "size %u, buf %p, data_sent %u, ack_received %u\n", |
@@ -559,17 +563,20 @@ tmt_rdy (void *cls, size_t size, void *buf) | |||
559 | return 0; | 563 | return 0; |
560 | } | 564 | } |
561 | msg->size = htons (msg_size); | 565 | msg->size = htons (msg_size); |
562 | msg->type = htons (1); | 566 | msg->type = htons (GNUNET_MESSAGE_TYPE_DUMMY); |
563 | data = (uint32_t *) &msg[1]; | 567 | data = (uint32_t *) &msg[1]; |
564 | *data = htonl (counter); | 568 | *data = htonl (counter); |
565 | if (GNUNET_NO == initialized) | 569 | if (GNUNET_NO == initialized) |
566 | { | 570 | { |
567 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending initializer\n"); | 571 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
572 | "sending initializer\n"); | ||
568 | msg_size = size_payload + 1000; | 573 | msg_size = size_payload + 1000; |
569 | if (SPEED_ACK == test) | 574 | msg->size = htons (msg_size); |
575 | if (SPEED_ACK == test) | ||
570 | data_sent++; | 576 | data_sent++; |
571 | } | 577 | } |
572 | else if (SPEED == test || SPEED_ACK == test) | 578 | else if ( (SPEED == test) || |
579 | (SPEED_ACK == test) ) | ||
573 | { | 580 | { |
574 | if (get_expected_target() == id) | 581 | if (get_expected_target() == id) |
575 | ack_sent++; | 582 | ack_sent++; |
@@ -580,9 +587,11 @@ tmt_rdy (void *cls, size_t size, void *buf) | |||
580 | " Sent message %u size %u\n", | 587 | " Sent message %u size %u\n", |
581 | counter, | 588 | counter, |
582 | (unsigned int) msg_size); | 589 | (unsigned int) msg_size); |
583 | if (data_sent < TOTAL_PACKETS && SPEED == test) | 590 | if ( (data_sent < TOTAL_PACKETS) && |
591 | (SPEED == test) ) | ||
584 | { | 592 | { |
585 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Scheduling message %d\n", | 593 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
594 | " Scheduling message %d\n", | ||
586 | counter + 1); | 595 | counter + 1); |
587 | data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL); | 596 | data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL); |
588 | } | 597 | } |
@@ -595,15 +604,16 @@ tmt_rdy (void *cls, size_t size, void *buf) | |||
595 | /** | 604 | /** |
596 | * Function is called whenever a message is received. | 605 | * Function is called whenever a message is received. |
597 | * | 606 | * |
598 | * @param cls closure (set from GNUNET_CADET_connect, peer number) | 607 | * @param cls closure (set from GNUNET_CADET_connect(), peer number) |
599 | * @param channel connection to the other end | 608 | * @param channel connection to the other end |
600 | * @param channel_ctx place to store local state associated with the channel | 609 | * @param channel_ctx place to store local state associated with the channel |
601 | * @param message the actual message | 610 | * @param message the actual message |
602 | * @return GNUNET_OK to keep the connection open, | 611 | * @return #GNUNET_OK to keep the connection open, |
603 | * GNUNET_SYSERR to close it (signal serious error) | 612 | * #GNUNET_SYSERR to close it (signal serious error) |
604 | */ | 613 | */ |
605 | int | 614 | static int |
606 | data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | 615 | data_callback (void *cls, |
616 | struct GNUNET_CADET_Channel *channel, | ||
607 | void **channel_ctx, | 617 | void **channel_ctx, |
608 | const struct GNUNET_MessageHeader *message) | 618 | const struct GNUNET_MessageHeader *message) |
609 | { | 619 | { |
@@ -623,7 +633,8 @@ data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | |||
623 | { | 633 | { |
624 | if (NULL != disconnect_task) | 634 | if (NULL != disconnect_task) |
625 | { | 635 | { |
626 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, " reschedule timeout\n"); | 636 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
637 | " reschedule timeout\n"); | ||
627 | GNUNET_SCHEDULER_cancel (disconnect_task); | 638 | GNUNET_SCHEDULER_cancel (disconnect_task); |
628 | disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, | 639 | disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, |
629 | &gather_stats_and_exit, | 640 | &gather_stats_and_exit, |
@@ -746,7 +757,9 @@ data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | |||
746 | * {callback_function, message_type, size_expected} | 757 | * {callback_function, message_type, size_expected} |
747 | */ | 758 | */ |
748 | static struct GNUNET_CADET_MessageHandler handlers[] = { | 759 | static struct GNUNET_CADET_MessageHandler handlers[] = { |
749 | {&data_callback, 1, sizeof (struct GNUNET_MessageHeader)}, | 760 | {&data_callback, |
761 | GNUNET_MESSAGE_TYPE_DUMMY, | ||
762 | sizeof (struct GNUNET_MessageHeader)}, | ||
750 | {NULL, 0, 0} | 763 | {NULL, 0, 0} |
751 | }; | 764 | }; |
752 | 765 | ||
@@ -764,10 +777,11 @@ static struct GNUNET_CADET_MessageHandler handlers[] = { | |||
764 | * (can be NULL -- that's not an error). | 777 | * (can be NULL -- that's not an error). |
765 | */ | 778 | */ |
766 | static void * | 779 | static void * |
767 | incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel, | 780 | incoming_channel (void *cls, |
768 | const struct GNUNET_PeerIdentity *initiator, | 781 | struct GNUNET_CADET_Channel *channel, |
769 | const struct GNUNET_HashCode *port, | 782 | const struct GNUNET_PeerIdentity *initiator, |
770 | enum GNUNET_CADET_ChannelOption options) | 783 | const struct GNUNET_HashCode *port, |
784 | enum GNUNET_CADET_ChannelOption options) | ||
771 | { | 785 | { |
772 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 786 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
773 | "Incoming channel from %s to peer %d:%s\n", | 787 | "Incoming channel from %s to peer %d:%s\n", |
@@ -776,7 +790,16 @@ incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel, | |||
776 | ok++; | 790 | ok++; |
777 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); | 791 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); |
778 | if ((long) cls == peers_requested - 1) | 792 | if ((long) cls == peers_requested - 1) |
793 | { | ||
794 | if (NULL != incoming_ch) | ||
795 | { | ||
796 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
797 | "Duplicate incoming channel for client %lu\n", | ||
798 | (long) cls); | ||
799 | GNUNET_break(0); | ||
800 | } | ||
779 | incoming_ch = channel; | 801 | incoming_ch = channel; |
802 | } | ||
780 | else | 803 | else |
781 | { | 804 | { |
782 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 805 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -794,6 +817,7 @@ incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel, | |||
794 | return NULL; | 817 | return NULL; |
795 | } | 818 | } |
796 | 819 | ||
820 | |||
797 | /** | 821 | /** |
798 | * Function called whenever an inbound channel is destroyed. Should clean up | 822 | * Function called whenever an inbound channel is destroyed. Should clean up |
799 | * any associated state. | 823 | * any associated state. |
@@ -804,13 +828,15 @@ incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel, | |||
804 | * with the channel is stored | 828 | * with the channel is stored |
805 | */ | 829 | */ |
806 | static void | 830 | static void |
807 | channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel, | 831 | channel_cleaner (void *cls, |
832 | const struct GNUNET_CADET_Channel *channel, | ||
808 | void *channel_ctx) | 833 | void *channel_ctx) |
809 | { | 834 | { |
810 | long i = (long) cls; | 835 | long i = (long) cls; |
811 | 836 | ||
812 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 837 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
813 | "Incoming channel disconnected at peer %ld\n", i); | 838 | "Incoming channel disconnected at peer %ld\n", |
839 | i); | ||
814 | if (peers_running - 1 == i) | 840 | if (peers_running - 1 == i) |
815 | { | 841 | { |
816 | ok++; | 842 | ok++; |
@@ -821,7 +847,7 @@ channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel, | |||
821 | { | 847 | { |
822 | if (P2P_SIGNAL == test) | 848 | if (P2P_SIGNAL == test) |
823 | { | 849 | { |
824 | ok ++; | 850 | ok++; |
825 | } | 851 | } |
826 | GNUNET_break (channel == ch); | 852 | GNUNET_break (channel == ch); |
827 | ch = NULL; | 853 | ch = NULL; |
@@ -838,8 +864,6 @@ channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel, | |||
838 | disconnect_task = GNUNET_SCHEDULER_add_now (&gather_stats_and_exit, | 864 | disconnect_task = GNUNET_SCHEDULER_add_now (&gather_stats_and_exit, |
839 | (void *) __LINE__); | 865 | (void *) __LINE__); |
840 | } | 866 | } |
841 | |||
842 | return; | ||
843 | } | 867 | } |
844 | 868 | ||
845 | 869 | ||
@@ -857,8 +881,8 @@ do_test (void *cls) | |||
857 | enum GNUNET_CADET_ChannelOption flags; | 881 | enum GNUNET_CADET_ChannelOption flags; |
858 | 882 | ||
859 | test_task = NULL; | 883 | test_task = NULL; |
860 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "do_test\n"); | 884 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
861 | 885 | "do_test\n"); | |
862 | if (NULL != disconnect_task) | 886 | if (NULL != disconnect_task) |
863 | { | 887 | { |
864 | GNUNET_SCHEDULER_cancel (disconnect_task); | 888 | GNUNET_SCHEDULER_cancel (disconnect_task); |
@@ -872,20 +896,27 @@ do_test (void *cls) | |||
872 | flags |= GNUNET_CADET_OPTION_RELIABLE; | 896 | flags |= GNUNET_CADET_OPTION_RELIABLE; |
873 | } | 897 | } |
874 | 898 | ||
875 | ch = GNUNET_CADET_channel_create (h1, NULL, p_id[1], &port, flags); | 899 | ch = GNUNET_CADET_channel_create (h1, |
900 | NULL, | ||
901 | p_id[1], | ||
902 | &port, | ||
903 | flags); | ||
876 | 904 | ||
877 | disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, | 905 | disconnect_task |
878 | &gather_stats_and_exit, | 906 | = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, |
879 | (void *) __LINE__); | 907 | &gather_stats_and_exit, |
908 | (void *) __LINE__); | ||
880 | if (KEEPALIVE == test) | 909 | if (KEEPALIVE == test) |
881 | return; /* Don't send any data. */ | 910 | return; /* Don't send any data. */ |
882 | 911 | ||
883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending data initializer...\n"); | 912 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
913 | "Sending data initializer...\n"); | ||
884 | data_received = 0; | 914 | data_received = 0; |
885 | data_sent = 0; | 915 | data_sent = 0; |
886 | ack_received = 0; | 916 | ack_received = 0; |
887 | ack_sent = 0; | 917 | ack_sent = 0; |
888 | th = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, | 918 | th = GNUNET_CADET_notify_transmit_ready (ch, |
919 | GNUNET_NO, | ||
889 | GNUNET_TIME_UNIT_FOREVER_REL, | 920 | GNUNET_TIME_UNIT_FOREVER_REL, |
890 | size_payload + 1000, | 921 | size_payload + 1000, |
891 | &tmt_rdy, (void *) 0L); | 922 | &tmt_rdy, (void *) 0L); |
@@ -909,24 +940,31 @@ pi_cb (void *cls, | |||
909 | { | 940 | { |
910 | long i = (long) cls; | 941 | long i = (long) cls; |
911 | 942 | ||
912 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i); | 943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
944 | "id callback for %ld\n", i); | ||
913 | 945 | ||
914 | if (NULL == pinfo || NULL != emsg) | 946 | if ( (NULL == pinfo) || |
947 | (NULL != emsg) ) | ||
915 | { | 948 | { |
916 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg); | 949 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
950 | "pi_cb: %s\n", emsg); | ||
917 | abort_test (__LINE__); | 951 | abort_test (__LINE__); |
918 | return; | 952 | return; |
919 | } | 953 | } |
920 | p_id[i] = pinfo->result.id; | 954 | p_id[i] = pinfo->result.id; |
921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i])); | 955 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
956 | " id: %s\n", GNUNET_i2s (p_id[i])); | ||
922 | p_ids++; | 957 | p_ids++; |
923 | if (p_ids < 2) | 958 | if (p_ids < 2) |
924 | return; | 959 | return; |
925 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n"); | 960 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
961 | "Got all IDs, starting test\n"); | ||
926 | test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 962 | test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
927 | &do_test, NULL); | 963 | &do_test, |
964 | NULL); | ||
928 | } | 965 | } |
929 | 966 | ||
967 | |||
930 | /** | 968 | /** |
931 | * test main: start test when all peers are connected | 969 | * test main: start test when all peers are connected |
932 | * | 970 | * |
diff --git a/src/cadet/test_cadet.conf b/src/cadet/test_cadet.conf index e0c00858e..b6e6c6ae3 100644 --- a/src/cadet/test_cadet.conf +++ b/src/cadet/test_cadet.conf | |||
@@ -32,6 +32,8 @@ NEIGHBOUR_LIMIT = 50 | |||
32 | #MANIPULATE_DELAY_IN = 10 ms | 32 | #MANIPULATE_DELAY_IN = 10 ms |
33 | #MANIPULATE_DELAY_OUT = 10 ms | 33 | #MANIPULATE_DELAY_OUT = 10 ms |
34 | 34 | ||
35 | [nat] | ||
36 | ENABLE_UPNP = NO | ||
35 | 37 | ||
36 | [ats] | 38 | [ats] |
37 | # Network specific inbound/outbound quotas | 39 | # Network specific inbound/outbound quotas |
diff --git a/src/cadet/test_cadet_local.c b/src/cadet/test_cadet_local.c index d15785cb0..2b915ab81 100644 --- a/src/cadet/test_cadet_local.c +++ b/src/cadet/test_cadet_local.c | |||
@@ -64,34 +64,37 @@ do_connect (void *cls); | |||
64 | static void | 64 | static void |
65 | do_shutdown (void *cls) | 65 | do_shutdown (void *cls) |
66 | { | 66 | { |
67 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutdown\n"); | 67 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
68 | "shutdown\n"); | ||
68 | if (NULL != abort_task) | 69 | if (NULL != abort_task) |
69 | { | 70 | { |
70 | GNUNET_SCHEDULER_cancel (abort_task); | 71 | GNUNET_SCHEDULER_cancel (abort_task); |
71 | abort_task = NULL; | 72 | abort_task = NULL; |
72 | } | 73 | } |
73 | if (NULL != connect_task) | ||
74 | { | ||
75 | GNUNET_SCHEDULER_cancel (connect_task); | ||
76 | connect_task = NULL; | ||
77 | } | ||
78 | if (NULL != ch) | 74 | if (NULL != ch) |
79 | { | 75 | { |
80 | GNUNET_CADET_channel_destroy (ch); | 76 | GNUNET_CADET_channel_destroy (ch); |
81 | ch = NULL; | 77 | ch = NULL; |
82 | } | 78 | } |
83 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 1\n"); | 79 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
80 | "Disconnect client 1\n"); | ||
84 | if (NULL != cadet_peer_1) | 81 | if (NULL != cadet_peer_1) |
85 | { | 82 | { |
86 | GNUNET_CADET_disconnect (cadet_peer_1); | 83 | GNUNET_CADET_disconnect (cadet_peer_1); |
87 | cadet_peer_1 = NULL; | 84 | cadet_peer_1 = NULL; |
88 | } | 85 | } |
89 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 2\n"); | 86 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
87 | "Disconnect client 2\n"); | ||
90 | if (NULL != cadet_peer_2) | 88 | if (NULL != cadet_peer_2) |
91 | { | 89 | { |
92 | GNUNET_CADET_disconnect (cadet_peer_2); | 90 | GNUNET_CADET_disconnect (cadet_peer_2); |
93 | cadet_peer_2 = NULL; | 91 | cadet_peer_2 = NULL; |
94 | } | 92 | } |
93 | if (NULL != connect_task) | ||
94 | { | ||
95 | GNUNET_SCHEDULER_cancel (connect_task); | ||
96 | connect_task = NULL; | ||
97 | } | ||
95 | } | 98 | } |
96 | 99 | ||
97 | 100 | ||
@@ -115,12 +118,12 @@ do_abort (void *cls) | |||
115 | * @param channel connection to the other end | 118 | * @param channel connection to the other end |
116 | * @param channel_ctx place to store local state associated with the channel | 119 | * @param channel_ctx place to store local state associated with the channel |
117 | * @param message the actual message | 120 | * @param message the actual message |
118 | * | 121 | * @return #GNUNET_OK to keep the connection open, |
119 | * @return GNUNET_OK to keep the connection open, | 122 | * #GNUNET_SYSERR to close it (signal serious error) |
120 | * GNUNET_SYSERR to close it (signal serious error) | ||
121 | */ | 123 | */ |
122 | static int | 124 | static int |
123 | data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | 125 | data_callback (void *cls, |
126 | struct GNUNET_CADET_Channel *channel, | ||
124 | void **channel_ctx, | 127 | void **channel_ctx, |
125 | const struct GNUNET_MessageHeader *message) | 128 | const struct GNUNET_MessageHeader *message) |
126 | { | 129 | { |
@@ -196,10 +199,12 @@ channel_end (void *cls, | |||
196 | ch = NULL; | 199 | ch = NULL; |
197 | if (GNUNET_NO == got_data) | 200 | if (GNUNET_NO == got_data) |
198 | { | 201 | { |
199 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply ( | 202 | if (NULL == connect_task) |
200 | GNUNET_TIME_UNIT_SECONDS, | 203 | connect_task |
201 | 2), | 204 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, |
202 | &do_connect, NULL); | 205 | 2), |
206 | &do_connect, | ||
207 | NULL); | ||
203 | } | 208 | } |
204 | } | 209 | } |
205 | 210 | ||
@@ -249,6 +254,7 @@ do_send (void *cls, size_t size, void *buf) | |||
249 | return sizeof (struct GNUNET_MessageHeader); | 254 | return sizeof (struct GNUNET_MessageHeader); |
250 | } | 255 | } |
251 | 256 | ||
257 | |||
252 | /** | 258 | /** |
253 | * Connect to other client and send data | 259 | * Connect to other client and send data |
254 | * | 260 | * |
@@ -261,13 +267,16 @@ do_connect (void *cls) | |||
261 | 267 | ||
262 | connect_task = NULL; | 268 | connect_task = NULL; |
263 | GNUNET_TESTING_peer_get_identity (me, &id); | 269 | GNUNET_TESTING_peer_get_identity (me, &id); |
264 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n"); | 270 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
265 | ch = GNUNET_CADET_channel_create (cadet_peer_1, NULL, &id, GC_u2h (1), | 271 | "CONNECT BY PORT\n"); |
266 | GNUNET_CADET_OPTION_DEFAULT); | 272 | ch = GNUNET_CADET_channel_create (cadet_peer_1, |
273 | NULL, | ||
274 | &id, GC_u2h (1), | ||
275 | GNUNET_CADET_OPTION_DEFAULT); | ||
267 | mth = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, | 276 | mth = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, |
268 | GNUNET_TIME_UNIT_FOREVER_REL, | 277 | GNUNET_TIME_UNIT_FOREVER_REL, |
269 | sizeof (struct GNUNET_MessageHeader), | 278 | sizeof (struct GNUNET_MessageHeader), |
270 | &do_send, NULL); | 279 | &do_send, NULL); |
271 | } | 280 | } |
272 | 281 | ||
273 | 282 | ||
@@ -284,7 +293,8 @@ run (void *cls, | |||
284 | struct GNUNET_TESTING_Peer *peer) | 293 | struct GNUNET_TESTING_Peer *peer) |
285 | { | 294 | { |
286 | me = peer; | 295 | me = peer; |
287 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | 296 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
297 | NULL); | ||
288 | abort_task = | 298 | abort_task = |
289 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 299 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
290 | (GNUNET_TIME_UNIT_SECONDS, 15), | 300 | (GNUNET_TIME_UNIT_SECONDS, 15), |
@@ -294,13 +304,13 @@ run (void *cls, | |||
294 | (void *) 1L, /* cls */ | 304 | (void *) 1L, /* cls */ |
295 | &channel_end, /* channel end hndlr */ | 305 | &channel_end, /* channel end hndlr */ |
296 | handlers1); /* traffic handlers */ | 306 | handlers1); /* traffic handlers */ |
297 | |||
298 | cadet_peer_2 = GNUNET_CADET_connect (cfg, /* configuration */ | 307 | cadet_peer_2 = GNUNET_CADET_connect (cfg, /* configuration */ |
299 | (void *) 2L, /* cls */ | 308 | (void *) 2L, /* cls */ |
300 | &channel_end, /* channel end hndlr */ | 309 | &channel_end, /* channel end hndlr */ |
301 | handlers2); /* traffic handlers */ | 310 | handlers2); /* traffic handlers */ |
302 | 311 | ||
303 | if (NULL == cadet_peer_1 || NULL == cadet_peer_2) | 312 | if ( (NULL == cadet_peer_1) || |
313 | (NULL == cadet_peer_2) ) | ||
304 | { | 314 | { |
305 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 315 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
306 | "Couldn't connect to cadet :(\n"); | 316 | "Couldn't connect to cadet :(\n"); |
@@ -308,12 +318,16 @@ run (void *cls, | |||
308 | GNUNET_SCHEDULER_shutdown (); | 318 | GNUNET_SCHEDULER_shutdown (); |
309 | return; | 319 | return; |
310 | } | 320 | } |
311 | GNUNET_CADET_open_port (cadet_peer_2, GC_u2h (1), | 321 | GNUNET_CADET_open_port (cadet_peer_2, |
312 | &inbound_channel, (void *) 2L); | 322 | GC_u2h (1), |
313 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply ( | 323 | &inbound_channel, |
314 | GNUNET_TIME_UNIT_SECONDS, | 324 | (void *) 2L); |
315 | 2), | 325 | if (NULL == connect_task) |
316 | &do_connect, NULL); | 326 | connect_task |
327 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | ||
328 | 2), | ||
329 | &do_connect, | ||
330 | NULL); | ||
317 | } | 331 | } |
318 | 332 | ||
319 | 333 | ||
diff --git a/src/cadet/test_cadet_single.c b/src/cadet/test_cadet_single.c index 9bfaeda0d..b45b0af5d 100644 --- a/src/cadet/test_cadet_single.c +++ b/src/cadet/test_cadet_single.c | |||
@@ -49,6 +49,10 @@ static struct GNUNET_SCHEDULER_Task *connect_task; | |||
49 | 49 | ||
50 | static unsigned int repetition; | 50 | static unsigned int repetition; |
51 | 51 | ||
52 | static struct GNUNET_CADET_TransmitHandle *nth; | ||
53 | |||
54 | static struct GNUNET_CADET_Port *port; | ||
55 | |||
52 | 56 | ||
53 | /* forward declaration */ | 57 | /* forward declaration */ |
54 | static size_t | 58 | static size_t |
@@ -61,7 +65,18 @@ do_send (void *cls, size_t size, void *buf); | |||
61 | static void | 65 | static void |
62 | do_shutdown (void *cls) | 66 | do_shutdown (void *cls) |
63 | { | 67 | { |
64 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutdown\n"); | 68 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
69 | "shutdown\n"); | ||
70 | if (NULL != port) | ||
71 | { | ||
72 | GNUNET_CADET_close_port (port); | ||
73 | port = NULL; | ||
74 | } | ||
75 | if (NULL != nth) | ||
76 | { | ||
77 | GNUNET_CADET_notify_transmit_ready_cancel (nth); | ||
78 | nth = NULL; | ||
79 | } | ||
65 | if (NULL != abort_task) | 80 | if (NULL != abort_task) |
66 | { | 81 | { |
67 | GNUNET_SCHEDULER_cancel (abort_task); | 82 | GNUNET_SCHEDULER_cancel (abort_task); |
@@ -77,8 +92,8 @@ do_shutdown (void *cls) | |||
77 | GNUNET_CADET_channel_destroy (ch1); | 92 | GNUNET_CADET_channel_destroy (ch1); |
78 | ch1 = NULL; | 93 | ch1 = NULL; |
79 | } | 94 | } |
80 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 1\n"); | 95 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
81 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 2\n"); | 96 | "Disconnect clients\n"); |
82 | if (NULL != cadet) | 97 | if (NULL != cadet) |
83 | { | 98 | { |
84 | GNUNET_CADET_disconnect (cadet); | 99 | GNUNET_CADET_disconnect (cadet); |
@@ -111,35 +126,38 @@ do_abort (void *cls) | |||
111 | * @param channel connection to the other end | 126 | * @param channel connection to the other end |
112 | * @param channel_ctx place to store local state associated with the channel | 127 | * @param channel_ctx place to store local state associated with the channel |
113 | * @param message the actual message | 128 | * @param message the actual message |
114 | * | 129 | * @return #GNUNET_OK to keep the connection open, |
115 | * @return GNUNET_OK to keep the connection open, | 130 | * #GNUNET_SYSERR to close it (signal serious error) |
116 | * GNUNET_SYSERR to close it (signal serious error) | ||
117 | */ | 131 | */ |
118 | static int | 132 | static int |
119 | data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | 133 | data_callback (void *cls, |
134 | struct GNUNET_CADET_Channel *channel, | ||
120 | void **channel_ctx, | 135 | void **channel_ctx, |
121 | const struct GNUNET_MessageHeader *message) | 136 | const struct GNUNET_MessageHeader *message) |
122 | { | 137 | { |
123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 138 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
124 | "Data callback! Repetition %u/%u\n", | 139 | "Data callback! Repetition %u/%u\n", |
125 | repetition, REPETITIONS); | 140 | repetition, REPETITIONS); |
126 | repetition = repetition + 1; | 141 | repetition++; |
127 | if (repetition < REPETITIONS) | 142 | if (repetition < REPETITIONS) |
128 | { | 143 | { |
129 | struct GNUNET_CADET_Channel *my_channel; | 144 | struct GNUNET_CADET_Channel *my_channel; |
130 | if (repetition % 2 == 0) | 145 | if (0 == repetition % 2) |
131 | my_channel = ch1; | 146 | my_channel = ch1; |
132 | else | 147 | else |
133 | my_channel = ch2; | 148 | my_channel = ch2; |
134 | GNUNET_CADET_notify_transmit_ready (my_channel, GNUNET_NO, | 149 | nth = GNUNET_CADET_notify_transmit_ready (my_channel, |
135 | GNUNET_TIME_UNIT_FOREVER_REL, | 150 | GNUNET_NO, |
136 | sizeof (struct GNUNET_MessageHeader) | 151 | GNUNET_TIME_UNIT_FOREVER_REL, |
137 | + DATA_SIZE, | 152 | sizeof (struct GNUNET_MessageHeader) |
138 | &do_send, NULL); | 153 | + DATA_SIZE, |
154 | &do_send, NULL); | ||
139 | GNUNET_CADET_receive_done (channel); | 155 | GNUNET_CADET_receive_done (channel); |
140 | return GNUNET_OK; | 156 | return GNUNET_OK; |
141 | } | 157 | } |
142 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All data OK. Destroying channel.\n"); | 158 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
159 | "All data OK. Destroying channel.\n"); | ||
160 | GNUNET_assert (NULL == nth); | ||
143 | GNUNET_CADET_channel_destroy (ch1); | 161 | GNUNET_CADET_channel_destroy (ch1); |
144 | ch1 = NULL; | 162 | ch1 = NULL; |
145 | return GNUNET_OK; | 163 | return GNUNET_OK; |
@@ -159,7 +177,8 @@ data_callback (void *cls, struct GNUNET_CADET_Channel *channel, | |||
159 | * (can be NULL -- that's not an error) | 177 | * (can be NULL -- that's not an error) |
160 | */ | 178 | */ |
161 | static void * | 179 | static void * |
162 | inbound_channel (void *cls, struct GNUNET_CADET_Channel *channel, | 180 | inbound_channel (void *cls, |
181 | struct GNUNET_CADET_Channel *channel, | ||
163 | const struct GNUNET_PeerIdentity *initiator, | 182 | const struct GNUNET_PeerIdentity *initiator, |
164 | const struct GNUNET_HashCode *port, | 183 | const struct GNUNET_HashCode *port, |
165 | enum GNUNET_CADET_ChannelOption options) | 184 | enum GNUNET_CADET_ChannelOption options) |
@@ -182,21 +201,28 @@ inbound_channel (void *cls, struct GNUNET_CADET_Channel *channel, | |||
182 | * with the channel is stored | 201 | * with the channel is stored |
183 | */ | 202 | */ |
184 | static void | 203 | static void |
185 | channel_end (void *cls, const struct GNUNET_CADET_Channel *channel, | 204 | channel_end (void *cls, |
205 | const struct GNUNET_CADET_Channel *channel, | ||
186 | void *channel_ctx) | 206 | void *channel_ctx) |
187 | { | 207 | { |
188 | long id = (long) cls; | 208 | long id = (long) cls; |
189 | 209 | ||
210 | nth = NULL; | ||
190 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 211 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
191 | "incoming channel closed at peer %ld\n", | 212 | "incoming channel closed at peer %ld\n", |
192 | id); | 213 | id); |
193 | if (REPETITIONS == repetition && channel == ch2) | 214 | if ( (REPETITIONS == repetition) && |
215 | (channel == ch2) ) | ||
194 | { | 216 | { |
195 | ch2 = NULL; | 217 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
196 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "everything fine! finishing!\n"); | 218 | "everything fine! finishing!\n"); |
197 | result = GNUNET_OK; | 219 | result = GNUNET_OK; |
198 | GNUNET_SCHEDULER_shutdown (); | 220 | GNUNET_SCHEDULER_shutdown (); |
199 | } | 221 | } |
222 | if (channel == ch2) | ||
223 | ch2 = NULL; | ||
224 | if (channel == ch1) | ||
225 | ch1 = NULL; | ||
200 | } | 226 | } |
201 | 227 | ||
202 | 228 | ||
@@ -215,7 +241,6 @@ static struct GNUNET_CADET_MessageHandler handlers1[] = { | |||
215 | * @param cls Closure (unused). | 241 | * @param cls Closure (unused). |
216 | * @param size Buffer size. | 242 | * @param size Buffer size. |
217 | * @param buf Buffer to fill. | 243 | * @param buf Buffer to fill. |
218 | * | ||
219 | * @return size of test packet. | 244 | * @return size of test packet. |
220 | */ | 245 | */ |
221 | static size_t | 246 | static size_t |
@@ -223,13 +248,14 @@ do_send (void *cls, size_t size, void *buf) | |||
223 | { | 248 | { |
224 | struct GNUNET_MessageHeader *m = buf; | 249 | struct GNUNET_MessageHeader *m = buf; |
225 | 250 | ||
251 | nth = NULL; | ||
226 | if (NULL == buf) | 252 | if (NULL == buf) |
227 | { | 253 | { |
228 | GNUNET_break (0); | 254 | GNUNET_break (0); |
229 | result = GNUNET_SYSERR; | 255 | result = GNUNET_SYSERR; |
230 | return 0; | 256 | return 0; |
231 | } | 257 | } |
232 | m->size = htons (sizeof (struct GNUNET_MessageHeader)); | 258 | m->size = htons (sizeof (struct GNUNET_MessageHeader) + DATA_SIZE); |
233 | m->type = htons (1); | 259 | m->type = htons (1); |
234 | memset (&m[1], 0, DATA_SIZE); | 260 | memset (&m[1], 0, DATA_SIZE); |
235 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader) + DATA_SIZE); | 261 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader) + DATA_SIZE); |
@@ -252,9 +278,12 @@ do_connect (void *cls) | |||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n"); | 278 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n"); |
253 | ch1 = GNUNET_CADET_channel_create (cadet, NULL, &id, GC_u2h (1), | 279 | ch1 = GNUNET_CADET_channel_create (cadet, NULL, &id, GC_u2h (1), |
254 | GNUNET_CADET_OPTION_DEFAULT); | 280 | GNUNET_CADET_OPTION_DEFAULT); |
255 | GNUNET_CADET_notify_transmit_ready (ch1, GNUNET_NO, | 281 | nth = GNUNET_CADET_notify_transmit_ready (ch1, |
256 | GNUNET_TIME_UNIT_FOREVER_REL, | 282 | GNUNET_NO, |
257 | size, &do_send, NULL); | 283 | GNUNET_TIME_UNIT_FOREVER_REL, |
284 | size, | ||
285 | &do_send, | ||
286 | NULL); | ||
258 | } | 287 | } |
259 | 288 | ||
260 | 289 | ||
@@ -280,12 +309,16 @@ run (void *cls, | |||
280 | (void *) 1L, /* cls */ | 309 | (void *) 1L, /* cls */ |
281 | &channel_end, /* inbound end hndlr */ | 310 | &channel_end, /* inbound end hndlr */ |
282 | handlers1); /* traffic handlers */ | 311 | handlers1); /* traffic handlers */ |
283 | GNUNET_CADET_open_port (cadet, GC_u2h (1), &inbound_channel, (void *) 1L); | 312 | port = GNUNET_CADET_open_port (cadet, |
313 | GC_u2h (1), | ||
314 | &inbound_channel, | ||
315 | (void *) 1L); | ||
284 | 316 | ||
285 | 317 | ||
286 | if (NULL == cadet) | 318 | if (NULL == cadet) |
287 | { | 319 | { |
288 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Couldn't connect to cadet :(\n"); | 320 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
321 | "Couldn't connect to cadet :(\n"); | ||
289 | result = GNUNET_SYSERR; | 322 | result = GNUNET_SYSERR; |
290 | return; | 323 | return; |
291 | } | 324 | } |
@@ -300,17 +333,21 @@ run (void *cls, | |||
300 | * Main | 333 | * Main |
301 | */ | 334 | */ |
302 | int | 335 | int |
303 | main (int argc, char *argv[]) | 336 | main (int argc, |
337 | char *argv[]) | ||
304 | { | 338 | { |
305 | result = GNUNET_NO; | 339 | result = GNUNET_NO; |
306 | if (0 != GNUNET_TESTING_peer_run ("test-cadet-local", | 340 | if (0 != GNUNET_TESTING_peer_run ("test-cadet-local", |
307 | "test_cadet.conf", | 341 | "test_cadet.conf", |
308 | &run, NULL)) | 342 | &run, NULL)) |
309 | { | 343 | { |
310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n"); | 344 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
345 | "run failed\n"); | ||
311 | return 2; | 346 | return 2; |
312 | } | 347 | } |
313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Final result: %d\n", result); | 348 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
349 | "Final result: %d\n", | ||
350 | result); | ||
314 | return (result == GNUNET_OK) ? 0 : 1; | 351 | return (result == GNUNET_OK) ? 0 : 1; |
315 | } | 352 | } |
316 | 353 | ||
diff --git a/src/core/core_api.c b/src/core/core_api.c index ace80b952..b6d8f61d2 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -249,9 +249,9 @@ handle_mq_error (void *cls, | |||
249 | { | 249 | { |
250 | struct GNUNET_CORE_Handle *h = cls; | 250 | struct GNUNET_CORE_Handle *h = cls; |
251 | 251 | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 252 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
253 | "MQ ERROR: %d\n", | 253 | "MQ ERROR: %d\n", |
254 | error); | 254 | error); |
255 | reconnect_later (h); | 255 | reconnect_later (h); |
256 | } | 256 | } |
257 | 257 | ||
@@ -348,10 +348,10 @@ core_mq_send_impl (struct GNUNET_MQ_Handle *mq, | |||
348 | sm->peer = pr->peer; | 348 | sm->peer = pr->peer; |
349 | sm->cork = htonl ((uint32_t) cork); | 349 | sm->cork = htonl ((uint32_t) cork); |
350 | sm->reserved = htonl (0); | 350 | sm->reserved = htonl (0); |
351 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 351 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
352 | "Calling get_message with buffer of %u bytes (%s)\n", | 352 | "Calling get_message with buffer of %u bytes (%s)\n", |
353 | (unsigned int) msize, | 353 | (unsigned int) msize, |
354 | cork ? "corked" : "uncorked"); | 354 | cork ? "corked" : "uncorked"); |
355 | } | 355 | } |
356 | 356 | ||
357 | 357 | ||
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 036fd1425..6687b4819 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -90,9 +90,9 @@ struct Session | |||
90 | 90 | ||
91 | /** | 91 | /** |
92 | * Key exchange state for this peer. | 92 | * Key exchange state for this peer. |
93 | */ | 93 | */ |
94 | struct GSC_KeyExchangeInfo *kx; | 94 | struct GSC_KeyExchangeInfo *kx; |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * Head of list of requests from clients for transmission to | 97 | * Head of list of requests from clients for transmission to |
98 | * this peer. | 98 | * this peer. |
@@ -725,10 +725,10 @@ try_transmission (struct Session *session) | |||
725 | GNUNET_YES)); | 725 | GNUNET_YES)); |
726 | if (NULL != session->cork_task) | 726 | if (NULL != session->cork_task) |
727 | GNUNET_SCHEDULER_cancel (session->cork_task); | 727 | GNUNET_SCHEDULER_cancel (session->cork_task); |
728 | session->cork_task = | 728 | session->cork_task |
729 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (min_deadline), | 729 | = GNUNET_SCHEDULER_add_at (min_deadline, |
730 | &pop_cork_task, | 730 | &pop_cork_task, |
731 | session); | 731 | session); |
732 | } | 732 | } |
733 | else | 733 | else |
734 | { | 734 | { |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index df56c010a..5ba4e5820 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -426,19 +426,20 @@ transmit_next_request_task (void *cls) | |||
426 | delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); | 426 | delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); |
427 | if (delay.rel_value_us > 0) | 427 | if (delay.rel_value_us > 0) |
428 | { | 428 | { |
429 | cqr->hnode = | 429 | cqr->hnode |
430 | GNUNET_CONTAINER_heap_insert (retry_heap, | 430 | = GNUNET_CONTAINER_heap_insert (retry_heap, |
431 | cqr, | 431 | cqr, |
432 | cqr->retry_time.abs_value_us); | 432 | cqr->retry_time.abs_value_us); |
433 | retry_task = | 433 | retry_task |
434 | GNUNET_SCHEDULER_add_delayed (delay, | 434 | = GNUNET_SCHEDULER_add_at (cqr->retry_time, |
435 | &transmit_next_request_task, | 435 | &transmit_next_request_task, |
436 | NULL); | 436 | NULL); |
437 | return; | 437 | return; |
438 | } | 438 | } |
439 | transmit_request (cqr); | 439 | transmit_request (cqr); |
440 | cqr->hnode | 440 | cqr->hnode |
441 | = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, | 441 | = GNUNET_CONTAINER_heap_insert (retry_heap, |
442 | cqr, | ||
442 | cqr->retry_time.abs_value_us); | 443 | cqr->retry_time.abs_value_us); |
443 | } | 444 | } |
444 | } | 445 | } |
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c index 02444cf14..f68635100 100644 --- a/src/fragmentation/fragmentation.c +++ b/src/fragmentation/fragmentation.c | |||
@@ -373,8 +373,9 @@ GNUNET_FRAGMENT_context_transmission_done (struct GNUNET_FRAGMENT_Context *fc) | |||
373 | fc->proc_busy = GNUNET_NO; | 373 | fc->proc_busy = GNUNET_NO; |
374 | GNUNET_assert (fc->task == NULL); | 374 | GNUNET_assert (fc->task == NULL); |
375 | fc->task = | 375 | fc->task = |
376 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | 376 | GNUNET_SCHEDULER_add_at (fc->delay_until, |
377 | (fc->delay_until), &transmit_next, fc); | 377 | &transmit_next, |
378 | fc); | ||
378 | } | 379 | } |
379 | 380 | ||
380 | 381 | ||
diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c index e8ce77904..12b04dcd1 100644 --- a/src/fs/gnunet-service-fs_pe.c +++ b/src/fs/gnunet-service-fs_pe.c | |||
@@ -427,10 +427,10 @@ schedule_peer_transmission (void *cls) | |||
427 | gettext_noop ("# delay heap timeout (ms)"), | 427 | gettext_noop ("# delay heap timeout (ms)"), |
428 | delay.rel_value_us / 1000LL, GNUNET_NO); | 428 | delay.rel_value_us / 1000LL, GNUNET_NO); |
429 | 429 | ||
430 | pp->task = | 430 | pp->task |
431 | GNUNET_SCHEDULER_add_delayed (delay, | 431 | = GNUNET_SCHEDULER_add_at (rp->earliest_transmission, |
432 | &schedule_peer_transmission, | 432 | &schedule_peer_transmission, |
433 | pp); | 433 | pp); |
434 | return; | 434 | return; |
435 | } | 435 | } |
436 | #if INSANE_STATISTICS | 436 | #if INSANE_STATISTICS |
diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h index 7090d4410..8d10c3d8d 100644 --- a/src/include/gnunet_cadet_service.h +++ b/src/include/gnunet_cadet_service.h | |||
@@ -497,7 +497,12 @@ struct GNUNET_CADET_ChannelTunnelNumber | |||
497 | { | 497 | { |
498 | /** | 498 | /** |
499 | * Which number does this channel have that uniquely identfies | 499 | * Which number does this channel have that uniquely identfies |
500 | * it within its tunnel? | 500 | * it within its tunnel, in network byte order. |
501 | * | ||
502 | * Given two peers, both may initiate channels over the same tunnel. | ||
503 | * The @e cn must be greater or equal to 0x80000000 (high-bit set) | ||
504 | * for tunnels initiated with the peer that has the larger peer | ||
505 | * identity as compared using #GNUNET_CRYPTO_cmp_peer_identity(). | ||
501 | */ | 506 | */ |
502 | uint32_t cn GNUNET_PACKED; | 507 | uint32_t cn GNUNET_PACKED; |
503 | }; | 508 | }; |
@@ -687,6 +692,164 @@ const struct GNUNET_HashCode * | |||
687 | GC_u2h (uint32_t port); | 692 | GC_u2h (uint32_t port); |
688 | 693 | ||
689 | 694 | ||
695 | /******************************************************************************/ | ||
696 | /******************************* MQ-BASED API *********************************/ | ||
697 | /******************************************************************************/ | ||
698 | |||
699 | /** | ||
700 | * Function called after #GNUNET_CADET_connecT has succeeded (or failed | ||
701 | * for good). Implementations of this function must not call | ||
702 | * #GNUNET_CADET_disconnecT (other than by scheduling a new task to | ||
703 | * do this later). | ||
704 | * | ||
705 | * @param cls closure | ||
706 | * @param connected #GNUNET_YES if successfully connected, #GNUNET_NO otherwise. | ||
707 | */ | ||
708 | typedef void | ||
709 | (*GNUNET_CADET_StartupCallback) (void *cls, int connected); | ||
710 | |||
711 | |||
712 | /** | ||
713 | * Method called whenever a given peer connects in mq-based CADET. | ||
714 | * | ||
715 | * @param cls Closure given to @a GNUNET_CADET_connecT. | ||
716 | * @param channel New handle to the channel. | ||
717 | * @param channel_cls Closure given to @a GNUNET_CADET_open_porT. | ||
718 | * NOTE: do we need two cls? I'd get rid of this one. | ||
719 | * @param peer Peer that started this channel. | ||
720 | * | ||
721 | * NOTE: to keep symmetry between incoming and outgoing channels, this call | ||
722 | * does not provide the *mq, since we cannot cleanly return an mq | ||
723 | * from @a GNUNET_CADET_channel_create. | ||
724 | * The client must always call @a GNUNET_CADET_get_mq to the *mq | ||
725 | * Alternatively, we can provide the mq here and add and out **mq | ||
726 | * to @a GNUNET_CADET_channel_create | ||
727 | * | ||
728 | * @return initial channel context for the channel | ||
729 | * (can be NULL -- that's not an error) | ||
730 | */ | ||
731 | typedef void * | ||
732 | (*GNUNET_CADET_ConnectEventHandler) (void *cls, | ||
733 | struct GNUNET_CADET_Channel *channel, | ||
734 | const struct GNUNET_PeerIdentity *peer); | ||
735 | |||
736 | /** | ||
737 | * Function called whenever an mq-channel is destroyed. Should clean up | ||
738 | * any associated state, including cancelling any pending transmission on this | ||
739 | * channel. | ||
740 | * | ||
741 | * It must NOT call @a GNUNET_CADET_channel_destroy on the channel. | ||
742 | * | ||
743 | * @param cls Closure (set from @a GNUNET_CADET_connecT). | ||
744 | * @param channel Connection to the other end (henceforth invalid). | ||
745 | * @param channel_ctx Context (set from @a GNUNET_CADET_ConnectEventHandler). | ||
746 | */ | ||
747 | typedef void | ||
748 | (GNUNET_CADET_DisconnectEventHandler) (void *cls, | ||
749 | const struct GNUNET_CADET_Channel *channel, | ||
750 | void *channel_ctx); | ||
751 | |||
752 | /** | ||
753 | * Connect to the mq-based cadet service. | ||
754 | * | ||
755 | * NOTE: it would be more elegant to provide a separate @a handlers and | ||
756 | * @a disconnects for each port, giving them to @a GNUNET_CADET_open_porT, | ||
757 | * but how do we handle *incoming* channels? | ||
758 | * | ||
759 | * @param cfg Configuration to use. | ||
760 | * @param cls Closure for the various callbacks that follow (including | ||
761 | * handlers in the handlers array). | ||
762 | * @param init callback to call once we have successfully connected | ||
763 | * to the cadet service | ||
764 | * @param disconnects Function called when a channel is destroyed. | ||
765 | * It is called immediately if the channel is destroyed by | ||
766 | * calling @a GNUNET_CADET_channel_destroy. | ||
767 | * @param handlers Callbacks for messages we care about, NULL-terminated. | ||
768 | * Messages of a type that is not in the handlers array | ||
769 | * are ignored if received. | ||
770 | * | ||
771 | * @return handle to the cadet service NULL on error | ||
772 | * (in this case, init is never called) | ||
773 | */ | ||
774 | struct GNUNET_CADET_Handle * | ||
775 | GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
776 | void *cls, | ||
777 | GNUNET_CADET_StartupCallback init, | ||
778 | GNUNET_CADET_DisconnectEventHandler disconnects, | ||
779 | const struct GNUNET_MQ_MessageHandler *handlers); | ||
780 | |||
781 | /** | ||
782 | * Disconnect from the mq-based cadet service. All channels will be destroyed. | ||
783 | * All channel disconnect callbacks will be called on any still connected peers, | ||
784 | * notifying about their disconnection. The registered inbound channel cleaner | ||
785 | * will be called should any inbound channels still exist. | ||
786 | * | ||
787 | * @param handle connection to cadet to disconnect | ||
788 | */ | ||
789 | void | ||
790 | GNUNET_CADET_disconnecT (struct GNUNET_CADET_Handle *handle); | ||
791 | |||
792 | /** | ||
793 | * Open a port to receive incomming mq-based channels. | ||
794 | * | ||
795 | * @param h CADET handle. | ||
796 | * @param port Hash representing the port number. | ||
797 | * @param new_channel Function called when an channel is received. | ||
798 | * @param new_channel_cls Closure for @a new_channel. | ||
799 | * NOTE: get rid of this cls? | ||
800 | * | ||
801 | * @return Port handle. | ||
802 | */ | ||
803 | struct GNUNET_CADET_Port * | ||
804 | GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h, | ||
805 | const struct GNUNET_HashCode *port, | ||
806 | GNUNET_CADET_ConnectEventHandler new_channel, | ||
807 | void *new_channel_cls); | ||
808 | |||
809 | /** | ||
810 | * Close a port opened with @a GNUNET_CADET_open_porT. | ||
811 | * The @a new_channel callback will no longer be called. | ||
812 | * | ||
813 | * @param p Port handle. | ||
814 | */ | ||
815 | void | ||
816 | GNUNET_CADET_close_porT (struct GNUNET_CADET_Port *p); | ||
817 | |||
818 | /** | ||
819 | * Obtain the message queue for a connected peer. | ||
820 | * | ||
821 | * @param h the cadet handle | ||
822 | * @param channel the identity of the peer | ||
823 | * | ||
824 | * @return NULL if @a channel is not yet connected. | ||
825 | * NOTE: provide an mq before a channel is connected? | ||
826 | * provide a callback to notify a client a channel connected? | ||
827 | */ | ||
828 | struct GNUNET_MQ_Handle * | ||
829 | GNUNET_CADET_get_mq (const struct GNUNET_CADET_Handle *h, | ||
830 | const struct GNUNET_CADET_Channel *channel); | ||
831 | |||
832 | /* NOTE: | ||
833 | * GNUNET_CADET_channel_create and _destroy can stay the same. | ||
834 | * Monitor API can stay the same (low-priority). | ||
835 | |||
836 | struct GNUNET_CADET_Channel * | ||
837 | GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h, | ||
838 | void *channel_ctx, | ||
839 | const struct GNUNET_PeerIdentity *peer, | ||
840 | const struct GNUNET_HashCode *port, | ||
841 | enum GNUNET_CADET_ChannelOption options); | ||
842 | void | ||
843 | GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel); | ||
844 | |||
845 | */ | ||
846 | |||
847 | /******************************************************************************/ | ||
848 | /******************************* MQ-BASED API *********************************/ | ||
849 | /******************************************************************************/ | ||
850 | |||
851 | |||
852 | |||
690 | #if 0 /* keep Emacsens' auto-indent happy */ | 853 | #if 0 /* keep Emacsens' auto-indent happy */ |
691 | { | 854 | { |
692 | #endif | 855 | #endif |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 9ad604711..fdcae66fa 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -614,6 +614,22 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); | |||
614 | * @ingroup logging | 614 | * @ingroup logging |
615 | * Convert a peer identity to a string (for printing debug messages). | 615 | * Convert a peer identity to a string (for printing debug messages). |
616 | * This is one of the very few calls in the entire API that is | 616 | * This is one of the very few calls in the entire API that is |
617 | * NOT reentrant! Identical to #GNUNET_i2s(), except that another | ||
618 | * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be | ||
619 | * used within the same log statement. | ||
620 | * | ||
621 | * @param pid the peer identity | ||
622 | * @return string form of the pid; will be overwritten by next | ||
623 | * call to #GNUNET_i2s(). | ||
624 | */ | ||
625 | const char * | ||
626 | GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid); | ||
627 | |||
628 | |||
629 | /** | ||
630 | * @ingroup logging | ||
631 | * Convert a peer identity to a string (for printing debug messages). | ||
632 | * This is one of the very few calls in the entire API that is | ||
617 | * NOT reentrant! | 633 | * NOT reentrant! |
618 | * | 634 | * |
619 | * @param pid the peer identity | 635 | * @param pid the peer identity |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index e31b1f33c..b2807e990 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2745,6 +2745,16 @@ extern "C" | |||
2745 | */ | 2745 | */ |
2746 | #define GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE 1023 | 2746 | #define GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE 1023 |
2747 | 2747 | ||
2748 | /** | ||
2749 | * Ask the cadet service to create a new channel. | ||
2750 | */ | ||
2751 | #define GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE 1024 | ||
2752 | |||
2753 | /** | ||
2754 | * Tell client that a channel was destroyed. | ||
2755 | */ | ||
2756 | #define GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY 1025 | ||
2757 | |||
2748 | /********************************** Monitor *********************************/ | 2758 | /********************************** Monitor *********************************/ |
2749 | 2759 | ||
2750 | 2760 | ||
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index 1a0438bed..2be1858ce 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h | |||
@@ -172,7 +172,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | |||
172 | 172 | ||
173 | 173 | ||
174 | /** | 174 | /** |
175 | * Request the shutdown of a scheduler. Marks all tasks | 175 | * Request the shutdown of a scheduler. Marks all tasks |
176 | * awaiting shutdown as ready. Note that tasks | 176 | * awaiting shutdown as ready. Note that tasks |
177 | * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call | 177 | * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call |
178 | * will be delayed until the next shutdown signal. | 178 | * will be delayed until the next shutdown signal. |
@@ -309,7 +309,7 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, | |||
309 | * will be scheduled for execution once the delay has expired. It | 309 | * will be scheduled for execution once the delay has expired. It |
310 | * will be run with the DEFAULT priority. | 310 | * will be run with the DEFAULT priority. |
311 | * | 311 | * |
312 | * @param delay when should this operation time out? | 312 | * @param delay with which the operation should be run |
313 | * @param task main function of the task | 313 | * @param task main function of the task |
314 | * @param task_cls closure of @a task | 314 | * @param task_cls closure of @a task |
315 | * @return unique task identifier for the job | 315 | * @return unique task identifier for the job |
@@ -322,10 +322,27 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, | |||
322 | 322 | ||
323 | 323 | ||
324 | /** | 324 | /** |
325 | * Schedule a new task to be run at the specified time. The task | ||
326 | * will be scheduled for execution once specified time has been | ||
327 | * reached. It will be run with the DEFAULT priority. | ||
328 | * | ||
329 | * @param at time at which this operation should run | ||
330 | * @param task main function of the task | ||
331 | * @param task_cls closure of @a task | ||
332 | * @return unique task identifier for the job | ||
333 | * only valid until @a task is started! | ||
334 | */ | ||
335 | struct GNUNET_SCHEDULER_Task * | ||
336 | GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at, | ||
337 | GNUNET_SCHEDULER_TaskCallback task, | ||
338 | void *task_cls); | ||
339 | |||
340 | |||
341 | /** | ||
325 | * Schedule a new task to be run with a specified delay. The task | 342 | * Schedule a new task to be run with a specified delay. The task |
326 | * will be scheduled for execution once the delay has expired. | 343 | * will be scheduled for execution once the delay has expired. |
327 | * | 344 | * |
328 | * @param delay when should this operation time out? | 345 | * @param delay when should this operation time out? |
329 | * @param priority priority to use for the task | 346 | * @param priority priority to use for the task |
330 | * @param task main function of the task | 347 | * @param task main function of the task |
331 | * @param task_cls closure of @a task | 348 | * @param task_cls closure of @a task |
@@ -340,6 +357,24 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | |||
340 | 357 | ||
341 | 358 | ||
342 | /** | 359 | /** |
360 | * Schedule a new task to be run at the specified time. The task | ||
361 | * will be scheduled for execution at time @a at. | ||
362 | * | ||
363 | * @param at time when the operation should run | ||
364 | * @param priority priority to use for the task | ||
365 | * @param task main function of the task | ||
366 | * @param task_cls closure of @a task | ||
367 | * @return unique task identifier for the job | ||
368 | * only valid until @a task is started! | ||
369 | */ | ||
370 | struct GNUNET_SCHEDULER_Task * | ||
371 | GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | ||
372 | enum GNUNET_SCHEDULER_Priority priority, | ||
373 | GNUNET_SCHEDULER_TaskCallback task, | ||
374 | void *task_cls); | ||
375 | |||
376 | |||
377 | /** | ||
343 | * Schedule a new task to be run with a specified delay or when the | 378 | * Schedule a new task to be run with a specified delay or when the |
344 | * specified file descriptor is ready for reading. The delay can be | 379 | * specified file descriptor is ready for reading. The delay can be |
345 | * used as a timeout on the socket being ready. The task will be | 380 | * used as a timeout on the socket being ready. The task will be |
@@ -480,7 +515,7 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, | |||
480 | * scheduled for execution once either the delay has expired or the | 515 | * scheduled for execution once either the delay has expired or the |
481 | * socket operation is ready. | 516 | * socket operation is ready. |
482 | * | 517 | * |
483 | * @param delay when should this operation time out? | 518 | * @param delay when should this operation time out? |
484 | * @param priority priority of the task | 519 | * @param priority priority of the task |
485 | * @param fd file-descriptor | 520 | * @param fd file-descriptor |
486 | * @param on_read whether to poll the file-descriptor for readability | 521 | * @param on_read whether to poll the file-descriptor for readability |
@@ -516,7 +551,7 @@ GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay, | |||
516 | * </code> | 551 | * </code> |
517 | * | 552 | * |
518 | * @param prio how important is this task? | 553 | * @param prio how important is this task? |
519 | * @param delay how long should we wait? | 554 | * @param delay how long should we wait? |
520 | * @param rs set of file descriptors we want to read (can be NULL) | 555 | * @param rs set of file descriptors we want to read (can be NULL) |
521 | * @param ws set of file descriptors we want to write (can be NULL) | 556 | * @param ws set of file descriptors we want to write (can be NULL) |
522 | * @param task main function of the task | 557 | * @param task main function of the task |
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c index 98d87262e..bfe212308 100644 --- a/src/nat/gnunet-service-nat.c +++ b/src/nat/gnunet-service-nat.c | |||
@@ -1434,8 +1434,8 @@ handle_register (void *cls, | |||
1434 | off = (const char *) &message[1]; | 1434 | off = (const char *) &message[1]; |
1435 | for (unsigned int i=0;i<ch->num_caddrs;i++) | 1435 | for (unsigned int i=0;i<ch->num_caddrs;i++) |
1436 | { | 1436 | { |
1437 | size_t alen; | ||
1438 | const struct sockaddr *sa = (const struct sockaddr *) off; | 1437 | const struct sockaddr *sa = (const struct sockaddr *) off; |
1438 | size_t alen; | ||
1439 | uint16_t port; | 1439 | uint16_t port; |
1440 | int is_nat; | 1440 | int is_nat; |
1441 | 1441 | ||
@@ -1450,22 +1450,28 @@ handle_register (void *cls, | |||
1450 | { | 1450 | { |
1451 | case AF_INET: | 1451 | case AF_INET: |
1452 | { | 1452 | { |
1453 | const struct sockaddr_in *s4 = (const struct sockaddr_in *) sa; | 1453 | struct sockaddr_in s4; |
1454 | 1454 | ||
1455 | GNUNET_memcpy (&s4, | ||
1456 | off, | ||
1457 | sizeof (struct sockaddr_in)); | ||
1455 | alen = sizeof (struct sockaddr_in); | 1458 | alen = sizeof (struct sockaddr_in); |
1456 | if (is_nat_v4 (&s4->sin_addr)) | 1459 | if (is_nat_v4 (&s4.sin_addr)) |
1457 | is_nat = GNUNET_YES; | 1460 | is_nat = GNUNET_YES; |
1458 | port = ntohs (s4->sin_port); | 1461 | port = ntohs (s4.sin_port); |
1459 | } | 1462 | } |
1460 | break; | 1463 | break; |
1461 | case AF_INET6: | 1464 | case AF_INET6: |
1462 | { | 1465 | { |
1463 | const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) sa; | 1466 | struct sockaddr_in6 s6; |
1464 | 1467 | ||
1468 | GNUNET_memcpy (&s6, | ||
1469 | off, | ||
1470 | sizeof (struct sockaddr_in6)); | ||
1465 | alen = sizeof (struct sockaddr_in6); | 1471 | alen = sizeof (struct sockaddr_in6); |
1466 | if (is_nat_v6 (&s6->sin6_addr)) | 1472 | if (is_nat_v6 (&s6.sin6_addr)) |
1467 | is_nat = GNUNET_YES; | 1473 | is_nat = GNUNET_YES; |
1468 | port = ntohs (s6->sin6_port); | 1474 | port = ntohs (s6.sin6_port); |
1469 | } | 1475 | } |
1470 | break; | 1476 | break; |
1471 | #if AF_UNIX | 1477 | #if AF_UNIX |
@@ -1483,7 +1489,7 @@ handle_register (void *cls, | |||
1483 | GNUNET_assert (alen <= left); | 1489 | GNUNET_assert (alen <= left); |
1484 | GNUNET_assert (alen <= sizeof (struct sockaddr_storage)); | 1490 | GNUNET_assert (alen <= sizeof (struct sockaddr_storage)); |
1485 | GNUNET_memcpy (&ch->caddrs[i].ss, | 1491 | GNUNET_memcpy (&ch->caddrs[i].ss, |
1486 | sa, | 1492 | off, |
1487 | alen); | 1493 | alen); |
1488 | 1494 | ||
1489 | /* If applicable, try UPNPC NAT punching */ | 1495 | /* If applicable, try UPNPC NAT punching */ |
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c index 4d54a740b..e35115e31 100644 --- a/src/nse/gnunet-service-nse.c +++ b/src/nse/gnunet-service-nse.c | |||
@@ -437,7 +437,7 @@ handle_start (void *cls, | |||
437 | GNUNET_notification_context_add (nc, | 437 | GNUNET_notification_context_add (nc, |
438 | mq); | 438 | mq); |
439 | setup_estimate_message (&em); | 439 | setup_estimate_message (&em); |
440 | env = GNUNET_MQ_msg_copy (&em.header); | 440 | env = GNUNET_MQ_msg_copy (&em.header); |
441 | GNUNET_MQ_send (mq, | 441 | GNUNET_MQ_send (mq, |
442 | env); | 442 | env); |
443 | GNUNET_SERVICE_client_continue (client); | 443 | GNUNET_SERVICE_client_continue (client); |
@@ -607,14 +607,14 @@ transmit_task_cb (void *cls) | |||
607 | struct NSEPeerEntry *peer_entry = cls; | 607 | struct NSEPeerEntry *peer_entry = cls; |
608 | unsigned int idx; | 608 | unsigned int idx; |
609 | struct GNUNET_MQ_Envelope *env; | 609 | struct GNUNET_MQ_Envelope *env; |
610 | 610 | ||
611 | peer_entry->transmit_task = NULL; | 611 | peer_entry->transmit_task = NULL; |
612 | idx = estimate_index; | 612 | idx = estimate_index; |
613 | if (GNUNET_NO == peer_entry->previous_round) | 613 | if (GNUNET_NO == peer_entry->previous_round) |
614 | { | 614 | { |
615 | idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE; | 615 | idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE; |
616 | peer_entry->previous_round = GNUNET_YES; | 616 | peer_entry->previous_round = GNUNET_YES; |
617 | peer_entry->transmit_task | 617 | peer_entry->transmit_task |
618 | = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), | 618 | = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), |
619 | &transmit_task_cb, | 619 | &transmit_task_cb, |
620 | peer_entry); | 620 | peer_entry); |
@@ -652,12 +652,12 @@ transmit_task_cb (void *cls) | |||
652 | GNUNET_NO); | 652 | GNUNET_NO); |
653 | #if ENABLE_NSE_HISTOGRAM | 653 | #if ENABLE_NSE_HISTOGRAM |
654 | peer_entry->transmitted_messages++; | 654 | peer_entry->transmitted_messages++; |
655 | peer_entry->last_transmitted_size | 655 | peer_entry->last_transmitted_size |
656 | = ntohl(size_estimate_messages[idx].matching_bits); | 656 | = ntohl(size_estimate_messages[idx].matching_bits); |
657 | #endif | 657 | #endif |
658 | env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header); | 658 | env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header); |
659 | GNUNET_MQ_send (peer_entry->mq, | 659 | GNUNET_MQ_send (peer_entry->mq, |
660 | env); | 660 | env); |
661 | } | 661 | } |
662 | 662 | ||
663 | 663 | ||
@@ -811,11 +811,10 @@ update_flood_message (void *cls) | |||
811 | GNUNET_CONTAINER_multipeermap_iterate (peers, | 811 | GNUNET_CONTAINER_multipeermap_iterate (peers, |
812 | &schedule_current_round, | 812 | &schedule_current_round, |
813 | NULL); | 813 | NULL); |
814 | flood_task = | 814 | flood_task |
815 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | 815 | = GNUNET_SCHEDULER_add_at (next_timestamp, |
816 | (next_timestamp), | 816 | &update_flood_message, |
817 | &update_flood_message, | 817 | NULL); |
818 | NULL); | ||
819 | } | 818 | } |
820 | 819 | ||
821 | 820 | ||
@@ -1012,7 +1011,7 @@ update_flood_times (void *cls, | |||
1012 | { | 1011 | { |
1013 | /* still stuck in previous round, no point to update, check that | 1012 | /* still stuck in previous round, no point to update, check that |
1014 | * we are active here though... */ | 1013 | * we are active here though... */ |
1015 | if (NULL == peer_entry->transmit_task) | 1014 | if (NULL == peer_entry->transmit_task) |
1016 | { | 1015 | { |
1017 | GNUNET_break (0); | 1016 | GNUNET_break (0); |
1018 | } | 1017 | } |
@@ -1034,7 +1033,7 @@ update_flood_times (void *cls, | |||
1034 | /** | 1033 | /** |
1035 | * Core handler for size estimate flooding messages. | 1034 | * Core handler for size estimate flooding messages. |
1036 | * | 1035 | * |
1037 | * @param cls peer this message is from | 1036 | * @param cls peer this message is from |
1038 | * @param incoming_flood received message | 1037 | * @param incoming_flood received message |
1039 | */ | 1038 | */ |
1040 | static void | 1039 | static void |
@@ -1169,7 +1168,7 @@ handle_p2p_estimate (void *cls, | |||
1169 | /* push back our result now, that peer is spreading bad information... */ | 1168 | /* push back our result now, that peer is spreading bad information... */ |
1170 | if (NULL != peer_entry->transmit_task) | 1169 | if (NULL != peer_entry->transmit_task) |
1171 | GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); | 1170 | GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); |
1172 | peer_entry->transmit_task | 1171 | peer_entry->transmit_task |
1173 | = GNUNET_SCHEDULER_add_now (&transmit_task_cb, | 1172 | = GNUNET_SCHEDULER_add_now (&transmit_task_cb, |
1174 | peer_entry); | 1173 | peer_entry); |
1175 | /* Not closer than our most recent message, no need to do work here */ | 1174 | /* Not closer than our most recent message, no need to do work here */ |
@@ -1431,11 +1430,10 @@ core_init (void *cls, | |||
1431 | current_timestamp); | 1430 | current_timestamp); |
1432 | estimate_count++; | 1431 | estimate_count++; |
1433 | } | 1432 | } |
1434 | flood_task = | 1433 | flood_task |
1435 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | 1434 | = GNUNET_SCHEDULER_add_at (next_timestamp, |
1436 | (next_timestamp), | 1435 | &update_flood_message, |
1437 | &update_flood_message, | 1436 | NULL); |
1438 | NULL); | ||
1439 | } | 1437 | } |
1440 | 1438 | ||
1441 | 1439 | ||
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index d48f07e71..067ebce23 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c | |||
@@ -534,10 +534,10 @@ schedule_next_hello (void *cls) | |||
534 | 1, | 534 | 1, |
535 | GNUNET_NO); | 535 | GNUNET_NO); |
536 | /* prepare to send the next one */ | 536 | /* prepare to send the next one */ |
537 | if (NULL != pl->hello_delay_task) | ||
538 | GNUNET_SCHEDULER_cancel (pl->hello_delay_task); | ||
539 | pl->next_hello_allowed | 537 | pl->next_hello_allowed |
540 | = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY); | 538 | = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY); |
539 | if (NULL != pl->hello_delay_task) | ||
540 | GNUNET_SCHEDULER_cancel (pl->hello_delay_task); | ||
541 | pl->hello_delay_task | 541 | pl->hello_delay_task |
542 | = GNUNET_SCHEDULER_add_now (&schedule_next_hello, | 542 | = GNUNET_SCHEDULER_add_now (&schedule_next_hello, |
543 | pl); | 543 | pl); |
@@ -1022,7 +1022,7 @@ check_hello (void *cls, | |||
1022 | const struct GNUNET_HELLO_Message *message) | 1022 | const struct GNUNET_HELLO_Message *message) |
1023 | { | 1023 | { |
1024 | struct GNUNET_PeerIdentity pid; | 1024 | struct GNUNET_PeerIdentity pid; |
1025 | 1025 | ||
1026 | if (GNUNET_OK != | 1026 | if (GNUNET_OK != |
1027 | GNUNET_HELLO_get_id (message, | 1027 | GNUNET_HELLO_get_id (message, |
1028 | &pid)) | 1028 | &pid)) |
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c index f198d6e49..e68753583 100644 --- a/src/transport/gnunet-service-transport_manipulation.c +++ b/src/transport/gnunet-service-transport_manipulation.c | |||
@@ -219,7 +219,6 @@ send_delayed (void *cls) | |||
219 | struct DelayQueueEntry *dqe = cls; | 219 | struct DelayQueueEntry *dqe = cls; |
220 | struct DelayQueueEntry *next; | 220 | struct DelayQueueEntry *next; |
221 | struct TM_Peer *tmp = dqe->tmp; | 221 | struct TM_Peer *tmp = dqe->tmp; |
222 | struct GNUNET_TIME_Relative delay; | ||
223 | 222 | ||
224 | GNUNET_break (GNUNET_YES == | 223 | GNUNET_break (GNUNET_YES == |
225 | GST_neighbours_test_connected (&dqe->id)); | 224 | GST_neighbours_test_connected (&dqe->id)); |
@@ -233,9 +232,9 @@ send_delayed (void *cls) | |||
233 | if (NULL != next) | 232 | if (NULL != next) |
234 | { | 233 | { |
235 | /* More delayed messages */ | 234 | /* More delayed messages */ |
236 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | 235 | tmp->send_delay_task = GNUNET_SCHEDULER_add_at (next->sent_at, |
237 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | 236 | &send_delayed, |
238 | &send_delayed, next); | 237 | next); |
239 | } | 238 | } |
240 | } | 239 | } |
241 | else | 240 | else |
@@ -249,10 +248,9 @@ send_delayed (void *cls) | |||
249 | if (NULL != next) | 248 | if (NULL != next) |
250 | { | 249 | { |
251 | /* More delayed messages */ | 250 | /* More delayed messages */ |
252 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | 251 | generic_send_delay_task = GNUNET_SCHEDULER_add_at (next->sent_at, |
253 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, | 252 | &send_delayed, |
254 | &send_delayed, | 253 | next); |
255 | next); | ||
256 | } | 254 | } |
257 | } | 255 | } |
258 | GST_neighbours_send (&dqe->id, | 256 | GST_neighbours_send (&dqe->id, |
@@ -503,9 +501,9 @@ GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer) | |||
503 | generic_send_delay_task = NULL; | 501 | generic_send_delay_task = NULL; |
504 | if (NULL != generic_dqe_head) | 502 | if (NULL != generic_dqe_head) |
505 | generic_send_delay_task | 503 | generic_send_delay_task |
506 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at), | 504 | = GNUNET_SCHEDULER_add_at (generic_dqe_head->sent_at, |
507 | &send_delayed, | 505 | &send_delayed, |
508 | generic_dqe_head); | 506 | generic_dqe_head); |
509 | } | 507 | } |
510 | } | 508 | } |
511 | 509 | ||
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index e1e4f56f8..3952a728e 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -735,9 +735,9 @@ set_state_and_timeout (struct NeighbourMapEntry *n, | |||
735 | { | 735 | { |
736 | /* new timeout is earlier, reschedule master task */ | 736 | /* new timeout is earlier, reschedule master task */ |
737 | GNUNET_SCHEDULER_cancel (n->task); | 737 | GNUNET_SCHEDULER_cancel (n->task); |
738 | n->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (timeout), | 738 | n->task = GNUNET_SCHEDULER_add_at (timeout, |
739 | &master_task, | 739 | &master_task, |
740 | n); | 740 | n); |
741 | } | 741 | } |
742 | n->timeout = timeout; | 742 | n->timeout = timeout; |
743 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 743 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
diff --git a/src/util/.gitignore b/src/util/.gitignore index 87b379746..f207e07bf 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore | |||
@@ -62,3 +62,4 @@ test_speedup | |||
62 | test_strings | 62 | test_strings |
63 | test_strings_to_data | 63 | test_strings_to_data |
64 | test_time | 64 | test_time |
65 | test_socks.nc | ||
diff --git a/src/util/common_logging.c b/src/util/common_logging.c index ce229826e..7d5b50b8b 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c | |||
@@ -1164,7 +1164,7 @@ GNUNET_h2s (const struct GNUNET_HashCode * hc) | |||
1164 | const char * | 1164 | const char * |
1165 | GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc) | 1165 | GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc) |
1166 | { | 1166 | { |
1167 | static char buf[32]; | 1167 | static char buf[64]; |
1168 | 1168 | ||
1169 | GNUNET_STRINGS_data_to_string (shc, | 1169 | GNUNET_STRINGS_data_to_string (shc, |
1170 | sizeof (*shc), | 1170 | sizeof (*shc), |
@@ -1209,8 +1209,39 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid) | |||
1209 | static char buf[256]; | 1209 | static char buf[256]; |
1210 | char *ret; | 1210 | char *ret; |
1211 | 1211 | ||
1212 | if (NULL == pid) | ||
1213 | return "NULL"; | ||
1212 | ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); | 1214 | ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); |
1213 | strcpy (buf, ret); | 1215 | strcpy (buf, |
1216 | ret); | ||
1217 | GNUNET_free (ret); | ||
1218 | buf[4] = '\0'; | ||
1219 | return buf; | ||
1220 | } | ||
1221 | |||
1222 | |||
1223 | /** | ||
1224 | * Convert a peer identity to a string (for printing debug messages). | ||
1225 | * This is one of the very few calls in the entire API that is | ||
1226 | * NOT reentrant! Identical to #GNUNET_i2s(), except that another | ||
1227 | * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be | ||
1228 | * used within the same log statement. | ||
1229 | * | ||
1230 | * @param pid the peer identity | ||
1231 | * @return string form of the pid; will be overwritten by next | ||
1232 | * call to #GNUNET_i2s. | ||
1233 | */ | ||
1234 | const char * | ||
1235 | GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid) | ||
1236 | { | ||
1237 | static char buf[256]; | ||
1238 | char *ret; | ||
1239 | |||
1240 | if (NULL == pid) | ||
1241 | return "NULL"; | ||
1242 | ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key); | ||
1243 | strcpy (buf, | ||
1244 | ret); | ||
1214 | GNUNET_free (ret); | 1245 | GNUNET_free (ret); |
1215 | buf[4] = '\0'; | 1246 | buf[4] = '\0'; |
1216 | return buf; | 1247 | return buf; |
diff --git a/src/util/mq.c b/src/util/mq.c index 985e86331..d12f69e5f 100644 --- a/src/util/mq.c +++ b/src/util/mq.c | |||
@@ -811,12 +811,13 @@ GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, | |||
811 | * @param cb_cls closure for the callback | 811 | * @param cb_cls closure for the callback |
812 | */ | 812 | */ |
813 | void | 813 | void |
814 | GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *mqm, | 814 | GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *ev, |
815 | GNUNET_SCHEDULER_TaskCallback cb, | 815 | GNUNET_SCHEDULER_TaskCallback cb, |
816 | void *cb_cls) | 816 | void *cb_cls) |
817 | { | 817 | { |
818 | mqm->sent_cb = cb; | 818 | GNUNET_assert (NULL == ev->sent_cb); |
819 | mqm->sent_cls = cb_cls; | 819 | ev->sent_cb = cb; |
820 | ev->sent_cls = cb_cls; | ||
820 | } | 821 | } |
821 | 822 | ||
822 | 823 | ||
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index b016b91b7..409a0942f 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -155,7 +155,7 @@ struct GNUNET_SCHEDULER_Task | |||
155 | * Is this task run on shutdown? | 155 | * Is this task run on shutdown? |
156 | */ | 156 | */ |
157 | int on_shutdown; | 157 | int on_shutdown; |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * Is this task in the ready list? | 160 | * Is this task in the ready list? |
161 | */ | 161 | */ |
@@ -490,7 +490,7 @@ check_ready (const struct GNUNET_NETWORK_FDSet *rs, | |||
490 | 490 | ||
491 | 491 | ||
492 | /** | 492 | /** |
493 | * Request the shutdown of a scheduler. Marks all tasks | 493 | * Request the shutdown of a scheduler. Marks all tasks |
494 | * awaiting shutdown as ready. Note that tasks | 494 | * awaiting shutdown as ready. Note that tasks |
495 | * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call | 495 | * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call |
496 | * will be delayed until the next shutdown signal. | 496 | * will be delayed until the next shutdown signal. |
@@ -534,13 +534,13 @@ destroy_task (struct GNUNET_SCHEDULER_Task *t) | |||
534 | * Output stack trace of task @a t. | 534 | * Output stack trace of task @a t. |
535 | * | 535 | * |
536 | * @param t task to dump stack trace of | 536 | * @param t task to dump stack trace of |
537 | */ | 537 | */ |
538 | static void | 538 | static void |
539 | dump_backtrace (struct GNUNET_SCHEDULER_Task *t) | 539 | dump_backtrace (struct GNUNET_SCHEDULER_Task *t) |
540 | { | 540 | { |
541 | #if EXECINFO | 541 | #if EXECINFO |
542 | unsigned int i; | 542 | unsigned int i; |
543 | 543 | ||
544 | for (i = 0; i < t->num_backtrace_strings; i++) | 544 | for (i = 0; i < t->num_backtrace_strings; i++) |
545 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 545 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
546 | "Task %p trace %u: %s\n", | 546 | "Task %p trace %u: %s\n", |
@@ -1080,10 +1080,10 @@ GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback tas | |||
1080 | 1080 | ||
1081 | 1081 | ||
1082 | /** | 1082 | /** |
1083 | * Schedule a new task to be run with a specified delay. The task | 1083 | * Schedule a new task to be run at the specified time. The task |
1084 | * will be scheduled for execution once the delay has expired. | 1084 | * will be scheduled for execution at time @a at. |
1085 | * | 1085 | * |
1086 | * @param delay when should this operation time out? | 1086 | * @param at time when the operation should run |
1087 | * @param priority priority to use for the task | 1087 | * @param priority priority to use for the task |
1088 | * @param task main function of the task | 1088 | * @param task main function of the task |
1089 | * @param task_cls closure of @a task | 1089 | * @param task_cls closure of @a task |
@@ -1091,10 +1091,10 @@ GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback tas | |||
1091 | * only valid until @a task is started! | 1091 | * only valid until @a task is started! |
1092 | */ | 1092 | */ |
1093 | struct GNUNET_SCHEDULER_Task * | 1093 | struct GNUNET_SCHEDULER_Task * |
1094 | GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | 1094 | GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, |
1095 | enum GNUNET_SCHEDULER_Priority priority, | 1095 | enum GNUNET_SCHEDULER_Priority priority, |
1096 | GNUNET_SCHEDULER_TaskCallback task, | 1096 | GNUNET_SCHEDULER_TaskCallback task, |
1097 | void *task_cls) | 1097 | void *task_cls) |
1098 | { | 1098 | { |
1099 | struct GNUNET_SCHEDULER_Task *t; | 1099 | struct GNUNET_SCHEDULER_Task *t; |
1100 | struct GNUNET_SCHEDULER_Task *pos; | 1100 | struct GNUNET_SCHEDULER_Task *pos; |
@@ -1110,12 +1110,13 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | |||
1110 | #if PROFILE_DELAYS | 1110 | #if PROFILE_DELAYS |
1111 | t->start_time = GNUNET_TIME_absolute_get (); | 1111 | t->start_time = GNUNET_TIME_absolute_get (); |
1112 | #endif | 1112 | #endif |
1113 | t->timeout = GNUNET_TIME_relative_to_absolute (delay); | 1113 | t->timeout = at; |
1114 | t->priority = priority; | 1114 | t->priority = priority; |
1115 | t->lifeness = current_lifeness; | 1115 | t->lifeness = current_lifeness; |
1116 | /* try tail first (optimization in case we are | 1116 | /* try tail first (optimization in case we are |
1117 | * appending to a long list of tasks with timeouts) */ | 1117 | * appending to a long list of tasks with timeouts) */ |
1118 | if (0 == delay.rel_value_us) | 1118 | if ( (NULL == pending_timeout_head) || |
1119 | (at.abs_value_us < pending_timeout_head->timeout.abs_value_us) ) | ||
1119 | { | 1120 | { |
1120 | GNUNET_CONTAINER_DLL_insert (pending_timeout_head, | 1121 | GNUNET_CONTAINER_DLL_insert (pending_timeout_head, |
1121 | pending_timeout_tail, | 1122 | pending_timeout_tail, |
@@ -1144,9 +1145,9 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | |||
1144 | pending_timeout_tail, | 1145 | pending_timeout_tail, |
1145 | prev, | 1146 | prev, |
1146 | t); | 1147 | t); |
1147 | /* finally, update heuristic insertion point to last insertion... */ | ||
1148 | pending_timeout_last = t; | ||
1149 | } | 1148 | } |
1149 | /* finally, update heuristic insertion point to last insertion... */ | ||
1150 | pending_timeout_last = t; | ||
1150 | 1151 | ||
1151 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1152 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1152 | "Adding task: %p\n", | 1153 | "Adding task: %p\n", |
@@ -1157,6 +1158,30 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | |||
1157 | 1158 | ||
1158 | 1159 | ||
1159 | /** | 1160 | /** |
1161 | * Schedule a new task to be run with a specified delay. The task | ||
1162 | * will be scheduled for execution once the delay has expired. | ||
1163 | * | ||
1164 | * @param delay when should this operation time out? | ||
1165 | * @param priority priority to use for the task | ||
1166 | * @param task main function of the task | ||
1167 | * @param task_cls closure of @a task | ||
1168 | * @return unique task identifier for the job | ||
1169 | * only valid until @a task is started! | ||
1170 | */ | ||
1171 | struct GNUNET_SCHEDULER_Task * | ||
1172 | GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | ||
1173 | enum GNUNET_SCHEDULER_Priority priority, | ||
1174 | GNUNET_SCHEDULER_TaskCallback task, | ||
1175 | void *task_cls) | ||
1176 | { | ||
1177 | return GNUNET_SCHEDULER_add_at_with_priority (GNUNET_TIME_relative_to_absolute (delay), | ||
1178 | priority, | ||
1179 | task, | ||
1180 | task_cls); | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | /** | ||
1160 | * Schedule a new task to be run with a specified priority. | 1185 | * Schedule a new task to be run with a specified priority. |
1161 | * | 1186 | * |
1162 | * @param prio how important is the new task? | 1187 | * @param prio how important is the new task? |
@@ -1178,6 +1203,29 @@ GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, | |||
1178 | 1203 | ||
1179 | 1204 | ||
1180 | /** | 1205 | /** |
1206 | * Schedule a new task to be run at the specified time. The task | ||
1207 | * will be scheduled for execution once specified time has been | ||
1208 | * reached. It will be run with the DEFAULT priority. | ||
1209 | * | ||
1210 | * @param at time at which this operation should run | ||
1211 | * @param task main function of the task | ||
1212 | * @param task_cls closure of @a task | ||
1213 | * @return unique task identifier for the job | ||
1214 | * only valid until @a task is started! | ||
1215 | */ | ||
1216 | struct GNUNET_SCHEDULER_Task * | ||
1217 | GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at, | ||
1218 | GNUNET_SCHEDULER_TaskCallback task, | ||
1219 | void *task_cls) | ||
1220 | { | ||
1221 | return GNUNET_SCHEDULER_add_at_with_priority (at, | ||
1222 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1223 | task, | ||
1224 | task_cls); | ||
1225 | } | ||
1226 | |||
1227 | |||
1228 | /** | ||
1181 | * Schedule a new task to be run with a specified delay. The task | 1229 | * Schedule a new task to be run with a specified delay. The task |
1182 | * will be scheduled for execution once the delay has expired. It | 1230 | * will be scheduled for execution once the delay has expired. It |
1183 | * will be run with the DEFAULT priority. | 1231 | * will be run with the DEFAULT priority. |
@@ -1195,7 +1243,8 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, | |||
1195 | { | 1243 | { |
1196 | return GNUNET_SCHEDULER_add_delayed_with_priority (delay, | 1244 | return GNUNET_SCHEDULER_add_delayed_with_priority (delay, |
1197 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 1245 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
1198 | task, task_cls); | 1246 | task, |
1247 | task_cls); | ||
1199 | } | 1248 | } |
1200 | 1249 | ||
1201 | 1250 | ||
@@ -1391,7 +1440,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1391 | * scheduled for execution once either the delay has expired or the | 1440 | * scheduled for execution once either the delay has expired or the |
1392 | * socket operation is ready. It will be run with the DEFAULT priority. | 1441 | * socket operation is ready. It will be run with the DEFAULT priority. |
1393 | * | 1442 | * |
1394 | * @param delay when should this operation time out? | 1443 | * @param delay when should this operation time out? |
1395 | * @param rfd read file-descriptor | 1444 | * @param rfd read file-descriptor |
1396 | * @param task main function of the task | 1445 | * @param task main function of the task |
1397 | * @param task_cls closure of @a task | 1446 | * @param task_cls closure of @a task |
@@ -1640,7 +1689,7 @@ GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay, | |||
1640 | * </code> | 1689 | * </code> |
1641 | * | 1690 | * |
1642 | * @param prio how important is this task? | 1691 | * @param prio how important is this task? |
1643 | * @param delay how long should we wait? | 1692 | * @param delay how long should we wait? |
1644 | * @param rs set of file descriptors we want to read (can be NULL) | 1693 | * @param rs set of file descriptors we want to read (can be NULL) |
1645 | * @param ws set of file descriptors we want to write (can be NULL) | 1694 | * @param ws set of file descriptors we want to write (can be NULL) |
1646 | * @param task main function of the task | 1695 | * @param task main function of the task |
diff --git a/src/util/strings.c b/src/util/strings.c index 46eab856f..2b51d3e52 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -1354,7 +1354,7 @@ GNUNET_STRINGS_to_address_ip (const char *addr, | |||
1354 | 1354 | ||
1355 | 1355 | ||
1356 | /** | 1356 | /** |
1357 | * Parse an address given as a string into a | 1357 | * Parse an address given as a string into a |
1358 | * `struct sockaddr`. | 1358 | * `struct sockaddr`. |
1359 | * | 1359 | * |
1360 | * @param addr the address | 1360 | * @param addr the address |
@@ -1372,7 +1372,7 @@ GNUNET_STRINGS_parse_socket_addr (const char *addr, | |||
1372 | *af = AF_UNSPEC; | 1372 | *af = AF_UNSPEC; |
1373 | if ('[' == *addr) | 1373 | if ('[' == *addr) |
1374 | { | 1374 | { |
1375 | /* IPv6 */ | 1375 | /* IPv6 */ |
1376 | *sa = GNUNET_malloc (sizeof (struct sockaddr_in6)); | 1376 | *sa = GNUNET_malloc (sizeof (struct sockaddr_in6)); |
1377 | if (GNUNET_OK != | 1377 | if (GNUNET_OK != |
1378 | GNUNET_STRINGS_to_address_ipv6 (cp, | 1378 | GNUNET_STRINGS_to_address_ipv6 (cp, |