GNUnet 0.22.2
gnunet-service-conversation.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2016, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_signatures.h"
32#include "conversation.h"
33
34
40#define RING_TIMEOUT GNUNET_TIME_UNIT_DAYS
41
42
47struct Line;
48
53{
58
63
68
73
78
83
88};
89
90
97struct Channel
98{
102 struct Channel *next;
103
107 struct Channel *prev;
108
112 struct Line *line;
113
118
123
128
132 uint32_t cid;
133
138
143
148};
149
150
154struct Line
155{
160
165
170
175
180
186
190 uint32_t cid_gen;
191};
192
193
197static const struct GNUNET_CONFIGURATION_Handle *cfg;
198
203
208
209
218static struct Channel *
220{
221 for (struct Channel *ch = line->channel_head; NULL != ch; ch = ch->next)
222 if (cid == ch->cid)
223 return ch;
224 return NULL;
225}
226
227
234static void
236 const struct ClientPhonePickupMessage *msg)
237{
238 struct Line *line = cls;
239 struct CadetPhonePickupMessage *mppm;
240 struct GNUNET_MQ_Envelope *env;
241 struct Channel *ch;
242
243 if (NULL == line->port)
244 {
245 /* we never opened the port, bad client! */
246 GNUNET_break_op (0);
248 return;
249 }
250 for (ch = line->channel_head; NULL != ch; ch = ch->next)
251 if (msg->cid == ch->cid)
252 break;
253 if (NULL == ch)
254 {
255 /* could have been destroyed asynchronously, ignore message */
256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
258 return;
259 }
260 switch (ch->status)
261 {
262 case CS_CALLEE_INIT:
263 GNUNET_break (0);
265 return;
266
268 ch->status = CS_CALLEE_CONNECTED;
269 break;
270
272 GNUNET_break (0);
274 return;
275
278 "Ignoring client's PICKUP message, line is in SHUTDOWN\n");
279 break;
280
284 GNUNET_break (0);
286 return;
287 }
289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICK_UP message to cadet\n");
290 env =
294}
295
296
303static void
305{
306 struct Line *line = ch->line;
307 struct GNUNET_MQ_Envelope *env;
308 struct ClientPhoneHangupMessage *hup;
309
310 switch (ch->status)
311 {
312 case CS_CALLEE_INIT:
315 break;
316
321 if (NULL != line)
322 {
323 env =
325 hup->cid = ch->cid;
326 GNUNET_MQ_send (line->mq, env);
327 }
328 break;
329 }
330 if (NULL != line)
331 GNUNET_CONTAINER_DLL_remove (line->channel_head, line->channel_tail, ch);
332 GNUNET_free (ch);
333}
334
335
341static void
343{
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying cadet channels\n");
345 if (NULL != ch->channel)
346 {
348 ch->channel = NULL;
349 }
351}
352
353
360static void
362{
363 struct Channel *ch = cls;
364
365 switch (ch->status)
366 {
367 case CS_CALLEE_INIT:
368 GNUNET_break (0);
369 break;
370
372 GNUNET_break (0);
373 break;
374
376 GNUNET_break (0);
377 break;
378
381 break;
382
384 GNUNET_break (0);
385 break;
386
388 GNUNET_break (0);
389 break;
390
393 break;
394 }
395}
396
397
404static void
406 const struct ClientPhoneHangupMessage *msg)
407{
408 struct Line *line = cls;
409 struct GNUNET_MQ_Envelope *e;
410 struct CadetPhoneHangupMessage *mhum;
411 struct Channel *ch;
412
413 for (ch = line->channel_head; NULL != ch; ch = ch->next)
414 if (msg->cid == ch->cid)
415 break;
416 if (NULL == ch)
417 {
418 /* could have been destroyed asynchronously, ignore message */
419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
421 return;
422 }
424 "Received HANGUP for channel %u which is in state %d\n",
425 msg->cid,
426 ch->status);
427 switch (ch->status)
428 {
429 case CS_CALLEE_INIT:
430 GNUNET_break (0);
432 return;
433
435 ch->status = CS_CALLEE_SHUTDOWN;
436 break;
437
439 ch->status = CS_CALLEE_SHUTDOWN;
440 break;
441
443 /* maybe the other peer closed asynchronously... */
445 return;
446
448 ch->status = CS_CALLER_SHUTDOWN;
449 break;
450
452 ch->status = CS_CALLER_SHUTDOWN;
453 break;
454
456 /* maybe the other peer closed asynchronously... */
458 return;
459 }
460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG_UP message via cadet\n");
461 e =
464 GNUNET_MQ_send (ch->mq, e);
466}
467
468
475static void
477 const struct ClientPhoneSuspendMessage *msg)
478{
479 struct Line *line = cls;
480 struct GNUNET_MQ_Envelope *e;
481 struct CadetPhoneSuspendMessage *mhum;
482 struct Channel *ch;
483
484 for (ch = line->channel_head; NULL != ch; ch = ch->next)
485 if (msg->cid == ch->cid)
486 break;
487 if (NULL == ch)
488 {
489 /* could have been destroyed asynchronously, ignore message */
490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
492 return;
493 }
494 if (GNUNET_YES == ch->suspended_local)
495 {
496 GNUNET_break (0);
498 return;
499 }
501 "Received SUSPEND for channel %u which is in state %d\n",
502 msg->cid,
503 ch->status);
504 switch (ch->status)
505 {
506 case CS_CALLEE_INIT:
507 GNUNET_break (0);
509 return;
510
512 GNUNET_break (0);
514 return;
515
517 ch->suspended_local = GNUNET_YES;
518 break;
519
521 /* maybe the other peer closed asynchronously... */
523 return;
524
526 GNUNET_break (0);
528 return;
529
531 ch->suspended_local = GNUNET_YES;
532 break;
533
535 /* maybe the other peer closed asynchronously... */
537 return;
538 }
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUSPEND message via cadet\n");
540 e =
542 GNUNET_MQ_send (ch->mq, e);
544}
545
546
553static void
555 const struct ClientPhoneResumeMessage *msg)
556{
557 struct Line *line = cls;
558 struct GNUNET_MQ_Envelope *e;
559 struct CadetPhoneResumeMessage *mhum;
560 struct Channel *ch;
561
562 for (ch = line->channel_head; NULL != ch; ch = ch->next)
563 if (msg->cid == ch->cid)
564 break;
565 if (NULL == ch)
566 {
567 /* could have been destroyed asynchronously, ignore message */
568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
570 return;
571 }
572 if (GNUNET_YES != ch->suspended_local)
573 {
574 GNUNET_break (0);
576 return;
577 }
579 "Received RESUME for channel %u which is in state %d\n",
580 msg->cid,
581 ch->status);
582 switch (ch->status)
583 {
584 case CS_CALLEE_INIT:
585 GNUNET_break (0);
587 return;
588
590 GNUNET_break (0);
592 return;
593
595 ch->suspended_local = GNUNET_NO;
596 break;
597
599 /* maybe the other peer closed asynchronously... */
601 return;
602
604 GNUNET_break (0);
606 return;
607
609 ch->suspended_local = GNUNET_NO;
610 break;
611
613 /* maybe the other peer closed asynchronously... */
615 return;
616 }
617 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RESUME message via cadet\n");
619 GNUNET_MQ_send (ch->mq, e);
621}
622
623
629static void
631{
632 struct Channel *ch = cls;
633
634 ch->env = NULL;
635}
636
637
645static int
647{
648 (void) cls;
649 (void) msg;
650 return GNUNET_OK;
651}
652
653
660static void
662{
663 struct Line *line = cls;
664 struct CadetAudioMessage *mam;
665 struct Channel *ch;
666 size_t size;
667
668 size = ntohs (msg->header.size) - sizeof(struct ClientAudioMessage);
670 if (NULL == ch)
671 {
672 /* could have been destroyed asynchronously, ignore message */
673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
675 return;
676 }
677
678 switch (ch->status)
679 {
680 case CS_CALLEE_INIT:
683 GNUNET_break (0);
685 return;
686
689 /* common case, handled below */
690 break;
691
695 "Cadet audio channel in shutdown; audio data dropped\n");
697 return;
698 }
699 if (GNUNET_YES == ch->suspended_local)
700 {
702 "This channel is suspended locally\n");
704 return;
705 }
706 if (NULL != ch->env)
707 {
708 /* NOTE: we may want to not do this and instead combine the data */
710 "Bandwidth insufficient; dropping previous audio data segment\n");
712 ch->env = NULL;
713 }
714
716 "Received %u bytes of AUDIO data from client CID %u\n",
717 (unsigned int) size,
718 msg->cid);
719 ch->env = GNUNET_MQ_msg_extra (mam,
720 size,
722 GNUNET_memcpy (&mam[1], &msg[1], size);
723 /* FIXME: set options for unreliable transmission */
725 GNUNET_MQ_send (ch->mq, ch->env);
727}
728
737{
738 // FIXME
739 return GNUNET_OK;
740}
741
748static void
750{
751 struct Channel *ch = cls;
752 struct Line *line = ch->line;
753 struct GNUNET_MQ_Envelope *env;
754 struct ClientPhoneRingMessage *cring;
755 struct CadetPhoneRingInfoPS rs;
757 struct GNUNET_CRYPTO_Signature sig;
758 size_t key_len;
759 size_t sig_len;
760 size_t read;
761
763 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
764 rs.line_port = line->line_port;
766 rs.expiration_time = msg->expiration_time;
767 key_len = ntohl (msg->key_len);
768 sig_len = ntohl (msg->sig_len);
769
770 if ((GNUNET_SYSERR ==
772 key_len,
773 &identity,
774 &read)) ||
775 (read != key_len))
776 {
777 GNUNET_break_op (0);
779 return;
780 }
782 (char*) &msg[1] + read,
783 sig_len);
784 if (GNUNET_OK !=
787 &rs,
788 &sig,
789 &identity))
790 {
791 GNUNET_break_op (0);
793 return;
794 }
796 GNUNET_TIME_absolute_ntoh (msg->expiration_time))
798 {
799 /* ancient call, replay? */
800 GNUNET_break_op (0);
801 /* Note that our reliance on time here is awkward; better would be
802 to use a more complex challenge-response protocol against
803 replay attacks. Left for future work ;-). */
805 return;
806 }
807 if (CS_CALLEE_INIT != ch->status)
808 {
809 GNUNET_break_op (0);
811 return;
812 }
813 GNUNET_CADET_receive_done (ch->channel);
814 ch->status = CS_CALLEE_RINGING;
815 env = GNUNET_MQ_msg_extra (cring,
816 key_len,
818 cring->cid = ch->cid;
819 memcpy (&cring[1], &msg[1], key_len);
820 cring->key_len = msg->key_len;
822 "Sending RING message to client. CID is %u\n",
823 (unsigned int) ch->cid);
824 GNUNET_MQ_send (line->mq, env);
825}
826
827
834static void
836 const struct CadetPhoneHangupMessage *message)
837{
838 struct Channel *ch = cls;
839 struct Line *line = ch->line;
840 struct GNUNET_MQ_Envelope *env;
841 struct ClientPhoneHangupMessage *hup;
843 uint32_t cid;
844
845 (void) message;
846 GNUNET_CADET_receive_done (ch->channel);
847 cid = ch->cid;
848 status = ch->status;
850 switch (status)
851 {
852 case CS_CALLEE_INIT:
853 GNUNET_break_op (0);
854 return;
855
858 break;
859
861 return;
862
865 break;
866
868 return;
869 }
870 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
872 hup->cid = cid;
873 GNUNET_MQ_send (line->mq, env);
874}
875
876
883static void
885 const struct CadetPhonePickupMessage *message)
886{
887 struct Channel *ch = cls;
888 struct Line *line = ch->line;
889 struct GNUNET_MQ_Envelope *env;
890 struct ClientPhonePickedupMessage *pick;
891
892 (void) message;
893 GNUNET_CADET_receive_done (ch->channel);
894 switch (ch->status)
895 {
896 case CS_CALLEE_INIT:
899 GNUNET_break_op (0);
901 return;
902
904 GNUNET_break_op (0);
906 return;
907
909 ch->status = CS_CALLER_CONNECTED;
910 break;
911
913 GNUNET_break_op (0);
914 return;
915
917 GNUNET_break_op (0);
919 return;
920 }
921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
922 env =
924 pick->cid = ch->cid;
925 GNUNET_MQ_send (line->mq, env);
926}
927
928
935static void
937 const struct CadetPhoneSuspendMessage *message)
938{
939 struct Channel *ch = cls;
940 struct Line *line = ch->line;
941 struct GNUNET_MQ_Envelope *env;
942 struct ClientPhoneSuspendMessage *suspend;
943
944 (void) message;
945 GNUNET_CADET_receive_done (ch->channel);
946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
947 switch (ch->status)
948 {
949 case CS_CALLEE_INIT:
950 GNUNET_break_op (0);
951 break;
952
954 GNUNET_break_op (0);
955 break;
956
958 ch->suspended_remote = GNUNET_YES;
959 break;
960
962 return;
963
965 GNUNET_break_op (0);
966 break;
967
969 ch->suspended_remote = GNUNET_YES;
970 break;
971
973 return;
974 }
975 env =
977 suspend->cid = ch->cid;
978 GNUNET_MQ_send (line->mq, env);
979}
980
981
988static void
990 const struct CadetPhoneResumeMessage *msg)
991{
992 struct Channel *ch = cls;
993 struct Line *line;
994 struct GNUNET_MQ_Envelope *env;
995 struct ClientPhoneResumeMessage *resume;
996
997 (void) msg;
998 line = ch->line;
999 GNUNET_CADET_receive_done (ch->channel);
1000 if (GNUNET_YES != ch->suspended_remote)
1001 {
1002 GNUNET_log (
1004 "RESUME message received for non-suspended channel, dropping channel.\n");
1006 return;
1007 }
1008 switch (ch->status)
1009 {
1010 case CS_CALLEE_INIT:
1011 GNUNET_break (0);
1012 break;
1013
1014 case CS_CALLEE_RINGING:
1015 GNUNET_break (0);
1016 break;
1017
1019 ch->suspended_remote = GNUNET_NO;
1020 break;
1021
1022 case CS_CALLEE_SHUTDOWN:
1023 return;
1024
1025 case CS_CALLER_CALLING:
1026 GNUNET_break (0);
1027 break;
1028
1030 ch->suspended_remote = GNUNET_NO;
1031 break;
1032
1033 case CS_CALLER_SHUTDOWN:
1034 return;
1035 }
1036 env =
1038 resume->cid = ch->cid;
1039 GNUNET_MQ_send (line->mq, env);
1040}
1041
1042
1050static int
1052{
1053 (void) cls;
1054 (void) msg;
1055 return GNUNET_OK; /* any payload is fine */
1056}
1057
1058
1065static void
1067{
1068 struct Channel *ch = cls;
1069 size_t msize = ntohs (msg->header.size) - sizeof(struct CadetAudioMessage);
1070 struct GNUNET_MQ_Envelope *env;
1071 struct ClientAudioMessage *cam;
1072
1073 GNUNET_CADET_receive_done (ch->channel);
1074 if ((GNUNET_YES == ch->suspended_local) ||
1075 (GNUNET_YES == ch->suspended_remote))
1076 {
1077 GNUNET_log (
1079 "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1080 (unsigned int) msize,
1081 ch->cid);
1082 return;
1083 }
1085 "Forwarding %u bytes of AUDIO data to client CID %u\n",
1086 (unsigned int) msize,
1087 ch->cid);
1088 env =
1090 cam->cid = ch->cid;
1091 GNUNET_memcpy (&cam[1], &msg[1], msize);
1092 GNUNET_MQ_send (ch->line->mq, env);
1093}
1094
1095
1103static void
1104inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
1105{
1106 struct Channel *ch = cls;
1107
1108 GNUNET_assert (channel == ch->channel);
1109 ch->channel = NULL;
1111 "Channel destroyed by CADET in state %d\n",
1112 ch->status);
1114}
1115
1122static enum GNUNET_GenericReturnValue
1124{
1125 // FIXME
1126 return GNUNET_OK;
1127}
1128
1135static void
1137{
1138 struct Line *line = cls;
1139 struct Channel *ch = GNUNET_new (struct Channel);
1140 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1141 { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1144 ch),
1145 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1148 ch),
1149 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1152 ch),
1153 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1156 ch),
1157 GNUNET_MQ_hd_var_size (cadet_audio_message,
1159 struct CadetAudioMessage,
1160 ch),
1162 struct GNUNET_MQ_Envelope *e;
1163 struct CadetPhoneRingMessage *ring;
1164 struct CadetPhoneRingInfoPS rs;
1165 struct GNUNET_CRYPTO_PrivateKey caller_id;
1166 struct GNUNET_CRYPTO_PublicKey caller_id_pub;
1167 struct GNUNET_CRYPTO_Signature sig;
1168 ssize_t written;
1169 size_t key_len;
1170 size_t pkey_len;
1171 size_t sig_len;
1172 size_t read;
1173
1174 line->line_port = msg->line_port;
1176 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
1177 rs.line_port = line->line_port;
1178 rs.target_peer = msg->target;
1179 rs.expiration_time =
1181 key_len = ntohl (msg->key_len);
1182 if (GNUNET_SYSERR ==
1184 key_len,
1185 &caller_id,
1186 &read))
1187 {
1188 GNUNET_break_op (0);
1189 GNUNET_free (ch);
1191 return;
1192 }
1193 ch->line = line;
1194 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1195 ch->status = CS_CALLER_CALLING;
1197 ch,
1198 &msg->target,
1199 &msg->line_port,
1200 NULL,
1201 &inbound_end,
1202 cadet_handlers);
1203 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1204 GNUNET_assert (read == key_len);
1205 GNUNET_CRYPTO_sign (&caller_id, &rs, &sig);
1206 sig_len = GNUNET_CRYPTO_signature_get_length (&sig);
1207 GNUNET_CRYPTO_key_get_public (&caller_id, &caller_id_pub);
1208 pkey_len = GNUNET_CRYPTO_public_key_get_length (&caller_id_pub);
1209 e = GNUNET_MQ_msg_extra (ring, pkey_len + sig_len,
1211 written = GNUNET_CRYPTO_write_public_key_to_buffer (&caller_id_pub,
1212 &ring[1],
1213 pkey_len);
1215 ring->key_len = htonl (pkey_len);
1216 ring->sig_len = htonl (sig_len);
1218 (char *) &ring[1] + written,
1219 sig_len);
1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1221 GNUNET_MQ_send (ch->mq, e);
1223}
1224
1225
1235static void *
1237 struct GNUNET_CADET_Channel *channel,
1238 const struct GNUNET_PeerIdentity *initiator)
1239{
1240 struct Line *line = cls;
1241 struct Channel *ch;
1242
1243 (void) initiator;
1245 "Received incoming cadet channel on line %p\n",
1246 line);
1247 ch = GNUNET_new (struct Channel);
1248 ch->status = CS_CALLEE_INIT;
1249 ch->line = line;
1250 ch->channel = channel;
1251 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1252 ch->cid = line->cid_gen++;
1253 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1254 return ch;
1255}
1256
1257
1266static void *
1268 struct GNUNET_SERVICE_Client *client,
1269 struct GNUNET_MQ_Handle *mq)
1270{
1271 struct Line *line;
1272
1273 (void) cls;
1274 line = GNUNET_new (struct Line);
1275 line->client = client;
1276 line->mq = mq;
1277 return line;
1278}
1279
1280
1288static void
1291 void *app_ctx)
1292{
1293 struct Line *line = app_ctx;
1294 struct Channel *chn;
1295
1296 (void) cls;
1297 (void) client;
1298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
1299 if (NULL != line->port)
1300 {
1302 line->port = NULL;
1303 }
1304 for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1305 {
1306 chn = ch->next;
1307 ch->line = NULL;
1309 }
1310 GNUNET_free (line);
1311}
1312
1313
1320static void
1322 const struct ClientPhoneRegisterMessage *msg)
1323{
1324 struct Line *line = cls;
1325 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1326 { GNUNET_MQ_hd_var_size (cadet_ring_message,
1328 struct CadetPhoneRingMessage,
1329 NULL),
1330 GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1333 NULL),
1334 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1337 NULL),
1338 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1341 NULL),
1342 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1345 NULL),
1346 GNUNET_MQ_hd_var_size (cadet_audio_message,
1348 struct CadetAudioMessage,
1349 NULL),
1351
1352 line->line_port = msg->line_port;
1354 &msg->line_port,
1356 line,
1357 NULL,
1358 &inbound_end,
1359 cadet_handlers);
1360 if (NULL == line->port)
1361 {
1363 _ ("Could not open line, port %s already in use!\n"),
1364 GNUNET_h2s (&msg->line_port));
1366 return;
1367 }
1369}
1370
1371
1377static void
1379{
1380 (void) cls;
1381 if (NULL != cadet)
1382 {
1384 cadet = NULL;
1385 }
1386}
1387
1388
1396static void
1397run (void *cls,
1398 const struct GNUNET_CONFIGURATION_Handle *c,
1400{
1401 (void) cls;
1402 (void) service;
1403 cfg = c;
1407 if (NULL == cadet)
1408 {
1409 GNUNET_break (0);
1411 return;
1412 }
1414}
1415
1416
1422 "conversation",
1424 &run,
1427 NULL,
1428 GNUNET_MQ_hd_fixed_size (client_register_message,
1431 NULL),
1432 GNUNET_MQ_hd_fixed_size (client_pickup_message,
1435 NULL),
1436 GNUNET_MQ_hd_fixed_size (client_suspend_message,
1439 NULL),
1440 GNUNET_MQ_hd_fixed_size (client_resume_message,
1443 NULL),
1444 GNUNET_MQ_hd_fixed_size (client_hangup_message,
1447 NULL),
1448 GNUNET_MQ_hd_var_size (client_call_message,
1450 struct ClientCallMessage,
1451 NULL),
1452 GNUNET_MQ_hd_var_size (client_audio_message,
1454 struct ClientAudioMessage,
1455 NULL),
1457
1458
1459/* end of gnunet-service-conversation.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
constants for network protocols
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static char * line
Desired phone line (string to be converted to a hash).
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void handle_client_suspend_message(void *cls, const struct ClientPhoneSuspendMessage *msg)
Function to handle a suspend request message from the client.
static enum GNUNET_GenericReturnValue check_cadet_ring_message(void *cls, const struct CadetPhoneRingMessage *msg)
Function to handle a ring message incoming over cadet.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static void inbound_end(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever an inbound channel is destroyed.
#define RING_TIMEOUT
How long is our signature on a call valid? Needs to be long enough for time zone differences and netw...
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
static void * inbound_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Method called whenever another peer has added us to a channel the other peer initiated.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static int check_client_audio_message(void *cls, const struct ClientAudioMessage *msg)
Function to check audio data from the client.
static void handle_client_pickup_message(void *cls, const struct ClientPhonePickupMessage *msg)
Function to handle a pickup request message from the client.
static void handle_cadet_resume_message(void *cls, const struct CadetPhoneResumeMessage *msg)
Function to handle a resume message incoming over cadet.
static void do_shutdown(void *cls)
Shutdown nicely.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.
static void handle_client_call_message(void *cls, const struct ClientCallMessage *msg)
Function to handle call request from the client.
static void clean_up_channel(struct Channel *ch)
Channel went down, notify client and free data structure.
static void handle_cadet_audio_message(void *cls, const struct CadetAudioMessage *msg)
Function to handle an audio message incoming over cadet.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Main function that will be run by the scheduler.
static int check_cadet_audio_message(void *cls, const struct CadetAudioMessage *msg)
Function to check an audio message incoming over cadet.
static void handle_cadet_pickup_message(void *cls, const struct CadetPhonePickupMessage *message)
Function to handle a pickup message incoming over cadet.
static void handle_client_register_message(void *cls, const struct ClientPhoneRegisterMessage *msg)
Function to register a phone.
static void handle_client_audio_message(void *cls, const struct ClientAudioMessage *msg)
Function to handle audio data from the client.
static void handle_cadet_suspend_message(void *cls, const struct CadetPhoneSuspendMessage *message)
Function to handle a suspend message incoming over cadet.
ChannelStatus
The possible connection status.
@ CS_CALLEE_RINGING
Our phone is ringing, waiting for the client to pick up.
@ CS_CALLEE_SHUTDOWN
We're in shutdown, sending hangup messages before cleaning up.
@ CS_CALLEE_INIT
We just got the connection, but no introduction yet.
@ CS_CALLER_CONNECTED
We are talking!
@ CS_CALLEE_CONNECTED
We are talking!
@ CS_CALLER_SHUTDOWN
We're in shutdown, sending hangup messages before cleaning up.
@ CS_CALLER_CALLING
We are waiting for the phone to be picked up.
static enum GNUNET_GenericReturnValue check_client_call_message(void *cls, const struct ClientCallMessage *msg)
Function to handle call request from the client.
static void handle_cadet_hangup_message(void *cls, const struct CadetPhoneHangupMessage *message)
Function to handle a hangup message incoming over cadet.
static void mq_done_finish_caller_shutdown(void *cls)
We are done signalling shutdown to the other peer.
static void handle_client_hangup_message(void *cls, const struct ClientPhoneHangupMessage *msg)
Function to handle a hangup request message from the client.
static void destroy_line_cadet_channels(struct Channel *ch)
Destroy a channel.
static void channel_audio_sent_notify(void *cls)
Transmission of audio data via cadet channel finished.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
A client disconnected.
static void handle_cadet_ring_message(void *cls, const struct CadetPhoneRingMessage *msg)
Function to handle a ring message incoming over cadet.
GNUNET_SERVICE_MAIN(GNUNET_OS_project_data_gnunet(), "conversation", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_register_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER, struct ClientPhoneRegisterMessage, NULL), GNUNET_MQ_hd_fixed_size(client_pickup_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP, struct ClientPhonePickupMessage, NULL), GNUNET_MQ_hd_fixed_size(client_suspend_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND, struct ClientPhoneSuspendMessage, NULL), GNUNET_MQ_hd_fixed_size(client_resume_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME, struct ClientPhoneResumeMessage, NULL), GNUNET_MQ_hd_fixed_size(client_hangup_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP, struct ClientPhoneHangupMessage, NULL), GNUNET_MQ_hd_var_size(client_call_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL, struct ClientCallMessage, NULL), GNUNET_MQ_hd_var_size(client_audio_message, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO, struct ClientAudioMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static struct Channel * find_channel_by_line(struct Line *line, uint32_t cid)
Given a cid, find the corresponding channel given a line.
static void handle_client_resume_message(void *cls, const struct ClientPhoneResumeMessage *msg)
Function to handle a resume request message from the client.
CADET service; establish channels to distant peers.
Constants for network protocols.
#define GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING
Signature of a conversation ring.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:897
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:875
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:833
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1081
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition: cadet_api.c:966
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:777
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:804
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1030
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_get_peer_identity(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst)
Retrieve the identity of the host's peer.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
ssize_t GNUNET_CRYPTO_read_signature_from_buffer(struct GNUNET_CRYPTO_Signature *sig, const void *buffer, size_t len)
Reads a GNUNET_CRYPTO_Signature from a compact buffer.
Definition: crypto_pkey.c:227
ssize_t GNUNET_CRYPTO_public_key_get_length(const struct GNUNET_CRYPTO_PublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_PublicKey.
Definition: crypto_pkey.c:85
#define GNUNET_log(kind,...)
ssize_t GNUNET_CRYPTO_write_public_key_to_buffer(const struct GNUNET_CRYPTO_PublicKey *key, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_PublicKey to a compact buffer.
Definition: crypto_pkey.c:128
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public(const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: crypto_pkey.c:430
void * cls
Closure for mv and cb.
ssize_t GNUNET_CRYPTO_write_signature_to_buffer(const struct GNUNET_CRYPTO_Signature *sig, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_Signature to a compact buffer.
Definition: crypto_pkey.c:248
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
ssize_t GNUNET_CRYPTO_signature_get_length(const struct GNUNET_CRYPTO_Signature *sig)
Get the compacted length of a GNUNET_CRYPTO_Signature.
Definition: crypto_pkey.c:190
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_public_key_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_PublicKey *key, size_t *read)
Reads a GNUNET_CRYPTO_PublicKey from a compact buffer.
Definition: crypto_pkey.c:102
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_CRYPTO_sign(priv, ps, sig)
Sign a given block with GNUNET_CRYPTO_PrivateKey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_private_key_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_PrivateKey *key, size_t *read)
Reads a GNUNET_CRYPTO_PrivateKey from a compact buffer.
Definition: crypto_pkey.c:146
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_CRYPTO_signature_verify(purp, ps, sig, pub)
Verify a given signature with GNUNET_CRYPTO_PublicKey.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send_cancel(struct GNUNET_MQ_Envelope *ev)
Cancel sending the message.
Definition: mq.c:785
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:61
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:76
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:655
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME
Client <-> Server message to resume connection.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER
Client -> Server message to register a phone.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO
Cadet: audio data.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP
Client -> Server message to reject/hangup a call.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND
Client <-> Server message to suspend connection.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP
Service -> Client message to notify that phone was picked up.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP
Client -> Server message to reject/hangup a call.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING
Cadet: call initiation.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP
Cadet: hang up / refuse call.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP
Cadet: pick up phone (establish audio channel)
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO
Client <-> Server message to send audio data.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL
Client <- Server message to indicate a ringing phone.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME
Cadet: phone resumed.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING
Client <- Server message to indicate a ringing phone.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND
Cadet: phone suspended.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1339
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2418
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2389
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:741
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:640
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:179
Cadet message to transmit the audio.
Definition: conversation.h:385
Cadet message for hanging up.
Definition: conversation.h:337
Cadet message for picking up.
Definition: conversation.h:349
Cadet message for phone resumed.
Definition: conversation.h:373
Information signed in a struct CadetPhoneRingMessage whereby the caller self-identifies to the receiv...
Definition: conversation.h:271
struct GNUNET_PeerIdentity target_peer
Which peer is the call for?
Definition: conversation.h:286
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:291
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose for the signature, must be GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING.
Definition: conversation.h:276
struct GNUNET_HashCode line_port
Which port did the call go to?
Definition: conversation.h:281
Cadet message to make a phone ring.
Definition: conversation.h:300
uint32_t key_len
The length of the key.
Definition: conversation.h:319
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:314
uint32_t sig_len
The length of the signature.
Definition: conversation.h:324
Cadet message for phone suspended.
Definition: conversation.h:361
A struct Channel represents a cadet channel, which is a P2P connection to another conversation servic...
struct GNUNET_MQ_Handle * mq
Message queue for control messages.
struct GNUNET_CADET_Channel * channel
Handle for the channel.
struct Channel * prev
This is a DLL.
enum ChannelStatus status
Current status of this line.
int8_t suspended_local
GNUNET_YES if the channel was suspended by the local client.
int8_t suspended_remote
GNUNET_YES if the channel was suspended by the other peer.
struct GNUNET_MQ_Envelope * env
Temporary buffer for audio data in the mq.
struct Channel * next
This is a DLL.
struct Line * line
Line associated with the channel.
uint32_t cid
Channel identifier we use for this call with the client.
Message Client <-> Service to transmit the audio.
Definition: conversation.h:195
uint32_t cid
CID, internal caller ID to identify which active call we are sending data to.
Definition: conversation.h:205
Client -> Service message to call a phone.
Definition: conversation.h:215
Client <-> Service hang up phone that may or may not be ringing.
Definition: conversation.h:177
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:187
Service -> Client: other peer has picked up the phone, we are now talking.
Definition: conversation.h:252
uint32_t cid
Call ID of the corresponding GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL.
Definition: conversation.h:262
Client -> Service pick up phone that is ringing.
Definition: conversation.h:158
Client -> Service message to register a phone.
Definition: conversation.h:73
Service <-> Client message for phone was resumed.
Definition: conversation.h:140
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:150
Service -> Client message for phone is ringing.
Definition: conversation.h:95
uint32_t cid
CID, internal caller ID number used in the future to identify which active call we are talking about.
Definition: conversation.h:105
uint32_t key_len
The identity key length.
Definition: conversation.h:110
Service <-> Client message for phone was suspended.
Definition: conversation.h:122
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:132
Opaque handle to a channel.
Definition: cadet.h:116
struct GNUNET_MQ_Handle * mq
Message Queue for the channel (which we are implementing).
Definition: cadet.h:142
Opaque handle to the service.
Definition: cadet_api.c:39
Opaque handle to a port.
Definition: cadet_api.c:80
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
An identity signature as per LSD0001.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
The identity of the host (wraps the signing key of the peer).
Handle to a client that is connected to a service.
Definition: service.c:249
Handle to a service.
Definition: service.c:116
uint64_t rel_value_us
The actual value.
A struct Line connects a local client with cadet channels.
uint32_t cid_gen
Generator for channel IDs.
struct GNUNET_HashCode line_port
Port number we are listening on (to verify signatures).
struct GNUNET_MQ_Handle * mq
Message queue for client.
struct Channel * channel_tail
This is a DLL.
struct GNUNET_CADET_Port * port
Our open port.
struct Channel * channel_head
This is a DLL.
struct GNUNET_SERVICE_Client * client
Handle to the line client.