GNUnet 0.21.1
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_applications.h"
31#include "gnunet_constants.h"
32#include "gnunet_signatures.h"
35#include "conversation.h"
36
37
43#define RING_TIMEOUT GNUNET_TIME_UNIT_DAYS
44
45
50struct Line;
51
56{
61
66
71
76
81
86
91};
92
93
101{
105 struct Channel *next;
106
110 struct Channel *prev;
111
115 struct Line *line;
116
121
126
131
135 uint32_t cid;
136
141
146
151};
152
153
157struct Line
158{
163
168
173
178
183
189
193 uint32_t cid_gen;
194};
195
196
200static const struct GNUNET_CONFIGURATION_Handle *cfg;
201
206
211
212
221static struct Channel *
223{
224 for (struct Channel *ch = line->channel_head; NULL != ch; ch = ch->next)
225 if (cid == ch->cid)
226 return ch;
227 return NULL;
228}
229
230
237static void
239 const struct ClientPhonePickupMessage *msg)
240{
241 struct Line *line = cls;
242 struct CadetPhonePickupMessage *mppm;
243 struct GNUNET_MQ_Envelope *env;
244 struct Channel *ch;
245
246 if (NULL == line->port)
247 {
248 /* we never opened the port, bad client! */
249 GNUNET_break_op (0);
251 return;
252 }
253 for (ch = line->channel_head; NULL != ch; ch = ch->next)
254 if (msg->cid == ch->cid)
255 break;
256 if (NULL == ch)
257 {
258 /* could have been destroyed asynchronously, ignore message */
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
261 return;
262 }
263 switch (ch->status)
264 {
265 case CS_CALLEE_INIT:
266 GNUNET_break (0);
268 return;
269
271 ch->status = CS_CALLEE_CONNECTED;
272 break;
273
275 GNUNET_break (0);
277 return;
278
281 "Ignoring client's PICKUP message, line is in SHUTDOWN\n");
282 break;
283
287 GNUNET_break (0);
289 return;
290 }
292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICK_UP message to cadet\n");
293 env =
297}
298
299
306static void
308{
309 struct Line *line = ch->line;
310 struct GNUNET_MQ_Envelope *env;
311 struct ClientPhoneHangupMessage *hup;
312
313 switch (ch->status)
314 {
315 case CS_CALLEE_INIT:
318 break;
319
324 if (NULL != line)
325 {
326 env =
328 hup->cid = ch->cid;
329 GNUNET_MQ_send (line->mq, env);
330 }
331 break;
332 }
333 if (NULL != line)
334 GNUNET_CONTAINER_DLL_remove (line->channel_head, line->channel_tail, ch);
335 GNUNET_free (ch);
336}
337
338
344static void
346{
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying cadet channels\n");
348 if (NULL != ch->channel)
349 {
351 ch->channel = NULL;
352 }
354}
355
356
363static void
365{
366 struct Channel *ch = cls;
367
368 switch (ch->status)
369 {
370 case CS_CALLEE_INIT:
371 GNUNET_break (0);
372 break;
373
375 GNUNET_break (0);
376 break;
377
379 GNUNET_break (0);
380 break;
381
384 break;
385
387 GNUNET_break (0);
388 break;
389
391 GNUNET_break (0);
392 break;
393
396 break;
397 }
398}
399
400
407static void
409 const struct ClientPhoneHangupMessage *msg)
410{
411 struct Line *line = cls;
412 struct GNUNET_MQ_Envelope *e;
413 struct CadetPhoneHangupMessage *mhum;
414 struct Channel *ch;
415
416 for (ch = line->channel_head; NULL != ch; ch = ch->next)
417 if (msg->cid == ch->cid)
418 break;
419 if (NULL == ch)
420 {
421 /* could have been destroyed asynchronously, ignore message */
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
424 return;
425 }
427 "Received HANGUP for channel %u which is in state %d\n",
428 msg->cid,
429 ch->status);
430 switch (ch->status)
431 {
432 case CS_CALLEE_INIT:
433 GNUNET_break (0);
435 return;
436
438 ch->status = CS_CALLEE_SHUTDOWN;
439 break;
440
442 ch->status = CS_CALLEE_SHUTDOWN;
443 break;
444
446 /* maybe the other peer closed asynchronously... */
448 return;
449
451 ch->status = CS_CALLER_SHUTDOWN;
452 break;
453
455 ch->status = CS_CALLER_SHUTDOWN;
456 break;
457
459 /* maybe the other peer closed asynchronously... */
461 return;
462 }
463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG_UP message via cadet\n");
464 e =
467 GNUNET_MQ_send (ch->mq, e);
469}
470
471
478static void
480 const struct ClientPhoneSuspendMessage *msg)
481{
482 struct Line *line = cls;
483 struct GNUNET_MQ_Envelope *e;
484 struct CadetPhoneSuspendMessage *mhum;
485 struct Channel *ch;
486
487 for (ch = line->channel_head; NULL != ch; ch = ch->next)
488 if (msg->cid == ch->cid)
489 break;
490 if (NULL == ch)
491 {
492 /* could have been destroyed asynchronously, ignore message */
493 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
495 return;
496 }
497 if (GNUNET_YES == ch->suspended_local)
498 {
499 GNUNET_break (0);
501 return;
502 }
504 "Received SUSPEND for channel %u which is in state %d\n",
505 msg->cid,
506 ch->status);
507 switch (ch->status)
508 {
509 case CS_CALLEE_INIT:
510 GNUNET_break (0);
512 return;
513
515 GNUNET_break (0);
517 return;
518
520 ch->suspended_local = GNUNET_YES;
521 break;
522
524 /* maybe the other peer closed asynchronously... */
526 return;
527
529 GNUNET_break (0);
531 return;
532
534 ch->suspended_local = GNUNET_YES;
535 break;
536
538 /* maybe the other peer closed asynchronously... */
540 return;
541 }
542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUSPEND message via cadet\n");
543 e =
545 GNUNET_MQ_send (ch->mq, e);
547}
548
549
556static void
558 const struct ClientPhoneResumeMessage *msg)
559{
560 struct Line *line = cls;
561 struct GNUNET_MQ_Envelope *e;
562 struct CadetPhoneResumeMessage *mhum;
563 struct Channel *ch;
564
565 for (ch = line->channel_head; NULL != ch; ch = ch->next)
566 if (msg->cid == ch->cid)
567 break;
568 if (NULL == ch)
569 {
570 /* could have been destroyed asynchronously, ignore message */
571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
573 return;
574 }
575 if (GNUNET_YES != ch->suspended_local)
576 {
577 GNUNET_break (0);
579 return;
580 }
582 "Received RESUME for channel %u which is in state %d\n",
583 msg->cid,
584 ch->status);
585 switch (ch->status)
586 {
587 case CS_CALLEE_INIT:
588 GNUNET_break (0);
590 return;
591
593 GNUNET_break (0);
595 return;
596
598 ch->suspended_local = GNUNET_NO;
599 break;
600
602 /* maybe the other peer closed asynchronously... */
604 return;
605
607 GNUNET_break (0);
609 return;
610
612 ch->suspended_local = GNUNET_NO;
613 break;
614
616 /* maybe the other peer closed asynchronously... */
618 return;
619 }
620 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RESUME message via cadet\n");
622 GNUNET_MQ_send (ch->mq, e);
624}
625
626
632static void
634{
635 struct Channel *ch = cls;
636
637 ch->env = NULL;
638}
639
640
648static int
650{
651 (void) cls;
652 (void) msg;
653 return GNUNET_OK;
654}
655
656
663static void
665{
666 struct Line *line = cls;
667 struct CadetAudioMessage *mam;
668 struct Channel *ch;
669 size_t size;
670
671 size = ntohs (msg->header.size) - sizeof(struct ClientAudioMessage);
673 if (NULL == ch)
674 {
675 /* could have been destroyed asynchronously, ignore message */
676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
678 return;
679 }
680
681 switch (ch->status)
682 {
683 case CS_CALLEE_INIT:
686 GNUNET_break (0);
688 return;
689
692 /* common case, handled below */
693 break;
694
698 "Cadet audio channel in shutdown; audio data dropped\n");
700 return;
701 }
702 if (GNUNET_YES == ch->suspended_local)
703 {
705 "This channel is suspended locally\n");
707 return;
708 }
709 if (NULL != ch->env)
710 {
711 /* NOTE: we may want to not do this and instead combine the data */
713 "Bandwidth insufficient; dropping previous audio data segment\n");
715 ch->env = NULL;
716 }
717
719 "Received %u bytes of AUDIO data from client CID %u\n",
720 (unsigned int) size,
721 msg->cid);
722 ch->env = GNUNET_MQ_msg_extra (mam,
723 size,
725 GNUNET_memcpy (&mam[1], &msg[1], size);
726 /* FIXME: set options for unreliable transmission */
728 GNUNET_MQ_send (ch->mq, ch->env);
730}
731
740{
741 // FIXME
742 return GNUNET_OK;
743}
744
751static void
753{
754 struct Channel *ch = cls;
755 struct Line *line = ch->line;
756 struct GNUNET_MQ_Envelope *env;
757 struct ClientPhoneRingMessage *cring;
758 struct CadetPhoneRingInfoPS rs;
760 struct GNUNET_CRYPTO_Signature sig;
761 size_t key_len;
762 size_t sig_len;
763 size_t read;
764
766 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
767 rs.line_port = line->line_port;
769 rs.expiration_time = msg->expiration_time;
770 key_len = ntohl (msg->key_len);
771 sig_len = ntohl (msg->sig_len);
772
773 if ((GNUNET_SYSERR ==
775 key_len,
776 &identity,
777 &read)) ||
778 (read != key_len))
779 {
780 GNUNET_break_op (0);
782 return;
783 }
785 (char*) &msg[1] + read,
786 sig_len);
787 if (GNUNET_OK !=
790 &rs,
791 &sig,
792 &identity))
793 {
794 GNUNET_break_op (0);
796 return;
797 }
799 GNUNET_TIME_absolute_ntoh (msg->expiration_time))
801 {
802 /* ancient call, replay? */
803 GNUNET_break_op (0);
804 /* Note that our reliance on time here is awkward; better would be
805 to use a more complex challenge-response protocol against
806 replay attacks. Left for future work ;-). */
808 return;
809 }
810 if (CS_CALLEE_INIT != ch->status)
811 {
812 GNUNET_break_op (0);
814 return;
815 }
816 GNUNET_CADET_receive_done (ch->channel);
817 ch->status = CS_CALLEE_RINGING;
818 env = GNUNET_MQ_msg_extra (cring,
819 key_len,
821 cring->cid = ch->cid;
822 memcpy (&cring[1], &msg[1], key_len);
823 cring->key_len = msg->key_len;
825 "Sending RING message to client. CID is %u\n",
826 (unsigned int) ch->cid);
827 GNUNET_MQ_send (line->mq, env);
828}
829
830
837static void
839 const struct CadetPhoneHangupMessage *message)
840{
841 struct Channel *ch = cls;
842 struct Line *line = ch->line;
843 struct GNUNET_MQ_Envelope *env;
844 struct ClientPhoneHangupMessage *hup;
846 uint32_t cid;
847
848 (void) message;
849 GNUNET_CADET_receive_done (ch->channel);
850 cid = ch->cid;
851 status = ch->status;
853 switch (status)
854 {
855 case CS_CALLEE_INIT:
856 GNUNET_break_op (0);
857 return;
858
861 break;
862
864 return;
865
868 break;
869
871 return;
872 }
873 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
875 hup->cid = cid;
876 GNUNET_MQ_send (line->mq, env);
877}
878
879
886static void
888 const struct CadetPhonePickupMessage *message)
889{
890 struct Channel *ch = cls;
891 struct Line *line = ch->line;
892 struct GNUNET_MQ_Envelope *env;
893 struct ClientPhonePickedupMessage *pick;
894
895 (void) message;
896 GNUNET_CADET_receive_done (ch->channel);
897 switch (ch->status)
898 {
899 case CS_CALLEE_INIT:
902 GNUNET_break_op (0);
904 return;
905
907 GNUNET_break_op (0);
909 return;
910
912 ch->status = CS_CALLER_CONNECTED;
913 break;
914
916 GNUNET_break_op (0);
917 return;
918
920 GNUNET_break_op (0);
922 return;
923 }
924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
925 env =
927 pick->cid = ch->cid;
928 GNUNET_MQ_send (line->mq, env);
929}
930
931
938static void
940 const struct CadetPhoneSuspendMessage *message)
941{
942 struct Channel *ch = cls;
943 struct Line *line = ch->line;
944 struct GNUNET_MQ_Envelope *env;
945 struct ClientPhoneSuspendMessage *suspend;
946
947 (void) message;
948 GNUNET_CADET_receive_done (ch->channel);
949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
950 switch (ch->status)
951 {
952 case CS_CALLEE_INIT:
953 GNUNET_break_op (0);
954 break;
955
957 GNUNET_break_op (0);
958 break;
959
961 ch->suspended_remote = GNUNET_YES;
962 break;
963
965 return;
966
968 GNUNET_break_op (0);
969 break;
970
972 ch->suspended_remote = GNUNET_YES;
973 break;
974
976 return;
977 }
978 env =
980 suspend->cid = ch->cid;
981 GNUNET_MQ_send (line->mq, env);
982}
983
984
991static void
993 const struct CadetPhoneResumeMessage *msg)
994{
995 struct Channel *ch = cls;
996 struct Line *line;
997 struct GNUNET_MQ_Envelope *env;
998 struct ClientPhoneResumeMessage *resume;
999
1000 (void) msg;
1001 line = ch->line;
1002 GNUNET_CADET_receive_done (ch->channel);
1003 if (GNUNET_YES != ch->suspended_remote)
1004 {
1005 GNUNET_log (
1007 "RESUME message received for non-suspended channel, dropping channel.\n");
1009 return;
1010 }
1011 switch (ch->status)
1012 {
1013 case CS_CALLEE_INIT:
1014 GNUNET_break (0);
1015 break;
1016
1017 case CS_CALLEE_RINGING:
1018 GNUNET_break (0);
1019 break;
1020
1022 ch->suspended_remote = GNUNET_NO;
1023 break;
1024
1025 case CS_CALLEE_SHUTDOWN:
1026 return;
1027
1028 case CS_CALLER_CALLING:
1029 GNUNET_break (0);
1030 break;
1031
1033 ch->suspended_remote = GNUNET_NO;
1034 break;
1035
1036 case CS_CALLER_SHUTDOWN:
1037 return;
1038 }
1039 env =
1041 resume->cid = ch->cid;
1042 GNUNET_MQ_send (line->mq, env);
1043}
1044
1045
1053static int
1055{
1056 (void) cls;
1057 (void) msg;
1058 return GNUNET_OK; /* any payload is fine */
1059}
1060
1061
1068static void
1070{
1071 struct Channel *ch = cls;
1072 size_t msize = ntohs (msg->header.size) - sizeof(struct CadetAudioMessage);
1073 struct GNUNET_MQ_Envelope *env;
1074 struct ClientAudioMessage *cam;
1075
1076 GNUNET_CADET_receive_done (ch->channel);
1077 if ((GNUNET_YES == ch->suspended_local) ||
1078 (GNUNET_YES == ch->suspended_remote))
1079 {
1080 GNUNET_log (
1082 "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1083 (unsigned int) msize,
1084 ch->cid);
1085 return;
1086 }
1088 "Forwarding %u bytes of AUDIO data to client CID %u\n",
1089 (unsigned int) msize,
1090 ch->cid);
1091 env =
1093 cam->cid = ch->cid;
1094 GNUNET_memcpy (&cam[1], &msg[1], msize);
1095 GNUNET_MQ_send (ch->line->mq, env);
1096}
1097
1098
1106static void
1107inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
1108{
1109 struct Channel *ch = cls;
1110
1111 GNUNET_assert (channel == ch->channel);
1112 ch->channel = NULL;
1114 "Channel destroyed by CADET in state %d\n",
1115 ch->status);
1117}
1118
1125static enum GNUNET_GenericReturnValue
1127{
1128 // FIXME
1129 return GNUNET_OK;
1130}
1131
1138static void
1140{
1141 struct Line *line = cls;
1142 struct Channel *ch = GNUNET_new (struct Channel);
1143 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1144 { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1147 ch),
1148 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1151 ch),
1152 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1155 ch),
1156 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1159 ch),
1160 GNUNET_MQ_hd_var_size (cadet_audio_message,
1162 struct CadetAudioMessage,
1163 ch),
1165 struct GNUNET_MQ_Envelope *e;
1166 struct CadetPhoneRingMessage *ring;
1167 struct CadetPhoneRingInfoPS rs;
1168 struct GNUNET_CRYPTO_PrivateKey caller_id;
1169 struct GNUNET_CRYPTO_PublicKey caller_id_pub;
1170 struct GNUNET_CRYPTO_Signature sig;
1171 ssize_t written;
1172 size_t key_len;
1173 size_t pkey_len;
1174 size_t sig_len;
1175 size_t read;
1176
1177 line->line_port = msg->line_port;
1179 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
1180 rs.line_port = line->line_port;
1181 rs.target_peer = msg->target;
1182 rs.expiration_time =
1184 key_len = ntohl (msg->key_len);
1185 if (GNUNET_SYSERR ==
1187 key_len,
1188 &caller_id,
1189 &read))
1190 {
1191 GNUNET_break_op (0);
1192 GNUNET_free (ch);
1194 return;
1195 }
1196 ch->line = line;
1197 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1198 ch->status = CS_CALLER_CALLING;
1200 ch,
1201 &msg->target,
1202 &msg->line_port,
1203 NULL,
1204 &inbound_end,
1205 cadet_handlers);
1206 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1207 GNUNET_assert (read == key_len);
1208 GNUNET_CRYPTO_sign (&caller_id, &rs, &sig);
1209 sig_len = GNUNET_CRYPTO_signature_get_length (&sig);
1210 GNUNET_CRYPTO_key_get_public (&caller_id, &caller_id_pub);
1211 pkey_len = GNUNET_CRYPTO_public_key_get_length (&caller_id_pub);
1212 e = GNUNET_MQ_msg_extra (ring, pkey_len + sig_len,
1214 written = GNUNET_CRYPTO_write_public_key_to_buffer (&caller_id_pub,
1215 &ring[1],
1216 pkey_len);
1218 ring->key_len = htonl (pkey_len);
1219 ring->sig_len = htonl (sig_len);
1221 (char *) &ring[1] + written,
1222 sig_len);
1223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1224 GNUNET_MQ_send (ch->mq, e);
1226}
1227
1228
1238static void *
1240 struct GNUNET_CADET_Channel *channel,
1241 const struct GNUNET_PeerIdentity *initiator)
1242{
1243 struct Line *line = cls;
1244 struct Channel *ch;
1245
1246 (void) initiator;
1248 "Received incoming cadet channel on line %p\n",
1249 line);
1250 ch = GNUNET_new (struct Channel);
1251 ch->status = CS_CALLEE_INIT;
1252 ch->line = line;
1253 ch->channel = channel;
1254 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1255 ch->cid = line->cid_gen++;
1256 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1257 return ch;
1258}
1259
1260
1269static void *
1271 struct GNUNET_SERVICE_Client *client,
1272 struct GNUNET_MQ_Handle *mq)
1273{
1274 struct Line *line;
1275
1276 (void) cls;
1277 line = GNUNET_new (struct Line);
1278 line->client = client;
1279 line->mq = mq;
1280 return line;
1281}
1282
1283
1291static void
1294 void *app_ctx)
1295{
1296 struct Line *line = app_ctx;
1297 struct Channel *chn;
1298
1299 (void) cls;
1300 (void) client;
1301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
1302 if (NULL != line->port)
1303 {
1305 line->port = NULL;
1306 }
1307 for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1308 {
1309 chn = ch->next;
1310 ch->line = NULL;
1312 }
1313 GNUNET_free (line);
1314}
1315
1316
1323static void
1325 const struct ClientPhoneRegisterMessage *msg)
1326{
1327 struct Line *line = cls;
1328 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1329 { GNUNET_MQ_hd_var_size (cadet_ring_message,
1331 struct CadetPhoneRingMessage,
1332 NULL),
1333 GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1336 NULL),
1337 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1340 NULL),
1341 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1344 NULL),
1345 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1348 NULL),
1349 GNUNET_MQ_hd_var_size (cadet_audio_message,
1351 struct CadetAudioMessage,
1352 NULL),
1354
1355 line->line_port = msg->line_port;
1357 &msg->line_port,
1359 line,
1360 NULL,
1361 &inbound_end,
1362 cadet_handlers);
1363 if (NULL == line->port)
1364 {
1366 _ ("Could not open line, port %s already in use!\n"),
1367 GNUNET_h2s (&msg->line_port));
1369 return;
1370 }
1372}
1373
1374
1380static void
1382{
1383 (void) cls;
1384 if (NULL != cadet)
1385 {
1387 cadet = NULL;
1388 }
1389}
1390
1391
1399static void
1400run (void *cls,
1401 const struct GNUNET_CONFIGURATION_Handle *c,
1403{
1404 (void) cls;
1405 (void) service;
1406 cfg = c;
1410 if (NULL == cadet)
1411 {
1412 GNUNET_break (0);
1414 return;
1415 }
1417}
1418
1419
1424 "conversation",
1426 &run,
1429 NULL,
1430 GNUNET_MQ_hd_fixed_size (client_register_message,
1433 NULL),
1434 GNUNET_MQ_hd_fixed_size (client_pickup_message,
1437 NULL),
1438 GNUNET_MQ_hd_fixed_size (client_suspend_message,
1441 NULL),
1442 GNUNET_MQ_hd_fixed_size (client_resume_message,
1445 NULL),
1446 GNUNET_MQ_hd_fixed_size (client_hangup_message,
1449 NULL),
1450 GNUNET_MQ_hd_var_size (client_call_message,
1452 struct ClientCallMessage,
1453 NULL),
1454 GNUNET_MQ_hd_var_size (client_audio_message,
1456 struct ClientAudioMessage,
1457 NULL),
1459
1460
1461/* 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:38
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...
GNUNET_SERVICE_MAIN("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 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.
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.
Constants for network applications operating on top of the CADET service.
CADET service; establish channels to distant peers.
API to the conversation service.
Constants for network protocols.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:872
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
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:1066
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:954
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:801
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:1015
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:226
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:68
#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:602
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:246
#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:189
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:103
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
#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:768
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:304
#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:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#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:638
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#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:562
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:1334
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2489
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2408
@ 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:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
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:638
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
#define GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING
Signature of a conversation ring.
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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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:252
Handle to a service.
Definition: service.c:118
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.