GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
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
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_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
constants for network protocols
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static struct GNUNET_CADET_Channel * ch
Channel handle.
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 * 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.
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.
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.
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.
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.
#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.
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.
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.
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.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#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
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2462
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2433
@ 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
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Cadet message to transmit the audio.
Cadet message for hanging up.
Cadet message for picking up.
Cadet message for phone resumed.
Information signed in a struct CadetPhoneRingMessage whereby the caller self-identifies to the receiv...
struct GNUNET_PeerIdentity target_peer
Which peer is the call for?
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose for the signature, must be GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING.
struct GNUNET_HashCode line_port
Which port did the call go to?
Cadet message to make a phone ring.
uint32_t key_len
The length of the key.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
uint32_t sig_len
The length of the signature.
Cadet message for phone suspended.
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.
uint32_t cid
CID, internal caller ID to identify which active call we are sending data to.
Client -> Service message to call a phone.
Client <-> Service hang up phone that may or may not be ringing.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Service -> Client: other peer has picked up the phone, we are now talking.
uint32_t cid
Call ID of the corresponding GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL.
Client -> Service pick up phone that is ringing.
Client -> Service message to register a phone.
Service <-> Client message for phone was resumed.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Service -> Client message for phone is ringing.
uint32_t cid
CID, internal caller ID number used in the future to identify which active call we are talking about.
uint32_t key_len
The identity key length.
Service <-> Client message for phone was suspended.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
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
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition service.c:273
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.