diff options
Diffstat (limited to 'src/conversation/gnunet-service-conversation.c')
-rw-r--r-- | src/conversation/gnunet-service-conversation.c | 859 |
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; | |||
55 | enum ChannelStatus | 55 | enum 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 | |||
180 | struct Line | 160 | struct 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 | */ |
238 | static struct GNUNET_PeerIdentity my_identity; | 214 | static struct GNUNET_PeerIdentity my_identity; |
239 | 215 | ||
240 | /** | ||
241 | * Head of DLL of active lines. | ||
242 | */ | ||
243 | static struct Line *lines_head; | ||
244 | |||
245 | /** | ||
246 | * Tail of DLL of active lines. | ||
247 | */ | ||
248 | static 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 | */ | ||
255 | static 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 | */ |
265 | static void | 225 | static struct Channel * |
266 | handle_client_register_message (void *cls, | 226 | find_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, | |||
366 | static void | 320 | static void |
367 | destroy_line_cadet_channels (struct Channel *ch) | 321 | destroy_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 | */ |
758 | static size_t | 731 | static void |
759 | transmit_line_audio (void *cls, | 732 | channel_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); |
892 | static void | 826 | /* FIXME: set options for unreliable transmission */ |
893 | mq_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 | */ |
911 | static int | 847 | static int |
912 | handle_cadet_ring_message (void *cls, | 848 | handle_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 | */ |
995 | static int | 916 | static int |
996 | handle_cadet_hangup_message (void *cls, | 917 | handle_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 | */ |
1054 | static int | 970 | static int |
1055 | handle_cadet_pickup_message (void *cls, | 971 | handle_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 | */ |
1125 | static int | 1027 | static int |
1126 | handle_cadet_suspend_message (void *cls, | 1028 | handle_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 | */ |
1250 | static int | 1151 | static int |
1251 | handle_cadet_audio_message (void *cls, | 1152 | handle_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 | */ |
1352 | static void * | 1204 | static void * |
1353 | inbound_channel (void *cls, | 1205 | inbound_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 | */ |
1476 | static void | 1342 | static void |
1477 | do_shutdown (void *cls) | 1343 | handle_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 | */ | ||
1381 | static void | ||
1382 | do_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); |