aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/gnunet-service-conversation.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-11 18:04:19 +0000
committerChristian Grothoff <christian@grothoff.org>2016-08-11 18:04:19 +0000
commit9c37ec935877bc6196febec8f6b2f0ad036189b9 (patch)
tree93b0ab56d432abb92fb10d4b5d0e01f6c1411333 /src/conversation/gnunet-service-conversation.c
parent7a5835e38561a55ea15d7caa9910bb6cdf0da79f (diff)
downloadgnunet-9c37ec935877bc6196febec8f6b2f0ad036189b9.tar.gz
gnunet-9c37ec935877bc6196febec8f6b2f0ad036189b9.zip
-converting API to use new CADET ports
Diffstat (limited to 'src/conversation/gnunet-service-conversation.c')
-rw-r--r--src/conversation/gnunet-service-conversation.c859
1 files changed, 372 insertions, 487 deletions
diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c
index b547d814c..baf35c9a2 100644
--- a/src/conversation/gnunet-service-conversation.c
+++ b/src/conversation/gnunet-service-conversation.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, 2016 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
@@ -55,6 +55,11 @@ struct Line;
55enum ChannelStatus 55enum ChannelStatus
56{ 56{
57 /** 57 /**
58 * We just got the connection, but no introduction yet.
59 */
60 CS_CALLEE_INIT,
61
62 /**
58 * Our phone is ringing, waiting for the client to pick up. 63 * Our phone is ringing, waiting for the client to pick up.
59 */ 64 */
60 CS_CALLEE_RINGING, 65 CS_CALLEE_RINGING,
@@ -112,51 +117,26 @@ struct Channel
112 struct Line *line; 117 struct Line *line;
113 118
114 /** 119 /**
115 * Handle for the reliable channel (contol data) 120 * Handle for the channel.
116 */
117 struct GNUNET_CADET_Channel *channel_reliable;
118
119 /**
120 * Handle for unreliable channel (audio data)
121 */
122 struct GNUNET_CADET_Channel *channel_unreliable;
123
124 /**
125 * Transmit handle for pending audio messages
126 */ 121 */
127 struct GNUNET_CADET_TransmitHandle *unreliable_mth; 122 struct GNUNET_CADET_Channel *channel;
128 123
129 /** 124 /**
130 * Message queue for control messages 125 * Message queue for control messages
131 */ 126 */
132 struct GNUNET_MQ_Handle *reliable_mq; 127 struct GNUNET_MQ_Handle *mq;
133 128
134 /** 129 /**
135 * Target of the line, if we are the caller. 130 * Temporary buffer for audio data in the @e mq.
136 */ 131 */
137 struct GNUNET_PeerIdentity target; 132 struct GNUNET_MQ_Envelope *env;
138 133
139 /** 134 /**
140 * Temporary buffer for audio data. 135 * Channel identifier we use for this call with the client.
141 */
142 void *audio_data;
143
144 /**
145 * Number of bytes in @e audio_data.
146 */
147 size_t audio_size;
148
149 /**
150 * Channel identifier.
151 */ 136 */
152 uint32_t cid; 137 uint32_t cid;
153 138
154 /** 139 /**
155 * Remote line number.
156 */
157 uint32_t remote_line;
158
159 /**
160 * Current status of this line. 140 * Current status of this line.
161 */ 141 */
162 enum ChannelStatus status; 142 enum ChannelStatus status;
@@ -180,16 +160,6 @@ struct Channel
180struct Line 160struct Line
181{ 161{
182 /** 162 /**
183 * Kept in a DLL.
184 */
185 struct Line *next;
186
187 /**
188 * Kept in a DLL.
189 */
190 struct Line *prev;
191
192 /**
193 * This is a DLL. 163 * This is a DLL.
194 */ 164 */
195 struct Channel *channel_head; 165 struct Channel *channel_head;
@@ -205,14 +175,20 @@ struct Line
205 struct GNUNET_SERVER_Client *client; 175 struct GNUNET_SERVER_Client *client;
206 176
207 /** 177 /**
208 * Generator for channel IDs. 178 * Our open port.
209 */ 179 */
210 uint32_t cid_gen; 180 struct GNUNET_CADET_Port *port;
211 181
212 /** 182 /**
213 * Our line number. 183 * Port number we are listening on (to verify signatures).
184 * Only valid if @e port is non-NULL.
214 */ 185 */
215 uint32_t local_line; 186 struct GNUNET_HashCode line_port;
187
188 /**
189 * Generator for channel IDs.
190 */
191 uint32_t cid_gen;
216 192
217}; 193};
218 194
@@ -237,56 +213,25 @@ static struct GNUNET_CADET_Handle *cadet;
237 */ 213 */
238static struct GNUNET_PeerIdentity my_identity; 214static struct GNUNET_PeerIdentity my_identity;
239 215
240/**
241 * Head of DLL of active lines.
242 */
243static struct Line *lines_head;
244
245/**
246 * Tail of DLL of active lines.
247 */
248static struct Line *lines_tail;
249
250/**
251 * Counter for generating local line numbers.
252 * FIXME: randomize generation in the future
253 * to eliminate information leakage.
254 */
255static uint32_t local_line_cnt;
256
257 216
258/** 217/**
259 * Function to register a phone. 218 * Given a @a cid, find the corresponding channel given
219 * a @a line.
260 * 220 *
261 * @param cls closure, NULL 221 * @param line a line to search
262 * @param client the client from which the message is 222 * @param cid what to search for
263 * @param message the message from the client 223 * @return NULL for not found
264 */ 224 */
265static void 225static struct Channel *
266handle_client_register_message (void *cls, 226find_channel_by_line (struct Line *line,
267 struct GNUNET_SERVER_Client *client, 227 uint32_t cid)
268 const struct GNUNET_MessageHeader *message)
269{ 228{
270 const struct ClientPhoneRegisterMessage *msg; 229 struct Channel *ch;
271 struct Line *line;
272 230
273 msg = (const struct ClientPhoneRegisterMessage *) message; 231 for (ch = line->channel_head; NULL != ch; ch = ch->next)
274 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 232 if (cid == ch->cid)
275 if (NULL != line) 233 return ch;
276 { 234 return NULL;
277 GNUNET_break (0);
278 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
279 return;
280 }
281 line = GNUNET_new (struct Line);
282 line->client = client;
283 GNUNET_SERVER_notification_context_add (nc, client);
284 GNUNET_SERVER_client_set_user_context (client, line);
285 GNUNET_CONTAINER_DLL_insert (lines_head,
286 lines_tail,
287 line);
288 line->local_line = ntohl (msg->line) & (~ HIGH_BIT);
289 GNUNET_SERVER_receive_done (client, GNUNET_OK);
290} 235}
291 236
292 237
@@ -309,7 +254,8 @@ handle_client_pickup_message (void *cls,
309 struct Channel *ch; 254 struct Channel *ch;
310 255
311 msg = (const struct ClientPhonePickupMessage *) message; 256 msg = (const struct ClientPhonePickupMessage *) message;
312 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 257 line = GNUNET_SERVER_client_get_user_context (client,
258 struct Line);
313 if (NULL == line) 259 if (NULL == line)
314 { 260 {
315 GNUNET_break (0); 261 GNUNET_break (0);
@@ -325,17 +271,24 @@ handle_client_pickup_message (void *cls,
325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
326 "Channel %u not found\n", 272 "Channel %u not found\n",
327 msg->cid); 273 msg->cid);
328 GNUNET_SERVER_receive_done (client, GNUNET_YES); 274 GNUNET_SERVER_receive_done (client,
275 GNUNET_YES);
329 return; 276 return;
330 } 277 }
331 switch (ch->status) 278 switch (ch->status)
332 { 279 {
280 case CS_CALLEE_INIT:
281 GNUNET_break (0);
282 GNUNET_SERVER_receive_done (client,
283 GNUNET_SYSERR);
284 return;
333 case CS_CALLEE_RINGING: 285 case CS_CALLEE_RINGING:
334 ch->status = CS_CALLEE_CONNECTED; 286 ch->status = CS_CALLEE_CONNECTED;
335 break; 287 break;
336 case CS_CALLEE_CONNECTED: 288 case CS_CALLEE_CONNECTED:
337 GNUNET_break (0); 289 GNUNET_break (0);
338 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 290 GNUNET_SERVER_receive_done (client,
291 GNUNET_SYSERR);
339 return; 292 return;
340 case CS_CALLEE_SHUTDOWN: 293 case CS_CALLEE_SHUTDOWN:
341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -353,8 +306,9 @@ handle_client_pickup_message (void *cls,
353 "Sending PICK_UP message to cadet\n"); 306 "Sending PICK_UP message to cadet\n");
354 e = GNUNET_MQ_msg (mppm, 307 e = GNUNET_MQ_msg (mppm,
355 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP); 308 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP);
356 GNUNET_MQ_send (ch->reliable_mq, e); 309 GNUNET_MQ_send (ch->mq, e);
357 GNUNET_SERVER_receive_done (client, GNUNET_OK); 310 GNUNET_SERVER_receive_done (client,
311 GNUNET_OK);
358} 312}
359 313
360 314
@@ -366,36 +320,15 @@ handle_client_pickup_message (void *cls,
366static void 320static void
367destroy_line_cadet_channels (struct Channel *ch) 321destroy_line_cadet_channels (struct Channel *ch)
368{ 322{
369 struct Line *line = ch->line;
370 struct GNUNET_CADET_Channel *t;
371
372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
373 "Destroying cadet channels\n"); 324 "Destroying cadet channels\n");
374 if (NULL != ch->reliable_mq) 325 if (NULL != ch->mq)
375 {
376 GNUNET_MQ_destroy (ch->reliable_mq);
377 ch->reliable_mq = NULL;
378 }
379 if (NULL != ch->unreliable_mth)
380 {
381 GNUNET_CADET_notify_transmit_ready_cancel (ch->unreliable_mth);
382 ch->unreliable_mth = NULL;
383 }
384 if (NULL != (t = ch->channel_unreliable))
385 {
386 ch->channel_unreliable = NULL;
387 GNUNET_CADET_channel_destroy (t);
388 }
389 if (NULL != (t = ch->channel_reliable))
390 { 326 {
391 ch->channel_reliable = NULL; 327 GNUNET_MQ_destroy (ch->mq);
392 GNUNET_CADET_channel_destroy (t); 328 ch->mq = NULL;
393 } 329 }
394 GNUNET_CONTAINER_DLL_remove (line->channel_head, 330 if (NULL != ch->channel)
395 line->channel_tail, 331 GNUNET_CADET_channel_destroy (ch->channel);
396 ch);
397 GNUNET_free_non_null (ch->audio_data);
398 GNUNET_free (ch);
399} 332}
400 333
401 334
@@ -412,6 +345,9 @@ mq_done_finish_caller_shutdown (void *cls)
412 345
413 switch (ch->status) 346 switch (ch->status)
414 { 347 {
348 case CS_CALLEE_INIT:
349 GNUNET_break (0);
350 break;
415 case CS_CALLEE_RINGING: 351 case CS_CALLEE_RINGING:
416 GNUNET_break (0); 352 GNUNET_break (0);
417 break; 353 break;
@@ -453,11 +389,13 @@ handle_client_hangup_message (void *cls,
453 struct Channel *ch; 389 struct Channel *ch;
454 390
455 msg = (const struct ClientPhoneHangupMessage *) message; 391 msg = (const struct ClientPhoneHangupMessage *) message;
456 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 392 line = GNUNET_SERVER_client_get_user_context (client,
393 struct Line);
457 if (NULL == line) 394 if (NULL == line)
458 { 395 {
459 GNUNET_break (0); 396 GNUNET_break (0);
460 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 397 GNUNET_SERVER_receive_done (client,
398 GNUNET_SYSERR);
461 return; 399 return;
462 } 400 }
463 for (ch = line->channel_head; NULL != ch; ch = ch->next) 401 for (ch = line->channel_head; NULL != ch; ch = ch->next)
@@ -469,7 +407,8 @@ handle_client_hangup_message (void *cls,
469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
470 "Channel %u not found\n", 408 "Channel %u not found\n",
471 msg->cid); 409 msg->cid);
472 GNUNET_SERVER_receive_done (client, GNUNET_OK); 410 GNUNET_SERVER_receive_done (client,
411 GNUNET_OK);
473 return; 412 return;
474 } 413 }
475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -478,6 +417,11 @@ handle_client_hangup_message (void *cls,
478 ch->status); 417 ch->status);
479 switch (ch->status) 418 switch (ch->status)
480 { 419 {
420 case CS_CALLEE_INIT:
421 GNUNET_break (0);
422 GNUNET_SERVER_receive_done (client,
423 GNUNET_SYSERR);
424 return;
481 case CS_CALLEE_RINGING: 425 case CS_CALLEE_RINGING:
482 ch->status = CS_CALLEE_SHUTDOWN; 426 ch->status = CS_CALLEE_SHUTDOWN;
483 break; 427 break;
@@ -486,7 +430,8 @@ handle_client_hangup_message (void *cls,
486 break; 430 break;
487 case CS_CALLEE_SHUTDOWN: 431 case CS_CALLEE_SHUTDOWN:
488 /* maybe the other peer closed asynchronously... */ 432 /* maybe the other peer closed asynchronously... */
489 GNUNET_SERVER_receive_done (client, GNUNET_OK); 433 GNUNET_SERVER_receive_done (client,
434 GNUNET_OK);
490 return; 435 return;
491 case CS_CALLER_CALLING: 436 case CS_CALLER_CALLING:
492 ch->status = CS_CALLER_SHUTDOWN; 437 ch->status = CS_CALLER_SHUTDOWN;
@@ -506,8 +451,10 @@ handle_client_hangup_message (void *cls,
506 GNUNET_MQ_notify_sent (e, 451 GNUNET_MQ_notify_sent (e,
507 &mq_done_finish_caller_shutdown, 452 &mq_done_finish_caller_shutdown,
508 ch); 453 ch);
509 GNUNET_MQ_send (ch->reliable_mq, e); 454 GNUNET_MQ_send (ch->mq,
510 GNUNET_SERVER_receive_done (client, GNUNET_OK); 455 e);
456 GNUNET_SERVER_receive_done (client,
457 GNUNET_OK);
511} 458}
512 459
513 460
@@ -530,11 +477,13 @@ handle_client_suspend_message (void *cls,
530 struct Channel *ch; 477 struct Channel *ch;
531 478
532 msg = (const struct ClientPhoneSuspendMessage *) message; 479 msg = (const struct ClientPhoneSuspendMessage *) message;
533 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 480 line = GNUNET_SERVER_client_get_user_context (client,
481 struct Line);
534 if (NULL == line) 482 if (NULL == line)
535 { 483 {
536 GNUNET_break (0); 484 GNUNET_break (0);
537 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 485 GNUNET_SERVER_receive_done (client,
486 GNUNET_SYSERR);
538 return; 487 return;
539 } 488 }
540 for (ch = line->channel_head; NULL != ch; ch = ch->next) 489 for (ch = line->channel_head; NULL != ch; ch = ch->next)
@@ -546,13 +495,15 @@ handle_client_suspend_message (void *cls,
546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
547 "Channel %u not found\n", 496 "Channel %u not found\n",
548 msg->cid); 497 msg->cid);
549 GNUNET_SERVER_receive_done (client, GNUNET_OK); 498 GNUNET_SERVER_receive_done (client,
499 GNUNET_OK);
550 return; 500 return;
551 } 501 }
552 if (GNUNET_YES == ch->suspended_local) 502 if (GNUNET_YES == ch->suspended_local)
553 { 503 {
554 GNUNET_break (0); 504 GNUNET_break (0);
555 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 505 GNUNET_SERVER_receive_done (client,
506 GNUNET_SYSERR);
556 return; 507 return;
557 } 508 }
558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -561,35 +512,46 @@ handle_client_suspend_message (void *cls,
561 ch->status); 512 ch->status);
562 switch (ch->status) 513 switch (ch->status)
563 { 514 {
515 case CS_CALLEE_INIT:
516 GNUNET_break (0);
517 GNUNET_SERVER_receive_done (client,
518 GNUNET_SYSERR);
519 return;
564 case CS_CALLEE_RINGING: 520 case CS_CALLEE_RINGING:
565 GNUNET_break (0); 521 GNUNET_break (0);
566 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 522 GNUNET_SERVER_receive_done (client,
523 GNUNET_SYSERR);
567 return; 524 return;
568 case CS_CALLEE_CONNECTED: 525 case CS_CALLEE_CONNECTED:
569 ch->suspended_local = GNUNET_YES; 526 ch->suspended_local = GNUNET_YES;
570 break; 527 break;
571 case CS_CALLEE_SHUTDOWN: 528 case CS_CALLEE_SHUTDOWN:
572 /* maybe the other peer closed asynchronously... */ 529 /* maybe the other peer closed asynchronously... */
573 GNUNET_SERVER_receive_done (client, GNUNET_OK); 530 GNUNET_SERVER_receive_done (client,
531 GNUNET_OK);
574 return; 532 return;
575 case CS_CALLER_CALLING: 533 case CS_CALLER_CALLING:
576 GNUNET_break (0); 534 GNUNET_break (0);
577 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 535 GNUNET_SERVER_receive_done (client,
536 GNUNET_SYSERR);
578 return; 537 return;
579 case CS_CALLER_CONNECTED: 538 case CS_CALLER_CONNECTED:
580 ch->suspended_local = GNUNET_YES; 539 ch->suspended_local = GNUNET_YES;
581 break; 540 break;
582 case CS_CALLER_SHUTDOWN: 541 case CS_CALLER_SHUTDOWN:
583 /* maybe the other peer closed asynchronously... */ 542 /* maybe the other peer closed asynchronously... */
584 GNUNET_SERVER_receive_done (client, GNUNET_OK); 543 GNUNET_SERVER_receive_done (client,
544 GNUNET_OK);
585 return; 545 return;
586 } 546 }
587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 547 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
588 "Sending SUSPEND message via cadet\n"); 548 "Sending SUSPEND message via cadet\n");
589 e = GNUNET_MQ_msg (mhum, 549 e = GNUNET_MQ_msg (mhum,
590 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND); 550 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND);
591 GNUNET_MQ_send (ch->reliable_mq, e); 551 GNUNET_MQ_send (ch->mq,
592 GNUNET_SERVER_receive_done (client, GNUNET_OK); 552 e);
553 GNUNET_SERVER_receive_done (client,
554 GNUNET_OK);
593} 555}
594 556
595 557
@@ -612,11 +574,13 @@ handle_client_resume_message (void *cls,
612 struct Channel *ch; 574 struct Channel *ch;
613 575
614 msg = (const struct ClientPhoneResumeMessage *) message; 576 msg = (const struct ClientPhoneResumeMessage *) message;
615 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 577 line = GNUNET_SERVER_client_get_user_context (client,
578 struct Line);
616 if (NULL == line) 579 if (NULL == line)
617 { 580 {
618 GNUNET_break (0); 581 GNUNET_break (0);
619 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 582 GNUNET_SERVER_receive_done (client,
583 GNUNET_SYSERR);
620 return; 584 return;
621 } 585 }
622 for (ch = line->channel_head; NULL != ch; ch = ch->next) 586 for (ch = line->channel_head; NULL != ch; ch = ch->next)
@@ -628,7 +592,8 @@ handle_client_resume_message (void *cls,
628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
629 "Channel %u not found\n", 593 "Channel %u not found\n",
630 msg->cid); 594 msg->cid);
631 GNUNET_SERVER_receive_done (client, GNUNET_OK); 595 GNUNET_SERVER_receive_done (client,
596 GNUNET_OK);
632 return; 597 return;
633 } 598 }
634 if (GNUNET_YES != ch->suspended_local) 599 if (GNUNET_YES != ch->suspended_local)
@@ -643,35 +608,46 @@ handle_client_resume_message (void *cls,
643 ch->status); 608 ch->status);
644 switch (ch->status) 609 switch (ch->status)
645 { 610 {
611 case CS_CALLEE_INIT:
612 GNUNET_break (0);
613 GNUNET_SERVER_receive_done (client,
614 GNUNET_SYSERR);
615 return;
646 case CS_CALLEE_RINGING: 616 case CS_CALLEE_RINGING:
647 GNUNET_break (0); 617 GNUNET_break (0);
648 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 618 GNUNET_SERVER_receive_done (client,
619 GNUNET_SYSERR);
649 return; 620 return;
650 case CS_CALLEE_CONNECTED: 621 case CS_CALLEE_CONNECTED:
651 ch->suspended_local = GNUNET_NO; 622 ch->suspended_local = GNUNET_NO;
652 break; 623 break;
653 case CS_CALLEE_SHUTDOWN: 624 case CS_CALLEE_SHUTDOWN:
654 /* maybe the other peer closed asynchronously... */ 625 /* maybe the other peer closed asynchronously... */
655 GNUNET_SERVER_receive_done (client, GNUNET_OK); 626 GNUNET_SERVER_receive_done (client,
627 GNUNET_OK);
656 return; 628 return;
657 case CS_CALLER_CALLING: 629 case CS_CALLER_CALLING:
658 GNUNET_break (0); 630 GNUNET_break (0);
659 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 631 GNUNET_SERVER_receive_done (client,
632 GNUNET_SYSERR);
660 return; 633 return;
661 case CS_CALLER_CONNECTED: 634 case CS_CALLER_CONNECTED:
662 ch->suspended_local = GNUNET_NO; 635 ch->suspended_local = GNUNET_NO;
663 break; 636 break;
664 case CS_CALLER_SHUTDOWN: 637 case CS_CALLER_SHUTDOWN:
665 /* maybe the other peer closed asynchronously... */ 638 /* maybe the other peer closed asynchronously... */
666 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 639 GNUNET_SERVER_receive_done (client,
640 GNUNET_SYSERR);
667 return; 641 return;
668 } 642 }
669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
670 "Sending RESUME message via cadet\n"); 644 "Sending RESUME message via cadet\n");
671 e = GNUNET_MQ_msg (mhum, 645 e = GNUNET_MQ_msg (mhum,
672 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME); 646 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME);
673 GNUNET_MQ_send (ch->reliable_mq, e); 647 GNUNET_MQ_send (ch->mq,
674 GNUNET_SERVER_receive_done (client, GNUNET_OK); 648 e);
649 GNUNET_SERVER_receive_done (client,
650 GNUNET_OK);
675} 651}
676 652
677 653
@@ -692,9 +668,11 @@ handle_client_call_message (void *cls,
692 struct Channel *ch; 668 struct Channel *ch;
693 struct GNUNET_MQ_Envelope *e; 669 struct GNUNET_MQ_Envelope *e;
694 struct CadetPhoneRingMessage *ring; 670 struct CadetPhoneRingMessage *ring;
671 struct CadetPhoneRingInfoPS rs;
695 672
696 msg = (const struct ClientCallMessage *) message; 673 msg = (const struct ClientCallMessage *) message;
697 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 674 line = GNUNET_SERVER_client_get_user_context (client,
675 struct Line);
698 if (NULL != line) 676 if (NULL != line)
699 { 677 {
700 GNUNET_break (0); 678 GNUNET_break (0);
@@ -703,86 +681,59 @@ handle_client_call_message (void *cls,
703 } 681 }
704 line = GNUNET_new (struct Line); 682 line = GNUNET_new (struct Line);
705 line->client = client; 683 line->client = client;
706 line->local_line = (local_line_cnt++) | HIGH_BIT; 684 line->line_port = msg->line_port;
707 GNUNET_SERVER_client_set_user_context (client, line); 685 GNUNET_SERVER_client_set_user_context (client,
708 GNUNET_SERVER_notification_context_add (nc, client); 686 line);
709 GNUNET_CONTAINER_DLL_insert (lines_head, 687 GNUNET_SERVER_notification_context_add (nc,
710 lines_tail, 688 client);
711 line); 689 rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
690 rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
691 rs.line_port = line->line_port;
692 rs.target_peer = msg->target;
693 rs.expiration_time
694 = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT));
695
712 ch = GNUNET_new (struct Channel); 696 ch = GNUNET_new (struct Channel);
713 ch->line = line; 697 ch->line = line;
714 GNUNET_CONTAINER_DLL_insert (line->channel_head, 698 GNUNET_CONTAINER_DLL_insert (line->channel_head,
715 line->channel_tail, 699 line->channel_tail,
716 ch); 700 ch);
717 ch->target = msg->target;
718 ch->remote_line = ntohl (msg->line);
719 ch->status = CS_CALLER_CALLING; 701 ch->status = CS_CALLER_CALLING;
720 ch->channel_reliable = GNUNET_CADET_channel_create (cadet, 702 ch->channel = GNUNET_CADET_channel_create (cadet,
721 ch, 703 ch,
722 &msg->target, 704 &msg->target,
723 GC_u2h (GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL), 705 &msg->line_port,
724 GNUNET_CADET_OPTION_RELIABLE); 706 GNUNET_CADET_OPTION_RELIABLE);
725 ch->reliable_mq = GNUNET_CADET_mq_create (ch->channel_reliable); 707 ch->mq = GNUNET_CADET_mq_create (ch->channel);
726 e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); 708 e = GNUNET_MQ_msg (ring,
727 ring->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); 709 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING);
728 ring->purpose.size = htonl (sizeof (struct GNUNET_PeerIdentity) * 2 +
729 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
730 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
731 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
732 GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, 710 GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id,
733 &ring->caller_id); 711 &ring->caller_id);
734 ring->remote_line = msg->line; 712 ring->expiration_time = rs.expiration_time;
735 ring->source_line = htonl (line->local_line);
736 ring->target = msg->target;
737 ring->source = my_identity;
738 ring->expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT));
739 GNUNET_assert (GNUNET_OK == 713 GNUNET_assert (GNUNET_OK ==
740 GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, 714 GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id,
741 &ring->purpose, 715 &rs.purpose,
742 &ring->signature)); 716 &ring->signature));
743 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
744 "Sending RING message via cadet\n"); 718 "Sending RING message via CADET\n");
745 GNUNET_MQ_send (ch->reliable_mq, e); 719 GNUNET_MQ_send (ch->mq,
746 GNUNET_SERVER_receive_done (client, GNUNET_OK); 720 e);
721 GNUNET_SERVER_receive_done (client,
722 GNUNET_OK);
747} 723}
748 724
749 725
750/** 726/**
751 * Transmit audio data via unreliable cadet channel. 727 * Transmission of audio data via cadet channel finished.
752 * 728 *
753 * @param cls the `struct Channel` we are transmitting for 729 * @param cls the `struct Channel` we are transmitting for
754 * @param size number of bytes available in @a buf
755 * @param buf where to copy the data
756 * @return number of bytes copied to @a buf
757 */ 730 */
758static size_t 731static void
759transmit_line_audio (void *cls, 732channel_audio_sent_notify (void *cls)
760 size_t size,
761 void *buf)
762{ 733{
763 struct Channel *ch = cls; 734 struct Channel *ch = cls;
764 struct CadetAudioMessage *mam = buf; 735
765 736 ch->env = NULL;
766 ch->unreliable_mth = NULL;
767 if ( (NULL == buf) ||
768 (size < sizeof (struct CadetAudioMessage) + ch->audio_size) )
769 {
770 /* eh, other error handling? */
771 return 0;
772 }
773 mam->header.size = htons (sizeof (struct CadetAudioMessage) + ch->audio_size);
774 mam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO);
775 mam->remote_line = htonl (ch->remote_line);
776 mam->source_line = htonl (ch->line->local_line);
777 GNUNET_memcpy (&mam[1], ch->audio_data, ch->audio_size);
778 GNUNET_free (ch->audio_data);
779 ch->audio_data = NULL;
780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
781 "Sending %u bytes of audio data from line %u to remote line %u via cadet\n",
782 (unsigned int) ch->audio_size,
783 ch->line->local_line,
784 ch->remote_line);
785 return sizeof (struct CadetAudioMessage) + ch->audio_size;
786} 737}
787 738
788 739
@@ -799,38 +750,43 @@ handle_client_audio_message (void *cls,
799 const struct GNUNET_MessageHeader *message) 750 const struct GNUNET_MessageHeader *message)
800{ 751{
801 const struct ClientAudioMessage *msg; 752 const struct ClientAudioMessage *msg;
753 struct ClientAudioMessage *mam;
802 struct Line *line; 754 struct Line *line;
803 struct Channel *ch; 755 struct Channel *ch;
804 size_t size; 756 size_t size;
805 757
806 size = ntohs (message->size) - sizeof (struct ClientAudioMessage); 758 size = ntohs (message->size) - sizeof (struct ClientAudioMessage);
807 msg = (const struct ClientAudioMessage *) message; 759 msg = (const struct ClientAudioMessage *) message;
808 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 760 line = GNUNET_SERVER_client_get_user_context (client,
761 struct Line);
809 if (NULL == line) 762 if (NULL == line)
810 { 763 {
811 GNUNET_break (0); 764 GNUNET_break (0);
812 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 765 GNUNET_SERVER_receive_done (client,
766 GNUNET_SYSERR);
813 return; 767 return;
814 } 768 }
815 for (ch = line->channel_head; NULL != ch; ch = ch->next) 769 ch = find_channel_by_line (line,
816 if (msg->cid == ch->cid) 770 msg->cid);
817 break;
818 if (NULL == ch) 771 if (NULL == ch)
819 { 772 {
820 /* could have been destroyed asynchronously, ignore message */ 773 /* could have been destroyed asynchronously, ignore message */
821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 774 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
822 "Channel %u not found\n", 775 "Channel %u not found\n",
823 msg->cid); 776 msg->cid);
824 GNUNET_SERVER_receive_done (client, GNUNET_OK); 777 GNUNET_SERVER_receive_done (client,
778 GNUNET_OK);
825 return; 779 return;
826 } 780 }
827 781
828 switch (ch->status) 782 switch (ch->status)
829 { 783 {
784 case CS_CALLEE_INIT:
830 case CS_CALLEE_RINGING: 785 case CS_CALLEE_RINGING:
831 case CS_CALLER_CALLING: 786 case CS_CALLER_CALLING:
832 GNUNET_break (0); 787 GNUNET_break (0);
833 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 788 GNUNET_SERVER_receive_done (client,
789 GNUNET_SYSERR);
834 return; 790 return;
835 case CS_CALLEE_CONNECTED: 791 case CS_CALLEE_CONNECTED:
836 case CS_CALLER_CONNECTED: 792 case CS_CALLER_CONNECTED:
@@ -840,61 +796,41 @@ handle_client_audio_message (void *cls,
840 case CS_CALLER_SHUTDOWN: 796 case CS_CALLER_SHUTDOWN:
841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
842 "Cadet audio channel in shutdown; audio data dropped\n"); 798 "Cadet audio channel in shutdown; audio data dropped\n");
843 GNUNET_SERVER_receive_done (client, GNUNET_OK); 799 GNUNET_SERVER_receive_done (client,
800 GNUNET_OK);
844 return; 801 return;
845 } 802 }
846 if (GNUNET_YES == ch->suspended_local) 803 if (GNUNET_YES == ch->suspended_local)
847 { 804 {
848 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "This channel is suspended locally\n"); 805 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
849 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 806 "This channel is suspended locally\n");
850 return; 807 GNUNET_SERVER_receive_done (client,
851 } 808 GNUNET_SYSERR);
852 if (NULL == ch->channel_unreliable)
853 {
854 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
855 _("Cadet audio channel not ready; audio data dropped\n"));
856 GNUNET_SERVER_receive_done (client, GNUNET_OK);
857 return; 809 return;
858 } 810 }
859 if (NULL != ch->unreliable_mth) 811 if (NULL != ch->env)
860 { 812 {
861 /* NOTE: we may want to not do this and instead combine the data */ 813 /* NOTE: we may want to not do this and instead combine the data */
862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 814 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
863 "Bandwidth insufficient; dropping previous audio data segment with %u bytes\n", 815 "Bandwidth insufficient; dropping previous audio data segment\n");
864 (unsigned int) ch->audio_size); 816 GNUNET_MQ_send_cancel (ch->env);
865 GNUNET_CADET_notify_transmit_ready_cancel (ch->unreliable_mth); 817 ch->env = NULL;
866 ch->unreliable_mth = NULL;
867 GNUNET_free (ch->audio_data);
868 ch->audio_data = NULL;
869 } 818 }
870 ch->audio_size = size;
871 ch->audio_data = GNUNET_malloc (ch->audio_size);
872 GNUNET_memcpy (ch->audio_data,
873 &msg[1],
874 size);
875 ch->unreliable_mth = GNUNET_CADET_notify_transmit_ready (ch->channel_unreliable,
876 GNUNET_NO,
877 GNUNET_TIME_UNIT_FOREVER_REL,
878 sizeof (struct CadetAudioMessage)
879 + ch->audio_size,
880 &transmit_line_audio,
881 ch);
882 GNUNET_SERVER_receive_done (client, GNUNET_OK);
883}
884
885 819
886/** 820 ch->env = GNUNET_MQ_msg_extra (mam,
887 * We are done signalling shutdown to the other peer. 821 size,
888 * Destroy the channel. 822 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO);
889 * 823 GNUNET_memcpy (&mam[1],
890 * @param cls the `struct GNUNET_CADET_channel` to destroy 824 &msg[1],
891 */ 825 size);
892static void 826 /* FIXME: set options for unreliable transmission */
893mq_done_destroy_channel (void *cls) 827 GNUNET_MQ_notify_sent (ch->env,
894{ 828 &channel_audio_sent_notify,
895 struct GNUNET_CADET_Channel *channel = cls; 829 ch);
896 830 GNUNET_MQ_send (ch->mq,
897 GNUNET_CADET_channel_destroy (channel); 831 ch->env);
832 GNUNET_SERVER_receive_done (client,
833 GNUNET_OK);
898} 834}
899 835
900 836
@@ -910,70 +846,55 @@ mq_done_destroy_channel (void *cls)
910 */ 846 */
911static int 847static int
912handle_cadet_ring_message (void *cls, 848handle_cadet_ring_message (void *cls,
913 struct GNUNET_CADET_Channel *channel, 849 struct GNUNET_CADET_Channel *channel,
914 void **channel_ctx, 850 void **channel_ctx,
915 const struct GNUNET_MessageHeader *message) 851 const struct GNUNET_MessageHeader *message)
916{ 852{
853 struct Channel *ch = *channel_ctx;
854 struct Line *line = ch->line;
917 const struct CadetPhoneRingMessage *msg; 855 const struct CadetPhoneRingMessage *msg;
918 struct Line *line;
919 struct Channel *ch;
920 struct GNUNET_MQ_Envelope *e;
921 struct CadetPhoneHangupMessage *hang_up;
922 struct ClientPhoneRingMessage cring; 856 struct ClientPhoneRingMessage cring;
923 struct GNUNET_MQ_Handle *reliable_mq; 857 struct CadetPhoneRingInfoPS rs;
924 858
925 msg = (const struct CadetPhoneRingMessage *) message; 859 msg = (const struct CadetPhoneRingMessage *) message;
926 if ( (msg->purpose.size != htonl (sizeof (struct GNUNET_PeerIdentity) * 2 + 860 rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
927 sizeof (struct GNUNET_TIME_AbsoluteNBO) + 861 rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
928 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 862 rs.line_port = line->line_port;
929 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) || 863 rs.target_peer = my_identity;
930 (GNUNET_OK != 864 rs.expiration_time = msg->expiration_time;
931 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, 865
932 &msg->purpose, 866 if (GNUNET_OK !=
867 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING,
868 &rs.purpose,
933 &msg->signature, 869 &msg->signature,
934 &msg->caller_id)) ) 870 &msg->caller_id))
935 { 871 {
936 GNUNET_break_op (0); 872 GNUNET_break_op (0);
937 return GNUNET_SYSERR; 873 return GNUNET_SYSERR;
938 } 874 }
939 GNUNET_CADET_receive_done (channel); /* needed? */ 875 if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (msg->expiration_time)).rel_value_us)
940 for (line = lines_head; NULL != line; line = line->next)
941 if (line->local_line == ntohl (msg->remote_line))
942 break;
943 if (NULL == line)
944 { 876 {
945 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 877 /* ancient call, replay? */
946 _("No available phone for incoming call on line %u, sending HANG_UP signal\n"), 878 GNUNET_break_op (0);
947 ntohl (msg->remote_line)); 879 /* Note that our reliance on time here is awkward; better would be
948 e = GNUNET_MQ_msg (hang_up, 880 to use a more complex challenge-response protocol against
949 GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP); 881 replay attacks. Left for future work ;-). */
950 GNUNET_MQ_notify_sent (e, 882 return GNUNET_SYSERR;
951 &mq_done_destroy_channel,
952 channel);
953 reliable_mq = GNUNET_CADET_mq_create (channel);
954 GNUNET_MQ_send (reliable_mq, e);
955 /* FIXME: do we need to clean up reliable_mq somehow/somewhere? */
956 return GNUNET_OK;
957 } 883 }
958 ch = GNUNET_new (struct Channel); 884 if (CS_CALLEE_INIT != ch->status)
959 ch->line = line; 885 {
960 GNUNET_CONTAINER_DLL_insert (line->channel_head, 886 GNUNET_break_op (0);
961 line->channel_tail, 887 return GNUNET_SYSERR;
962 ch); 888 }
889 GNUNET_CADET_receive_done (channel);
963 ch->status = CS_CALLEE_RINGING; 890 ch->status = CS_CALLEE_RINGING;
964 ch->remote_line = ntohl (msg->source_line);
965 ch->channel_reliable = channel;
966 ch->reliable_mq = GNUNET_CADET_mq_create (ch->channel_reliable);
967 ch->cid = line->cid_gen++;
968 ch->target = msg->source;
969 *channel_ctx = ch;
970 cring.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING); 891 cring.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING);
971 cring.header.size = htons (sizeof (cring)); 892 cring.header.size = htons (sizeof (cring));
972 cring.cid = ch->cid; 893 cring.cid = ch->cid;
973 cring.caller_id = msg->caller_id; 894 cring.caller_id = msg->caller_id;
974 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
975 "Sending RING message to client. CID %u:(%u, %u)\n", 896 "Sending RING message to client. CID is %u\n",
976 ch->cid, ch->remote_line, line->local_line); 897 (unsigned int) ch->cid);
977 GNUNET_SERVER_notification_context_unicast (nc, 898 GNUNET_SERVER_notification_context_unicast (nc,
978 line->client, 899 line->client,
979 &cring.header, 900 &cring.header,
@@ -994,31 +915,26 @@ handle_cadet_ring_message (void *cls,
994 */ 915 */
995static int 916static int
996handle_cadet_hangup_message (void *cls, 917handle_cadet_hangup_message (void *cls,
997 struct GNUNET_CADET_Channel *channel, 918 struct GNUNET_CADET_Channel *channel,
998 void **channel_ctx, 919 void **channel_ctx,
999 const struct GNUNET_MessageHeader *message) 920 const struct GNUNET_MessageHeader *message)
1000{ 921{
1001 struct Channel *ch = *channel_ctx; 922 struct Channel *ch = *channel_ctx;
1002 struct Line *line; 923 struct Line *line = ch->line;
1003 struct ClientPhoneHangupMessage hup; 924 struct ClientPhoneHangupMessage hup;
1004 enum ChannelStatus status; 925 enum ChannelStatus status;
1005 926
1006 if (NULL == ch) 927 GNUNET_CADET_receive_done (channel);
1007 {
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1009 "HANGUP message received for non-existing line, dropping channel.\n");
1010 return GNUNET_SYSERR;
1011 }
1012 line = ch->line;
1013 *channel_ctx = NULL;
1014 hup.header.size = htons (sizeof (hup)); 928 hup.header.size = htons (sizeof (hup));
1015 hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); 929 hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
1016 hup.cid = ch->cid; 930 hup.cid = ch->cid;
1017 status = ch->status; 931 status = ch->status;
1018 GNUNET_CADET_receive_done (channel);
1019 destroy_line_cadet_channels (ch); 932 destroy_line_cadet_channels (ch);
1020 switch (status) 933 switch (status)
1021 { 934 {
935 case CS_CALLEE_INIT:
936 GNUNET_break_op (0);
937 return GNUNET_OK;
1022 case CS_CALLEE_RINGING: 938 case CS_CALLEE_RINGING:
1023 case CS_CALLEE_CONNECTED: 939 case CS_CALLEE_CONNECTED:
1024 break; 940 break;
@@ -1053,24 +969,18 @@ handle_cadet_hangup_message (void *cls,
1053 */ 969 */
1054static int 970static int
1055handle_cadet_pickup_message (void *cls, 971handle_cadet_pickup_message (void *cls,
1056 struct GNUNET_CADET_Channel *channel, 972 struct GNUNET_CADET_Channel *channel,
1057 void **channel_ctx, 973 void **channel_ctx,
1058 const struct GNUNET_MessageHeader *message) 974 const struct GNUNET_MessageHeader *message)
1059{ 975{
1060 struct Channel *ch = *channel_ctx; 976 struct Channel *ch = *channel_ctx;
1061 struct Line *line; 977 struct Line *line = ch->line;
1062 struct ClientPhonePickedupMessage pick; 978 struct ClientPhonePickedupMessage pick;
1063 979
1064 if (NULL == ch)
1065 {
1066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1067 "PICKUP message received for non-existing channel, dropping channel.\n");
1068 return GNUNET_SYSERR;
1069 }
1070 line = ch->line;
1071 GNUNET_CADET_receive_done (channel); 980 GNUNET_CADET_receive_done (channel);
1072 switch (ch->status) 981 switch (ch->status)
1073 { 982 {
983 case CS_CALLEE_INIT:
1074 case CS_CALLEE_RINGING: 984 case CS_CALLEE_RINGING:
1075 case CS_CALLEE_CONNECTED: 985 case CS_CALLEE_CONNECTED:
1076 GNUNET_break_op (0); 986 GNUNET_break_op (0);
@@ -1093,21 +1003,13 @@ handle_cadet_pickup_message (void *cls,
1093 } 1003 }
1094 pick.header.size = htons (sizeof (pick)); 1004 pick.header.size = htons (sizeof (pick));
1095 pick.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP); 1005 pick.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
1006 pick.cid = ch->cid;
1096 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1007 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097 "Sending PICKED UP message to client\n"); 1008 "Sending PICKED UP message to client\n");
1098 GNUNET_SERVER_notification_context_unicast (nc, 1009 GNUNET_SERVER_notification_context_unicast (nc,
1099 line->client, 1010 line->client,
1100 &pick.header, 1011 &pick.header,
1101 GNUNET_NO); 1012 GNUNET_NO);
1102 ch->channel_unreliable = GNUNET_CADET_channel_create (cadet,
1103 ch,
1104 &ch->target,
1105 GC_u2h (GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO),
1106 GNUNET_CADET_OPTION_DEFAULT);
1107 if (NULL == ch->channel_unreliable)
1108 {
1109 GNUNET_break (0);
1110 }
1111 return GNUNET_OK; 1013 return GNUNET_OK;
1112} 1014}
1113 1015
@@ -1124,30 +1026,26 @@ handle_cadet_pickup_message (void *cls,
1124 */ 1026 */
1125static int 1027static int
1126handle_cadet_suspend_message (void *cls, 1028handle_cadet_suspend_message (void *cls,
1127 struct GNUNET_CADET_Channel *channel, 1029 struct GNUNET_CADET_Channel *channel,
1128 void **channel_ctx, 1030 void **channel_ctx,
1129 const struct GNUNET_MessageHeader *message) 1031 const struct GNUNET_MessageHeader *message)
1130{ 1032{
1131 struct Channel *ch = *channel_ctx; 1033 struct Channel *ch = *channel_ctx;
1132 struct Line *line; 1034 struct Line *line = ch->line;
1133 struct ClientPhoneSuspendMessage suspend; 1035 struct ClientPhoneSuspendMessage suspend;
1134 1036
1135 if (NULL == ch) 1037 GNUNET_CADET_receive_done (channel);
1136 {
1137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1138 "SUSPEND message received for non-existing line, dropping channel.\n");
1139 return GNUNET_SYSERR;
1140 }
1141 line = ch->line;
1142 suspend.header.size = htons (sizeof (suspend)); 1038 suspend.header.size = htons (sizeof (suspend));
1143 suspend.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND); 1039 suspend.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND);
1144 suspend.cid = ch->cid; 1040 suspend.cid = ch->cid;
1145 GNUNET_CADET_receive_done (channel);
1146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1147 "Suspending channel CID: %u(%u:%u)\n", 1042 "Suspending channel CID: %u\n",
1148 ch->cid, ch->remote_line, line->local_line); 1043 ch->cid);
1149 switch (ch->status) 1044 switch (ch->status)
1150 { 1045 {
1046 case CS_CALLEE_INIT:
1047 GNUNET_break_op (0);
1048 break;
1151 case CS_CALLEE_RINGING: 1049 case CS_CALLEE_RINGING:
1152 GNUNET_break_op (0); 1050 GNUNET_break_op (0);
1153 break; 1051 break;
@@ -1212,6 +1110,9 @@ handle_cadet_resume_message (void *cls,
1212 } 1110 }
1213 switch (ch->status) 1111 switch (ch->status)
1214 { 1112 {
1113 case CS_CALLEE_INIT:
1114 GNUNET_break (0);
1115 break;
1215 case CS_CALLEE_RINGING: 1116 case CS_CALLEE_RINGING:
1216 GNUNET_break (0); 1117 GNUNET_break (0);
1217 break; 1118 break;
@@ -1249,86 +1150,38 @@ handle_cadet_resume_message (void *cls,
1249 */ 1150 */
1250static int 1151static int
1251handle_cadet_audio_message (void *cls, 1152handle_cadet_audio_message (void *cls,
1252 struct GNUNET_CADET_Channel *channel, 1153 struct GNUNET_CADET_Channel *channel,
1253 void **channel_ctx, 1154 void **channel_ctx,
1254 const struct GNUNET_MessageHeader *message) 1155 const struct GNUNET_MessageHeader *message)
1255{ 1156{
1256 const struct CadetAudioMessage *msg;
1257 struct Channel *ch = *channel_ctx; 1157 struct Channel *ch = *channel_ctx;
1258 struct Line *line; 1158 const struct CadetAudioMessage *msg;
1259 struct GNUNET_PeerIdentity sender;
1260 size_t msize = ntohs (message->size) - sizeof (struct CadetAudioMessage); 1159 size_t msize = ntohs (message->size) - sizeof (struct CadetAudioMessage);
1261 char buf[msize + sizeof (struct ClientAudioMessage)]; 1160 char buf[msize + sizeof (struct ClientAudioMessage)] GNUNET_ALIGN;
1262 struct ClientAudioMessage *cam; 1161 struct ClientAudioMessage *cam;
1263 const union GNUNET_CADET_ChannelInfo *info;
1264 1162
1265 msg = (const struct CadetAudioMessage *) message; 1163 msg = (const struct CadetAudioMessage *) message;
1266 if (NULL == ch) 1164 GNUNET_CADET_receive_done (channel);
1165 if ( (GNUNET_YES == ch->suspended_local) ||
1166 (GNUNET_YES == ch->suspended_remote) )
1267 { 1167 {
1268 info = GNUNET_CADET_channel_get_info (channel, 1168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1269 GNUNET_CADET_OPTION_PEER); 1169 "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1270 if (NULL == info) 1170 (unsigned int) msize,
1271 { 1171 ch->cid);
1272 GNUNET_break (0); 1172 return GNUNET_OK;
1273 return GNUNET_SYSERR;
1274 }
1275 sender = info->peer;
1276 for (line = lines_head; NULL != line; line = line->next)
1277 if (line->local_line == ntohl (msg->remote_line))
1278 {
1279 for (ch = line->channel_head; NULL != ch; ch = ch->next)
1280 {
1281 if ( (CS_CALLEE_CONNECTED == ch->status) &&
1282 (0 == memcmp (&ch->target,
1283 &sender,
1284 sizeof (struct GNUNET_PeerIdentity))) &&
1285 (NULL == ch->channel_unreliable) &&
1286 (ch->remote_line == ntohl (msg->source_line)) )
1287 break;
1288 }
1289 break;
1290 }
1291 if (NULL == line)
1292 {
1293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1294 "Received %u bytes of AUDIO data for non-existing line %u, dropping.\n",
1295 (unsigned int) msize,
1296 ntohl (msg->remote_line));
1297 return GNUNET_SYSERR;
1298 }
1299 if (NULL == ch)
1300 {
1301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1302 "Received %u bytes of AUDIO data for unknown sender.\n",
1303 (unsigned int) msize);
1304 return GNUNET_SYSERR;
1305 }
1306 if ((GNUNET_YES == ch->suspended_local) || (GNUNET_YES == ch->suspended_remote))
1307 {
1308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1309 "Received %u bytes of AUDIO data on suspended channel CID %u:(%u:%u); dropping\n",
1310 (unsigned int) msize,
1311 ch->cid,
1312 ch->remote_line,
1313 line->local_line);
1314 GNUNET_CADET_receive_done (channel);
1315 return GNUNET_OK;
1316 }
1317 ch->channel_unreliable = channel;
1318 *channel_ctx = ch;
1319 } 1173 }
1320 GNUNET_CADET_receive_done (channel);
1321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1322 "Forwarding %u bytes of AUDIO data to client CID %u:(%u:%u)\n", 1175 "Forwarding %u bytes of AUDIO data to client CID %u\n",
1323 (unsigned int) msize, 1176 (unsigned int) msize,
1324 ch->cid, 1177 ch->cid);
1325 ch->remote_line,
1326 ch->line->local_line);
1327 cam = (struct ClientAudioMessage *) buf; 1178 cam = (struct ClientAudioMessage *) buf;
1328 cam->header.size = htons (sizeof (buf)); 1179 cam->header.size = htons (sizeof (buf));
1329 cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO); 1180 cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO);
1330 cam->cid = ch->cid; 1181 cam->cid = ch->cid;
1331 GNUNET_memcpy (&cam[1], &msg[1], msize); 1182 GNUNET_memcpy (&cam[1],
1183 &msg[1],
1184 msize);
1332 GNUNET_SERVER_notification_context_unicast (nc, 1185 GNUNET_SERVER_notification_context_unicast (nc,
1333 ch->line->client, 1186 ch->line->client,
1334 &cam->header, 1187 &cam->header,
@@ -1341,13 +1194,12 @@ handle_cadet_audio_message (void *cls,
1341 * Method called whenever another peer has added us to a channel 1194 * Method called whenever another peer has added us to a channel
1342 * the other peer initiated. 1195 * the other peer initiated.
1343 * 1196 *
1344 * @param cls closure 1197 * @param cls the `struct Line` receiving a connection
1345 * @param channel new handle to the channel 1198 * @param channel new handle to the channel
1346 * @param initiator peer that started the channel 1199 * @param initiator peer that started the channel
1347 * @param port port 1200 * @param port port
1348 * @param options channel option flags 1201 * @param options channel option flags
1349 * @return initial channel context for the channel; 1202 * @return initial channel context for the channel
1350 * (can be NULL -- that's not an error)
1351 */ 1203 */
1352static void * 1204static void *
1353inbound_channel (void *cls, 1205inbound_channel (void *cls,
@@ -1356,10 +1208,22 @@ inbound_channel (void *cls,
1356 const struct GNUNET_HashCode *port, 1208 const struct GNUNET_HashCode *port,
1357 enum GNUNET_CADET_ChannelOption options) 1209 enum GNUNET_CADET_ChannelOption options)
1358{ 1210{
1359 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1211 struct Line *line = cls;
1360 _("Received incoming Cadet channel on port %s\n"), 1212 struct Channel *ch;
1361 GNUNET_h2s (port)); 1213
1362 return NULL; 1214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1215 "Received incoming cadet channel on line %p\n",
1216 line);
1217 ch = GNUNET_new (struct Channel);
1218 ch->status = CS_CALLEE_INIT;
1219 ch->line = line;
1220 ch->channel = channel;
1221 ch->mq = GNUNET_CADET_mq_create (ch->channel);
1222 ch->cid = line->cid_gen++;
1223 GNUNET_CONTAINER_DLL_insert (line->channel_head,
1224 line->channel_tail,
1225 ch);
1226 return ch;
1363} 1227}
1364 1228
1365 1229
@@ -1379,63 +1243,53 @@ inbound_end (void *cls,
1379 void *channel_ctx) 1243 void *channel_ctx)
1380{ 1244{
1381 struct Channel *ch = channel_ctx; 1245 struct Channel *ch = channel_ctx;
1382 struct Line *line; 1246 struct Line *line = ch->line;
1383 struct ClientPhoneHangupMessage hup; 1247 struct ClientPhoneHangupMessage hup;
1384 1248
1385 if (NULL == ch) 1249 if (NULL == ch)
1386 { 1250 {
1387 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1251 GNUNET_break (0);
1388 "Cadet channel destroyed, but channel is unknown to us\n");
1389 return;
1390 }
1391 line = ch->line;
1392 if (ch->channel_unreliable == channel)
1393 {
1394 if (NULL != ch->unreliable_mth)
1395 {
1396 GNUNET_CADET_notify_transmit_ready_cancel (ch->unreliable_mth);
1397 ch->unreliable_mth = NULL;
1398 }
1399 ch->channel_unreliable = NULL;
1400 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1401 "Unreliable channel destroyed\n");
1402 return;
1403 }
1404 if (ch->channel_reliable != channel)
1405 {
1406 /* recursive call, I'm the one destroying 'ch' right now */
1407 return; 1252 return;
1408 } 1253 }
1409 ch->channel_reliable = NULL; 1254 GNUNET_assert (channel == ch->channel);
1410 1255 ch->channel = NULL;
1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1412 "Cadet channel destroyed by Cadet in state %d\n", 1257 "Channel destroyed by CADET in state %d\n",
1413 ch->status); 1258 ch->status);
1414 hup.header.size = htons (sizeof (hup)); 1259 hup.header.size = htons (sizeof (hup));
1415 hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); 1260 hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
1416 hup.cid = ch->cid; 1261 hup.cid = ch->cid;
1417 switch (ch->status) 1262 switch (ch->status)
1418 { 1263 {
1264 case CS_CALLEE_INIT:
1265 break;
1419 case CS_CALLEE_RINGING: 1266 case CS_CALLEE_RINGING:
1420 case CS_CALLEE_CONNECTED: 1267 case CS_CALLEE_CONNECTED:
1421 GNUNET_SERVER_notification_context_unicast (nc, 1268 if (NULL != line)
1422 line->client, 1269 GNUNET_SERVER_notification_context_unicast (nc,
1423 &hup.header, 1270 line->client,
1424 GNUNET_NO); 1271 &hup.header,
1272 GNUNET_NO);
1425 break; 1273 break;
1426 case CS_CALLEE_SHUTDOWN: 1274 case CS_CALLEE_SHUTDOWN:
1427 break; 1275 break;
1428 case CS_CALLER_CALLING: 1276 case CS_CALLER_CALLING:
1429 case CS_CALLER_CONNECTED: 1277 case CS_CALLER_CONNECTED:
1430 GNUNET_SERVER_notification_context_unicast (nc, 1278 if (NULL != line)
1431 line->client, 1279 GNUNET_SERVER_notification_context_unicast (nc,
1432 &hup.header, 1280 line->client,
1433 GNUNET_NO); 1281 &hup.header,
1282 GNUNET_NO);
1434 break; 1283 break;
1435 case CS_CALLER_SHUTDOWN: 1284 case CS_CALLER_SHUTDOWN:
1436 break; 1285 break;
1437 } 1286 }
1438 destroy_line_cadet_channels (ch); 1287 destroy_line_cadet_channels (ch);
1288 if (NULL != line)
1289 GNUNET_CONTAINER_DLL_remove (line->channel_head,
1290 line->channel_tail,
1291 ch);
1292 GNUNET_free (ch);
1439} 1293}
1440 1294
1441 1295
@@ -1450,45 +1304,83 @@ handle_client_disconnect (void *cls,
1450 struct GNUNET_SERVER_Client *client) 1304 struct GNUNET_SERVER_Client *client)
1451{ 1305{
1452 struct Line *line; 1306 struct Line *line;
1307 struct Channel *ch;
1308 struct Channel *chn;
1453 1309
1454 if (NULL == client) 1310 if (NULL == client)
1455 return; 1311 return;
1456 line = GNUNET_SERVER_client_get_user_context (client, struct Line); 1312 line = GNUNET_SERVER_client_get_user_context (client,
1313 struct Line);
1457 if (NULL == line) 1314 if (NULL == line)
1458 return; 1315 return;
1459 GNUNET_SERVER_client_set_user_context (client, NULL); 1316 GNUNET_SERVER_client_set_user_context (client,
1317 NULL);
1460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1461 "Client disconnected, closing line\n"); 1319 "Client disconnected, closing line\n");
1462 GNUNET_CONTAINER_DLL_remove (lines_head, 1320 if (NULL != line->port)
1463 lines_tail, 1321 {
1464 line); 1322 GNUNET_CADET_close_port (line->port);
1465 while (NULL != line->channel_head) 1323 line->port = NULL;
1466 destroy_line_cadet_channels (line->channel_head); 1324 }
1325 for (ch = line->channel_head; NULL != ch; ch = chn)
1326 {
1327 chn = ch->next;
1328 ch->line = NULL;
1329 destroy_line_cadet_channels (ch);
1330 }
1467 GNUNET_free (line); 1331 GNUNET_free (line);
1468} 1332}
1469 1333
1470 1334
1471/** 1335/**
1472 * Shutdown nicely 1336 * Function to register a phone.
1473 * 1337 *
1474 * @param cls closure, NULL 1338 * @param cls closure, NULL
1339 * @param client the client from which the message is
1340 * @param message the message from the client
1475 */ 1341 */
1476static void 1342static void
1477do_shutdown (void *cls) 1343handle_client_register_message (void *cls,
1344 struct GNUNET_SERVER_Client *client,
1345 const struct GNUNET_MessageHeader *message)
1478{ 1346{
1347 const struct ClientPhoneRegisterMessage *msg;
1479 struct Line *line; 1348 struct Line *line;
1480 struct Channel *ch;
1481 1349
1482 while (NULL != (line = lines_head)) 1350 msg = (const struct ClientPhoneRegisterMessage *) message;
1351 line = GNUNET_SERVER_client_get_user_context (client,
1352 struct Line);
1353 if (NULL != line)
1483 { 1354 {
1484 while (NULL != (ch = line->channel_head)) 1355 GNUNET_break (0);
1485 destroy_line_cadet_channels (ch); 1356 GNUNET_SERVER_receive_done (client,
1486 GNUNET_CONTAINER_DLL_remove (lines_head, 1357 GNUNET_SYSERR);
1487 lines_tail, 1358 return;
1488 line);
1489 GNUNET_SERVER_client_set_user_context (line->client, NULL);
1490 GNUNET_free (line);
1491 } 1359 }
1360 line = GNUNET_new (struct Line);
1361 line->client = client;
1362 GNUNET_SERVER_notification_context_add (nc,
1363 client);
1364 GNUNET_SERVER_client_set_user_context (client,
1365 line);
1366 line->line_port = msg->line_port;
1367 line->port = GNUNET_CADET_open_port (cadet,
1368 &msg->line_port,
1369 &inbound_channel,
1370 line);
1371 GNUNET_SERVER_receive_done (client,
1372 GNUNET_OK);
1373}
1374
1375
1376/**
1377 * Shutdown nicely
1378 *
1379 * @param cls closure, NULL
1380 */
1381static void
1382do_shutdown (void *cls)
1383{
1492 if (NULL != cadet) 1384 if (NULL != cadet)
1493 { 1385 {
1494 GNUNET_CADET_disconnect (cadet); 1386 GNUNET_CADET_disconnect (cadet);
@@ -1564,26 +1456,19 @@ run (void *cls,
1564 GNUNET_CRYPTO_get_peer_identity (cfg, 1456 GNUNET_CRYPTO_get_peer_identity (cfg,
1565 &my_identity)); 1457 &my_identity));
1566 cadet = GNUNET_CADET_connect (cfg, 1458 cadet = GNUNET_CADET_connect (cfg,
1567 NULL, 1459 NULL,
1568 &inbound_end, 1460 &inbound_end,
1569 cadet_handlers); 1461 cadet_handlers);
1570
1571 if (NULL == cadet) 1462 if (NULL == cadet)
1572 { 1463 {
1573 GNUNET_break (0); 1464 GNUNET_break (0);
1574 GNUNET_SCHEDULER_shutdown (); 1465 GNUNET_SCHEDULER_shutdown ();
1575 return; 1466 return;
1576 } 1467 }
1577 1468 nc = GNUNET_SERVER_notification_context_create (server,
1578 GNUNET_CADET_open_port (cadet, 1469 16);
1579 GC_u2h (GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL), 1470 GNUNET_SERVER_add_handlers (server,
1580 &inbound_channel, NULL); 1471 server_handlers);
1581 GNUNET_CADET_open_port (cadet,
1582 GC_u2h (GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO),
1583 &inbound_channel, NULL);
1584
1585 nc = GNUNET_SERVER_notification_context_create (server, 16);
1586 GNUNET_SERVER_add_handlers (server, server_handlers);
1587 GNUNET_SERVER_disconnect_notify (server, 1472 GNUNET_SERVER_disconnect_notify (server,
1588 &handle_client_disconnect, 1473 &handle_client_disconnect,
1589 NULL); 1474 NULL);