aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats-tests/.gitignore6
-rw-r--r--src/cadet/cadet.conf.in1
-rw-r--r--src/cadet/cadet.h35
-rw-r--r--src/cadet/cadet_api.c407
-rw-r--r--src/cadet/cadet_protocol.h39
-rw-r--r--src/cadet/gnunet-service-cadet-new.c544
-rw-r--r--src/cadet/gnunet-service-cadet-new.h23
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c1054
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.h82
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c110
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.h15
-rw-r--r--src/cadet/gnunet-service-cadet-new_core.c175
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.c50
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.h7
-rw-r--r--src/cadet/gnunet-service-cadet-new_hello.c16
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.c361
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.h4
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c594
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.h18
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c1078
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.h88
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c51
-rw-r--r--src/cadet/gnunet-service-cadet_channel.h4
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c10
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h2
-rw-r--r--src/cadet/gnunet-service-cadet_local.c153
-rw-r--r--src/cadet/gnunet-service-cadet_local.h14
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c4
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c67
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.h6
-rw-r--r--src/cadet/test_cadet.c116
-rw-r--r--src/cadet/test_cadet.conf2
-rw-r--r--src/cadet/test_cadet_local.c76
-rw-r--r--src/cadet/test_cadet_single.c97
-rw-r--r--src/core/core_api.c14
-rw-r--r--src/core/gnunet-service-core_sessions.c12
-rw-r--r--src/dht/gnunet-service-dht_clients.c15
-rw-r--r--src/fragmentation/fragmentation.c5
-rw-r--r--src/fs/gnunet-service-fs_pe.c8
-rw-r--r--src/include/gnunet_cadet_service.h165
-rw-r--r--src/include/gnunet_common.h16
-rw-r--r--src/include/gnunet_protocols.h10
-rw-r--r--src/include/gnunet_scheduler_lib.h45
-rw-r--r--src/nat/gnunet-service-nat.c22
-rw-r--r--src/nse/gnunet-service-nse.c34
-rw-r--r--src/topology/gnunet-daemon-topology.c6
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c20
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c6
-rw-r--r--src/util/.gitignore1
-rw-r--r--src/util/common_logging.c35
-rw-r--r--src/util/mq.c7
-rw-r--r--src/util/scheduler.c85
-rw-r--r--src/util/strings.c4
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
6perf_ats_proportional_transport_bandwidth 6perf_ats_proportional_transport_bandwidth
7perf_ats_proportional_transport_latency 7perf_ats_proportional_transport_latency
8perf_ats_proportional_transport_none 8perf_ats_proportional_transport_none
9perf_ats_mlp_core_bandwidth
10perf_ats_mlp_core_latency
11perf_ats_mlp_core_none
12perf_ats_mlp_transport_bandwidth
13perf_ats_mlp_transport_latency
14perf_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
5HOSTNAME = localhost 5HOSTNAME = localhost
6BINARY = gnunet-service-cadet 6BINARY = gnunet-service-cadet
7# PREFIX = valgrind --leak-check=yes
7ACCEPT_FROM = 127.0.0.1; 8ACCEPT_FROM = 127.0.0.1;
8ACCEPT_FROM6 = ::1; 9ACCEPT_FROM6 = ::1;
9UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock 10UNIXPATH = $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 */
138struct GNUNET_CADET_ChannelOpenMessageMessage 138struct 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 */
172struct GNUNET_CADET_ChannelDestroyMessage 172struct 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 */
231struct GNUNET_CADET_LocalInfo 231struct 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 */
259struct GNUNET_CADET_LocalInfoPeer 256struct 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 */
290struct GNUNET_CADET_LocalInfoTunnel 289struct 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 */
367static struct GNUNET_CADET_Channel * 362static struct GNUNET_CADET_Channel *
368retrieve_channel (struct GNUNET_CADET_Handle *h, 363retrieve_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 */
388static struct GNUNET_CADET_Channel * 383static struct GNUNET_CADET_Channel *
389create_channel (struct GNUNET_CADET_Handle *h, 384create_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!!!
434static void 428static void
435destroy_channel (struct GNUNET_CADET_Channel *ch, int call_cleaner) 429destroy_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
490add_to_queue (struct GNUNET_CADET_Handle *h, 489add_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 */
522static void
523send_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 */
589static void 572static void
590handle_channel_created (void *cls, 573handle_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 */
649static void 636static void
650handle_channel_destroy (void *cls, 637handle_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 */
1279static int 1256static int
1280do_reconnect (struct GNUNET_CADET_Handle *h) 1257do_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 */
1421void 1406void
1422GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) 1407GNUNET_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 */
1503struct GNUNET_CADET_Port * 1487struct 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 */
1571struct GNUNET_CADET_Channel * 1554struct 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
1607GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) 1590GNUNET_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 */
1747void 1738void
1748GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel) 1739GNUNET_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 */
90struct GNUNET_CADET_ConnectionCreateMessageAckMessage 90struct 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 */
384struct GNUNET_CADET_ChannelManageMessage 397struct 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
482struct GNUNET_CADET_ChannelAppDataMessage 496struct 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 */
111const struct GNUNET_CONFIGURATION_Handle *cfg;
112
113/**
118 * Handle to the statistics service. 114 * Handle to the statistics service.
119 */ 115 */
120struct GNUNET_STATISTICS_Handle *stats; 116struct GNUNET_STATISTICS_Handle *stats;
@@ -135,7 +131,7 @@ struct GNUNET_PeerIdentity my_full_id;
135struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 131struct 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 */
140int shutting_down; 136int shutting_down;
141 137
@@ -188,7 +184,6 @@ unsigned long long ratchet_messages;
188struct GNUNET_TIME_Relative ratchet_time; 184struct 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 */
228static struct CadetChannel *
229lookup_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 */
234static struct GNUNET_CADET_ClientChannelNumber 243static struct GNUNET_CADET_ClientChannelNumber
235client_get_next_lid (struct CadetClient *c) 244client_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 */
323static int
324destroy_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 */
347static int
348destroy_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 */
307static void 362static void
308shutdown_task (void *cls) 363shutdown_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 */
416static void
417shutdown_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 */
465static void 541static void
466handle_channel_create (void *cls, 542handle_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 */
530static struct GNUNET_CONTAINER_MultiHashMap32 *
531get_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 */
546static void 599static void
547handle_channel_destroy (void *cls, 600handle_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 */
588static int 637static int
589check_data (void *cls, 638check_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 */
621static void 693static void
622handle_data (void *cls, 694handle_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 */
667static void 737static void
668handle_ack (void *cls, 738handle_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 */
872static void 938static void
873handle_get_tunnels (void *cls, 939handle_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 */
893static void 962static void
894iter_connection (void *cls, 963iter_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 */
908static void 980static void
909iter_channel (void *cls, 981iter_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 */
927static void 999static void
928handle_show_tunnel (void *cls, 1000handle_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 */
1098static int 1171void
1099own_channel_destroy_iterator (void *cls, 1172GSC_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 */
1127static int 1199static int
1128incoming_channel_destroy_iterator (void *cls, 1200channel_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;
167struct CadetChannel; 168struct CadetChannel;
168 169
169/** 170/**
171 * Handle to our configuration.
172 */
173extern const struct GNUNET_CONFIGURATION_Handle *cfg;
174
175/**
170 * Handle to the statistics service. 176 * Handle to the statistics service.
171 */ 177 */
172extern struct GNUNET_STATISTICS_Handle *stats; 178extern struct GNUNET_STATISTICS_Handle *stats;
@@ -219,6 +225,10 @@ extern unsigned long long ratchet_messages;
219 */ 225 */
220extern struct GNUNET_TIME_Relative ratchet_time; 226extern struct GNUNET_TIME_Relative ratchet_time;
221 227
228/**
229 * Signal that shutdown is happening: prevent recovery measures.
230 */
231extern 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 */
252void
253GSC_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 */
168struct 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 */
161struct CadetChannel 206struct 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)
343struct GNUNET_CADET_ChannelTunnelNumber 372struct GNUNET_CADET_ChannelTunnelNumber
344GCCH_get_id (const struct CadetChannel *ch) 373GCCH_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 */
384static void
385free_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
356channel_destroy (struct CadetChannel *ch) 407channel_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 */
404static void 466static void
405send_create (void *cls); 467send_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 */
414static void 476static void
415create_sent_cb (void *cls) 477channel_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 */
432static void 501static void
433send_create (void *cls) 502send_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 */
542void
543GCCH_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 */
469struct CadetChannel * 565struct CadetChannel *
470GCCH_channel_local_new (struct CadetClient *owner, 566GCCH_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 */
527struct CadetChannel * 668struct CadetChannel *
528GCCH_channel_incoming_new (struct CadetTunnel *t, 669GCCH_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 */
598static void 744static void
599send_channel_ack (struct CadetChannel *ch) 745send_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 */
623static void 769static void
624send_connect_ack (void *cls) 770send_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 */
799void
800GCCH_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 */
832static void
833send_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 */
680void 932void
681GCCH_channel_local_destroy (struct CadetChannel *ch) 933GCCH_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 */
707void 992void
708GCCH_channel_incoming_destroy (struct CadetChannel *ch) 993GCCH_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 */
1048static int
1049is_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 */
1079void
1080GCCH_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 */
1190void
1191GCCH_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 */
742void 1251void
743GCCH_channel_remote_destroy (struct CadetChannel *ch) 1252GCCH_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 */
787static void
788GCCH_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 */
911int 1400int
912GCCH_handle_local_data (struct CadetChannel *ch, 1401GCCH_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 */
958static void 1485void
959send_client_buffered_data (struct CadetChannel *ch) 1486GCCH_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 */
1013void
1014GCCH_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 */
117void 119void
118GCCH_channel_local_destroy (struct CadetChannel *ch); 120GCCH_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 */
135void
136GCCH_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 */
131struct CadetChannel * 149struct CadetChannel *
132GCCH_channel_incoming_new (struct CadetTunnel *t, 150GCCH_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 */
163void
164GCCH_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 */
173void
174GCCH_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 */
185void
186GCCH_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 */
144void 196void
145GCCH_channel_incoming_destroy (struct CadetChannel *ch); 197GCCH_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 */
162void 214void
163GCCH_channel_remote_destroy (struct CadetChannel *ch); 215GCCH_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 */
178int 232int
179GCCH_handle_local_data (struct CadetChannel *ch, 233GCCH_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 */
188void 245void
189GCCH_handle_local_ack (struct CadetChannel *ch); 246GCCH_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 */
203void 217void
204GCC_handle_connection_ack (struct CadetConnection *cc) 218GCC_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
304send_create_ack (void *cls) 333send_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
560GCC_transmit (struct CadetConnection *cc, 604GCC_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 */
120void 120void
121GCC_handle_connection_ack (struct CadetConnection *cc); 121GCC_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 */
131void
132GCC_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)
260static void 284static void
261destroy_route (struct CadetRoute *route) 285destroy_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 */
482static void 543static void
483handle_connection_create_ack (void *cls, 544handle_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 */
612static void
613handle_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 */
655static void
656handle_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 */
217void
218GCD_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)
202void 235void
203GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) 236GCD_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)
308void 341void
309GCD_search_stop (struct GCD_search_handle *h) 342GCD_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 */
69void
70GCD_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 */
46static struct GNUNET_PEERINFO_NotifyContext* nc; 56static 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 */
75static void
76recalculate_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,
170static void 187static void
171path_destroy (struct CadetPeerPath *path) 188path_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 */
317static void 363static void
318extend_path (struct CadetPeerPath *path, 364extend_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 */
469struct CadetPeerPath * 574struct CadetPeerPath *
470GCPP_get_path_from_route (unsigned int path_length, 575GCPP_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 *
521GCPP_get_peer_at_offset (struct CadetPeerPath *path, 704GCPP_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 */
534char * 718const char *
535GCPP_2s (struct CadetPeerPath *path) 719GCPP_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 */
178char * 178const char *
179GCPP_2s (struct CadetPeerPath *p); 179GCPP_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 */
229const char * 230const char *
230GCP_2s (const struct CadetPeer *peer) 231GCP_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 */
307static void
308consider_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 */
374static void
375consider_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 */
384static void
385drop_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 */
402static void
403consider_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
296GCP_set_mq (struct CadetPeer *cp, 450GCP_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,
438void 626void
439GCP_destroy_all_peers () 627GCP_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 */
452static void
453consider_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 */
462static void 643void
463drop_paths (void *cls) 644GCP_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 */
480static void
481consider_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 */
587struct GNUNET_CONTAINER_HeapNode * 753struct GNUNET_CONTAINER_HeapNode *
588GCP_attach_path (struct CadetPeer *cp, 754GCP_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
668GCP_add_connection (struct CadetPeer *cp, 863GCP_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
686GCP_remove_connection (struct CadetPeer *cp, 885GCP_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 */
701static void
702consider_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 */
829unsigned int 974unsigned int
830GCP_count_paths (const struct CadetPeer *peer) 975GCP_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 */
844unsigned int 989unsigned int
845GCP_iterate_paths (struct CadetPeer *peer, 990GCP_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 */
879unsigned int 1041unsigned int
880GCP_iterate_paths_at (struct CadetPeer *peer, 1042GCP_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 */
911struct CadetTunnel * 1079struct CadetTunnel *
912GCP_get_tunnel (struct CadetPeer *peer, 1080GCP_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 */
1100static void
1101hello_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 */
933void 1116void
934GCP_set_hello (struct CadetPeer *peer, 1117GCP_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 */
950void 1160void
951GCP_drop_tunnel (struct CadetPeer *peer, 1161GCP_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
1041GCP_send_ooo (struct CadetPeer *cp, 1264GCP_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 */
99void
100GCP_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 */
132unsigned int 142unsigned int
133GCP_iterate_paths_at (struct CadetPeer *peer, 143GCP_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 */
199struct GNUNET_CONTAINER_HeapNode * 210struct GNUNET_CONTAINER_HeapNode *
200GCP_attach_path (struct CadetPeer *cp, 211GCP_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 */
430static const char *
431estate2s (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 */
448struct CadetChannel * 488struct CadetChannel *
449lookup_channel (struct CadetTunnel *t, 489lookup_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 */
478enum CadetTunnelCState 518static struct CadetTConnection *
479GCT_get_cstate (struct CadetTunnel *t) 519get_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 */
579static void
580trigger_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 */
1189static int
1190notify_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 */
1208void
1209GCT_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 &notify_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 */
1472static struct GNUNET_CADET_ChannelTunnelNumber
1473get_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
1316GCT_add_channel (struct CadetTunnel *t, 1512GCT_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 */
1603void
1604GCT_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 */
1634static int
1635destroy_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 */
1651void
1652GCT_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 */
1391static void 1674static void
1392connection_ready_cb (void *cls, 1675retry_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 */
1695static void
1696try_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 */
1433static void 1740static void
1434trigger_transmissions (struct CadetTunnel *t) 1741connection_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 */
1467static void 1800static void
1468maintain_connections_cb (void *cls) 1801trigger_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 */
1926static void
1927maintain_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 */
1646static void 2067static void
1647handle_plaintext_channel_create (void *cls, 2068handle_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 */
1661static void 2108void
1662handle_plaintext_channel_nack (void *cls, 2109GCT_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 */
1676static void 2136static void
1677handle_plaintext_channel_ack (void *cls, 2137handle_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,
1746struct CadetTunnel * 2239struct CadetTunnel *
1747GCT_create_tunnel (struct CadetPeer *destination) 2240GCT_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 */
1811void
1812GCT_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 */
1837void
1838GCT_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 */
2024void 2488void
2025GCT_send_cancel (struct CadetTunnelQueueEntry *q) 2489GCT_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 */
2146static const char *
2147cstate2s (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 */
2177static const char *
2178estate2s (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 */
44enum 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 */
77enum CadetTunnelEState 44enum 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 */
106void
107GCT_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 */
198void 166void
199GCT_remove_channel (struct CadetTunnel *t, 167GCT_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 */
178void
179GCT_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 */
309enum CadetTunnelCState
310GCT_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 */
1847int 1848int
1848GCCH_handle_local_create (struct CadetClient *c, 1849GCCH_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 *
2153GCCH_handle_create (struct CadetTunnel *t, 2154GCCH_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);
72struct GNUNET_CADET_ChannelTunnelNumber 72struct GNUNET_CADET_ChannelTunnelNumber
73GCCH_get_id (const struct CadetChannel *ch); 73GCCH_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);
82struct CadetTunnel * 83struct CadetTunnel *
83GCCH_get_tunnel (const struct CadetChannel *ch); 84GCCH_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 */
225int 227int
226GCCH_handle_local_create (struct CadetClient *c, 228GCCH_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
1054send_connection_ack (struct CadetConnection *c, int fwd) 1054send_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 */
2068void 2068void
2069GCC_handle_confirm (struct CadetPeer *peer, 2069GCC_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 */
137void 137void
138GCC_handle_confirm (struct CadetPeer *peer, 138GCC_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
472handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, 472handle_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 */
1221struct CadetChannel * 1220struct CadetChannel *
1222GML_channel_get (struct CadetClient *c, 1221GML_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 */
1252void 1251void
1253GML_channel_add (struct CadetClient *client, 1252GML_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 */
1277void 1276void
1278GML_channel_remove (struct CadetClient *client, 1277GML_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 */
1300struct GNUNET_CADET_ClientChannelNumber 1299struct GNUNET_CADET_ClientChannelNumber
1301GML_get_next_chid (struct CadetClient *c) 1300GML_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 */
1396void 1395void
1397GML_send_ack (struct CadetClient *c, 1396GML_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 */
1430void 1429void
1431GML_send_channel_create (struct CadetClient *c, 1430GML_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 */
1456void 1455void
1457GML_send_channel_nack (struct CadetClient *c, 1456GML_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 */
1483void 1482void
1484GML_send_channel_destroy (struct CadetClient *c, 1483GML_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 */
1511void 1510void
1512GML_send_data (struct CadetClient *c, 1511GML_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 (&copy[1], &msg[1], size); 1530 GNUNET_memcpy (&copy[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 &copy->header, GNUNET_NO); 1535 &copy->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 */
82struct CadetChannel * 82struct CadetChannel *
83GML_channel_get (struct CadetClient *c, 83GML_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 */
93void 93void
94GML_channel_add (struct CadetClient *client, 94GML_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 */
105void 105void
106GML_channel_remove (struct CadetClient *client, 106GML_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 */
117struct GNUNET_CADET_ClientChannelNumber 117struct GNUNET_CADET_ClientChannelNumber
118GML_get_next_chid (struct CadetClient *c); 118GML_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 */
492static void 492static void
493handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionCreateMessageAckMessage *msg) 493handle_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 */
2516struct CadetChannel * 2517struct CadetChannel *
2517GCT_get_channel (struct CadetTunnel *t, 2518GCT_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 */
2974struct GNUNET_CADET_ChannelTunnelNumber 2975struct GNUNET_CADET_ChannelTunnelNumber
2975GCT_get_next_chid (struct CadetTunnel *t) 2976GCT_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 */
293struct CadetChannel * 293struct CadetChannel *
294GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber chid); 294GCT_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 */
430struct GNUNET_CADET_ChannelTunnelNumber 430struct GNUNET_CADET_ChannelTunnelNumber
431GCT_get_next_chid (struct CadetTunnel *t); 431GCT_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 */
530size_t 530static size_t
531tmt_rdy (void *cls, size_t size, void *buf) 531tmt_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 */
605int 614static int
606data_callback (void *cls, struct GNUNET_CADET_Channel *channel, 615data_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 */
748static struct GNUNET_CADET_MessageHandler handlers[] = { 759static 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 */
766static void * 779static void *
767incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel, 780incoming_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 */
806static void 830static void
807channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel, 831channel_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]
36ENABLE_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);
64static void 64static void
65do_shutdown (void *cls) 65do_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 */
122static int 124static int
123data_callback (void *cls, struct GNUNET_CADET_Channel *channel, 125data_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
50static unsigned int repetition; 50static unsigned int repetition;
51 51
52static struct GNUNET_CADET_TransmitHandle *nth;
53
54static struct GNUNET_CADET_Port *port;
55
52 56
53/* forward declaration */ 57/* forward declaration */
54static size_t 58static size_t
@@ -61,7 +65,18 @@ do_send (void *cls, size_t size, void *buf);
61static void 65static void
62do_shutdown (void *cls) 66do_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 */
118static int 132static int
119data_callback (void *cls, struct GNUNET_CADET_Channel *channel, 133data_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 */
161static void * 179static void *
162inbound_channel (void *cls, struct GNUNET_CADET_Channel *channel, 180inbound_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 */
184static void 203static void
185channel_end (void *cls, const struct GNUNET_CADET_Channel *channel, 204channel_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 */
221static size_t 246static 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 */
302int 335int
303main (int argc, char *argv[]) 336main (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 *
687GC_u2h (uint32_t port); 692GC_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 */
708typedef 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 */
731typedef 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 */
747typedef 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 */
774struct GNUNET_CADET_Handle *
775GNUNET_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 */
789void
790GNUNET_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 */
803struct GNUNET_CADET_Port *
804GNUNET_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 */
815void
816GNUNET_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 */
828struct GNUNET_MQ_Handle *
829GNUNET_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
836struct GNUNET_CADET_Channel *
837GNUNET_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);
842void
843GNUNET_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 */
625const char *
626GNUNET_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 */
335struct GNUNET_SCHEDULER_Task *
336GNUNET_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 */
370struct GNUNET_SCHEDULER_Task *
371GNUNET_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 */
1040static void 1039static 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
62test_strings 62test_strings
63test_strings_to_data 63test_strings_to_data
64test_time 64test_time
65test_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)
1164const char * 1164const char *
1165GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc) 1165GNUNET_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 */
1234const char *
1235GNUNET_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 */
813void 813void
814GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *mqm, 814GNUNET_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 */
538static void 538static void
539dump_backtrace (struct GNUNET_SCHEDULER_Task *t) 539dump_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 */
1093struct GNUNET_SCHEDULER_Task * 1093struct GNUNET_SCHEDULER_Task *
1094GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, 1094GNUNET_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 */
1171struct GNUNET_SCHEDULER_Task *
1172GNUNET_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 */
1216struct GNUNET_SCHEDULER_Task *
1217GNUNET_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,