GNUnet 0.25.2-11-g84e94e98c
 
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
729
738{
739 // FIXME
740 return GNUNET_OK;
741}
742
743
750static void
752{
753 struct Channel *ch = cls;
754 struct Line *line = ch->line;
755 struct GNUNET_MQ_Envelope *env;
756 struct ClientPhoneRingMessage *cring;
757 struct CadetPhoneRingInfoPS rs;
760 size_t key_len;
761 size_t sig_len;
762 size_t read;
763
765 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
766 rs.line_port = line->line_port;
768 rs.expiration_time = msg->expiration_time;
769 key_len = ntohl (msg->key_len);
770 sig_len = ntohl (msg->sig_len);
771
772 if ((GNUNET_SYSERR ==
774 key_len,
775 &identity,
776 &read)) ||
777 (read != key_len))
778 {
779 GNUNET_break_op (0);
781 return;
782 }
784 (char*) &msg[1] + read,
785 sig_len);
786 if (GNUNET_OK !=
789 &rs,
790 &sig,
791 &identity))
792 {
793 GNUNET_break_op (0);
795 return;
796 }
798 GNUNET_TIME_absolute_ntoh (msg->expiration_time))
800 {
801 /* ancient call, replay? */
802 GNUNET_break_op (0);
803 /* Note that our reliance on time here is awkward; better would be
804 to use a more complex challenge-response protocol against
805 replay attacks. Left for future work ;-). */
807 return;
808 }
809 if (CS_CALLEE_INIT != ch->status)
810 {
811 GNUNET_break_op (0);
813 return;
814 }
815 GNUNET_CADET_receive_done (ch->channel);
816 ch->status = CS_CALLEE_RINGING;
817 env = GNUNET_MQ_msg_extra (cring,
818 key_len,
820 cring->cid = ch->cid;
821 memcpy (&cring[1], &msg[1], key_len);
822 cring->key_len = msg->key_len;
824 "Sending RING message to client. CID is %u\n",
825 (unsigned int) ch->cid);
826 GNUNET_MQ_send (line->mq, env);
827}
828
829
836static void
838 const struct CadetPhoneHangupMessage *message)
839{
840 struct Channel *ch = cls;
841 struct Line *line = ch->line;
842 struct GNUNET_MQ_Envelope *env;
843 struct ClientPhoneHangupMessage *hup;
845 uint32_t cid;
846
847 (void) message;
848 GNUNET_CADET_receive_done (ch->channel);
849 cid = ch->cid;
850 status = ch->status;
852 switch (status)
853 {
854 case CS_CALLEE_INIT:
855 GNUNET_break_op (0);
856 return;
857
860 break;
861
863 return;
864
867 break;
868
870 return;
871 }
872 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
874 hup->cid = cid;
875 GNUNET_MQ_send (line->mq, env);
876}
877
878
885static void
887 const struct CadetPhonePickupMessage *message)
888{
889 struct Channel *ch = cls;
890 struct Line *line = ch->line;
891 struct GNUNET_MQ_Envelope *env;
892 struct ClientPhonePickedupMessage *pick;
893
894 (void) message;
895 GNUNET_CADET_receive_done (ch->channel);
896 switch (ch->status)
897 {
898 case CS_CALLEE_INIT:
901 GNUNET_break_op (0);
903 return;
904
906 GNUNET_break_op (0);
908 return;
909
911 ch->status = CS_CALLER_CONNECTED;
912 break;
913
915 GNUNET_break_op (0);
916 return;
917
919 GNUNET_break_op (0);
921 return;
922 }
923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
924 env =
926 pick->cid = ch->cid;
927 GNUNET_MQ_send (line->mq, env);
928}
929
930
937static void
939 const struct CadetPhoneSuspendMessage *message)
940{
941 struct Channel *ch = cls;
942 struct Line *line = ch->line;
943 struct GNUNET_MQ_Envelope *env;
944 struct ClientPhoneSuspendMessage *suspend;
945
946 (void) message;
947 GNUNET_CADET_receive_done (ch->channel);
948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
949 switch (ch->status)
950 {
951 case CS_CALLEE_INIT:
952 GNUNET_break_op (0);
953 break;
954
956 GNUNET_break_op (0);
957 break;
958
960 ch->suspended_remote = GNUNET_YES;
961 break;
962
964 return;
965
967 GNUNET_break_op (0);
968 break;
969
971 ch->suspended_remote = GNUNET_YES;
972 break;
973
975 return;
976 }
977 env =
979 suspend->cid = ch->cid;
980 GNUNET_MQ_send (line->mq, env);
981}
982
983
990static void
992 const struct CadetPhoneResumeMessage *msg)
993{
994 struct Channel *ch = cls;
995 struct Line *line;
996 struct GNUNET_MQ_Envelope *env;
997 struct ClientPhoneResumeMessage *resume;
998
999 (void) msg;
1000 line = ch->line;
1001 GNUNET_CADET_receive_done (ch->channel);
1002 if (GNUNET_YES != ch->suspended_remote)
1003 {
1004 GNUNET_log (
1006 "RESUME message received for non-suspended channel, dropping channel.\n");
1008 return;
1009 }
1010 switch (ch->status)
1011 {
1012 case CS_CALLEE_INIT:
1013 GNUNET_break (0);
1014 break;
1015
1016 case CS_CALLEE_RINGING:
1017 GNUNET_break (0);
1018 break;
1019
1021 ch->suspended_remote = GNUNET_NO;
1022 break;
1023
1024 case CS_CALLEE_SHUTDOWN:
1025 return;
1026
1027 case CS_CALLER_CALLING:
1028 GNUNET_break (0);
1029 break;
1030
1032 ch->suspended_remote = GNUNET_NO;
1033 break;
1034
1035 case CS_CALLER_SHUTDOWN:
1036 return;
1037 }
1038 env =
1040 resume->cid = ch->cid;
1041 GNUNET_MQ_send (line->mq, env);
1042}
1043
1044
1052static int
1054{
1055 (void) cls;
1056 (void) msg;
1057 return GNUNET_OK; /* any payload is fine */
1058}
1059
1060
1067static void
1069{
1070 struct Channel *ch = cls;
1071 size_t msize = ntohs (msg->header.size) - sizeof(struct CadetAudioMessage);
1072 struct GNUNET_MQ_Envelope *env;
1073 struct ClientAudioMessage *cam;
1074
1075 GNUNET_CADET_receive_done (ch->channel);
1076 if ((GNUNET_YES == ch->suspended_local) ||
1077 (GNUNET_YES == ch->suspended_remote))
1078 {
1079 GNUNET_log (
1081 "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1082 (unsigned int) msize,
1083 ch->cid);
1084 return;
1085 }
1087 "Forwarding %u bytes of AUDIO data to client CID %u\n",
1088 (unsigned int) msize,
1089 ch->cid);
1090 env =
1092 cam->cid = ch->cid;
1093 GNUNET_memcpy (&cam[1], &msg[1], msize);
1094 GNUNET_MQ_send (ch->line->mq, env);
1095}
1096
1097
1105static void
1106inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
1107{
1108 struct Channel *ch = cls;
1109
1110 GNUNET_assert (channel == ch->channel);
1111 ch->channel = NULL;
1113 "Channel destroyed by CADET in state %d\n",
1114 ch->status);
1116}
1117
1118
1125static enum GNUNET_GenericReturnValue
1127{
1128 // FIXME
1129 return GNUNET_OK;
1130}
1131
1132
1139static void
1141{
1142 struct Line *line = cls;
1143 struct Channel *ch = GNUNET_new (struct Channel);
1144 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1145 { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1148 ch),
1149 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1152 ch),
1153 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1156 ch),
1157 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1160 ch),
1161 GNUNET_MQ_hd_var_size (cadet_audio_message,
1163 struct CadetAudioMessage,
1164 ch),
1166 struct GNUNET_MQ_Envelope *e;
1167 struct CadetPhoneRingMessage *ring;
1168 struct CadetPhoneRingInfoPS rs;
1169 struct GNUNET_CRYPTO_BlindablePrivateKey caller_id;
1170 struct GNUNET_CRYPTO_BlindablePublicKey caller_id_pub;
1172 ssize_t written;
1173 size_t key_len;
1174 size_t pkey_len;
1175 size_t sig_len;
1176 size_t read;
1177
1178 line->line_port = msg->line_port;
1180 rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
1181 rs.line_port = line->line_port;
1182 rs.target_peer = msg->target;
1183 rs.expiration_time =
1185 key_len = ntohl (msg->key_len);
1186 if (GNUNET_SYSERR ==
1188 key_len,
1189 &caller_id,
1190 &read))
1191 {
1192 GNUNET_break_op (0);
1193 GNUNET_free (ch);
1195 return;
1196 }
1197 ch->line = line;
1198 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1199 ch->status = CS_CALLER_CALLING;
1201 ch,
1202 &msg->target,
1203 &msg->line_port,
1204 NULL,
1205 &inbound_end,
1206 cadet_handlers);
1207 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1208 GNUNET_assert (read == key_len);
1209 GNUNET_CRYPTO_blinded_key_sign (&caller_id, &rs, &sig);
1211 GNUNET_CRYPTO_blindable_key_get_public (&caller_id, &caller_id_pub);
1212 pkey_len = GNUNET_CRYPTO_public_key_get_length (&caller_id_pub);
1213 e = GNUNET_MQ_msg_extra (ring, pkey_len + sig_len,
1215 written = GNUNET_CRYPTO_write_blindable_pk_to_buffer (&caller_id_pub,
1216 &ring[1],
1217 pkey_len);
1219 ring->key_len = htonl (pkey_len);
1220 ring->sig_len = htonl (sig_len);
1222 (char *) &ring[1]
1223 + written,
1224 sig_len);
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1226 GNUNET_MQ_send (ch->mq, e);
1228}
1229
1230
1240static void *
1242 struct GNUNET_CADET_Channel *channel,
1243 const struct GNUNET_PeerIdentity *initiator)
1244{
1245 struct Line *line = cls;
1246 struct Channel *ch;
1247
1248 (void) initiator;
1250 "Received incoming cadet channel on line %p\n",
1251 line);
1252 ch = GNUNET_new (struct Channel);
1253 ch->status = CS_CALLEE_INIT;
1254 ch->line = line;
1255 ch->channel = channel;
1256 ch->mq = GNUNET_CADET_get_mq (ch->channel);
1257 ch->cid = line->cid_gen++;
1258 GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
1259 return ch;
1260}
1261
1262
1271static void *
1273 struct GNUNET_SERVICE_Client *client,
1274 struct GNUNET_MQ_Handle *mq)
1275{
1276 struct Line *line;
1277
1278 (void) cls;
1279 line = GNUNET_new (struct Line);
1280 line->client = client;
1281 line->mq = mq;
1282 return line;
1283}
1284
1285
1293static void
1296 void *app_ctx)
1297{
1298 struct Line *line = app_ctx;
1299 struct Channel *chn;
1300
1301 (void) cls;
1302 (void) client;
1303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
1304 if (NULL != line->port)
1305 {
1307 line->port = NULL;
1308 }
1309 for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1310 {
1311 chn = ch->next;
1312 ch->line = NULL;
1314 }
1315 GNUNET_free (line);
1316}
1317
1318
1325static void
1327 const struct ClientPhoneRegisterMessage *msg)
1328{
1329 struct Line *line = cls;
1330 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1331 { GNUNET_MQ_hd_var_size (cadet_ring_message,
1333 struct CadetPhoneRingMessage,
1334 NULL),
1335 GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1338 NULL),
1339 GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1342 NULL),
1343 GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1346 NULL),
1347 GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1350 NULL),
1351 GNUNET_MQ_hd_var_size (cadet_audio_message,
1353 struct CadetAudioMessage,
1354 NULL),
1356
1357 line->line_port = msg->line_port;
1359 &msg->line_port,
1361 line,
1362 NULL,
1363 &inbound_end,
1364 cadet_handlers);
1365 if (NULL == line->port)
1366 {
1368 _ ("Could not open line, port %s already in use!\n"),
1369 GNUNET_h2s (&msg->line_port));
1371 return;
1372 }
1374}
1375
1376
1382static void
1384{
1385 (void) cls;
1386 if (NULL != cadet)
1387 {
1389 cadet = NULL;
1390 }
1391}
1392
1393
1401static void
1402run (void *cls,
1403 const struct GNUNET_CONFIGURATION_Handle *c,
1405{
1406 (void) cls;
1407 (void) service;
1408 cfg = c;
1412 if (NULL == cadet)
1413 {
1414 GNUNET_break (0);
1416 return;
1417 }
1419}
1420
1421
1427 "conversation",
1429 &run,
1432 NULL,
1433 GNUNET_MQ_hd_fixed_size (client_register_message,
1436 NULL),
1437 GNUNET_MQ_hd_fixed_size (client_pickup_message,
1440 NULL),
1441 GNUNET_MQ_hd_fixed_size (client_suspend_message,
1444 NULL),
1445 GNUNET_MQ_hd_fixed_size (client_resume_message,
1448 NULL),
1449 GNUNET_MQ_hd_fixed_size (client_hangup_message,
1452 NULL),
1453 GNUNET_MQ_hd_var_size (client_call_message,
1455 struct ClientCallMessage,
1456 NULL),
1457 GNUNET_MQ_hd_var_size (client_audio_message,
1459 struct ClientAudioMessage,
1460 NULL),
1462
1463
1464/* 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_public_key_get_length(const struct GNUNET_CRYPTO_BlindablePublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_BlindablePublicKey.
Definition crypto_pkey.c:85
#define GNUNET_CRYPTO_blinded_key_signature_verify(purp, ps, sig, pub)
Verify a given signature with GNUNET_CRYPTO_BlindablePublicKey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blindable_key_get_public(const struct GNUNET_CRYPTO_BlindablePrivateKey *privkey, struct GNUNET_CRYPTO_BlindablePublicKey *key)
Retrieves the public key representation of a private key.
#define GNUNET_log(kind,...)
ssize_t GNUNET_CRYPTO_write_blinded_key_signature_to_buffer(const struct GNUNET_CRYPTO_BlindableKeySignature *sig, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_BlindableKeySignature to a compact buffer.
void * cls
Closure for mv and cb.
ssize_t GNUNET_CRYPTO_blinded_key_signature_get_length(const struct GNUNET_CRYPTO_BlindableKeySignature *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_BlindablePublicKey *key, size_t *read)
Reads a GNUNET_CRYPTO_BlindablePublicKey from a compact buffer.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_private_key_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_BlindablePrivateKey *key, size_t *read)
Reads a GNUNET_CRYPTO_BlindablePrivateKey from a compact buffer.
#define GNUNET_CRYPTO_blinded_key_sign(priv, ps, sig)
Sign a given block with GNUNET_CRYPTO_BlindablePrivateKey.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
ssize_t GNUNET_CRYPTO_write_blindable_pk_to_buffer(const struct GNUNET_CRYPTO_BlindablePublicKey *key, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_BlindablePublicKey to a compact buffer.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
ssize_t GNUNET_CRYPTO_read_blinded_key_signature_from_buffer(struct GNUNET_CRYPTO_BlindableKeySignature *sig, const void *buffer, size_t len)
Reads a GNUNET_CRYPTO_BlindableKeySignature from a compact buffer.
@ 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: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:636
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_SignaturePurpose 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
An identity signature as per LSD0001.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
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.