GNUnet  0.10.x
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"
33 #include "gnunet_cadet_service.h"
35 #include "conversation.h"
36 
37 
43 #define RING_TIMEOUT GNUNET_TIME_UNIT_DAYS
44 
45 
50 struct Line;
51 
56 {
61 
66 
71 
76 
81 
86 
91 
92 };
93 
94 
101 struct Channel
102 {
103 
107  struct Channel *next;
108 
112  struct Channel *prev;
113 
117  struct Line *line;
118 
123 
128 
133 
137  uint32_t cid;
138 
143 
148 
153 
154 };
155 
156 
160 struct Line
161 {
166 
171 
176 
181 
186 
191  struct GNUNET_HashCode line_port;
192 
196  uint32_t cid_gen;
197 
198 };
199 
200 
204 static const struct GNUNET_CONFIGURATION_Handle *cfg;
205 
209 static struct GNUNET_CADET_Handle *cadet;
210 
215 
216 
225 static struct Channel *
227  uint32_t cid)
228 {
229  for (struct Channel *ch = line->channel_head;
230  NULL != ch;
231  ch = ch->next)
232  if (cid == ch->cid)
233  return ch;
234  return NULL;
235 }
236 
237 
244 static void
246  const struct ClientPhonePickupMessage *msg)
247 {
248  struct Line *line = cls;
249  struct CadetPhonePickupMessage *mppm;
250  struct GNUNET_MQ_Envelope *env;
251  struct Channel *ch;
252 
253  if (NULL == line->port)
254  {
255  /* we never opened the port, bad client! */
256  GNUNET_break_op (0);
258  return;
259  }
260  for (ch = line->channel_head; NULL != ch; ch = ch->next)
261  if (msg->cid == ch->cid)
262  break;
263  if (NULL == ch)
264  {
265  /* could have been destroyed asynchronously, ignore message */
267  "Channel %u not found\n",
268  msg->cid);
270  return;
271  }
272  switch (ch->status)
273  {
274  case CS_CALLEE_INIT:
275  GNUNET_break (0);
277  return;
278  case CS_CALLEE_RINGING:
280  break;
281  case CS_CALLEE_CONNECTED:
282  GNUNET_break (0);
284  return;
285  case CS_CALLEE_SHUTDOWN:
287  "Ignoring client's PICKUP message, line is in SHUTDOWN\n");
288  break;
289  case CS_CALLER_CALLING:
290  case CS_CALLER_CONNECTED:
291  case CS_CALLER_SHUTDOWN:
292  GNUNET_break (0);
294  return;
295  }
298  "Sending PICK_UP message to cadet\n");
299  env = GNUNET_MQ_msg (mppm,
301  GNUNET_MQ_send (ch->mq,
302  env);
304 }
305 
306 
313 static void
315 {
316  struct Line *line = ch->line;
317  struct GNUNET_MQ_Envelope *env;
318  struct ClientPhoneHangupMessage *hup;
319 
320  switch (ch->status)
321  {
322  case CS_CALLEE_INIT:
323  case CS_CALLEE_SHUTDOWN:
324  case CS_CALLER_SHUTDOWN:
325  break;
326  case CS_CALLEE_RINGING:
327  case CS_CALLEE_CONNECTED:
328  case CS_CALLER_CALLING:
329  case CS_CALLER_CONNECTED:
330  if (NULL != line)
331  {
332  env = GNUNET_MQ_msg (hup,
334  hup->cid = ch->cid;
335  GNUNET_MQ_send (line->mq,
336  env);
337  }
338  break;
339  }
340  if (NULL != line)
342  line->channel_tail,
343  ch);
344  GNUNET_free (ch);
345 }
346 
347 
353 static void
355 {
357  "Destroying cadet channels\n");
358  if (NULL != ch->channel)
359  {
361  ch->channel = NULL;
362  }
363  clean_up_channel (ch);
364 }
365 
366 
373 static void
375 {
376  struct Channel *ch = cls;
377 
378  switch (ch->status)
379  {
380  case CS_CALLEE_INIT:
381  GNUNET_break (0);
382  break;
383  case CS_CALLEE_RINGING:
384  GNUNET_break (0);
385  break;
386  case CS_CALLEE_CONNECTED:
387  GNUNET_break (0);
388  break;
389  case CS_CALLEE_SHUTDOWN:
391  break;
392  case CS_CALLER_CALLING:
393  GNUNET_break (0);
394  break;
395  case CS_CALLER_CONNECTED:
396  GNUNET_break (0);
397  break;
398  case CS_CALLER_SHUTDOWN:
400  break;
401  }
402 }
403 
404 
411 static void
413  const struct ClientPhoneHangupMessage *msg)
414 {
415  struct Line *line = cls;
416  struct GNUNET_MQ_Envelope *e;
417  struct CadetPhoneHangupMessage *mhum;
418  struct Channel *ch;
419 
420  for (ch = line->channel_head; NULL != ch; ch = ch->next)
421  if (msg->cid == ch->cid)
422  break;
423  if (NULL == ch)
424  {
425  /* could have been destroyed asynchronously, ignore message */
427  "Channel %u not found\n",
428  msg->cid);
430  return;
431  }
433  "Received HANGUP for channel %u which is in state %d\n",
434  msg->cid,
435  ch->status);
436  switch (ch->status)
437  {
438  case CS_CALLEE_INIT:
439  GNUNET_break (0);
441  return;
442  case CS_CALLEE_RINGING:
444  break;
445  case CS_CALLEE_CONNECTED:
447  break;
448  case CS_CALLEE_SHUTDOWN:
449  /* maybe the other peer closed asynchronously... */
451  return;
452  case CS_CALLER_CALLING:
454  break;
455  case CS_CALLER_CONNECTED:
457  break;
458  case CS_CALLER_SHUTDOWN:
459  /* maybe the other peer closed asynchronously... */
461  return;
462  }
464  "Sending HANG_UP message via cadet\n");
465  e = GNUNET_MQ_msg (mhum,
469  ch);
470  GNUNET_MQ_send (ch->mq,
471  e);
473 }
474 
475 
482 static void
484  const struct ClientPhoneSuspendMessage *msg)
485 {
486  struct Line *line = cls;
487  struct GNUNET_MQ_Envelope *e;
488  struct CadetPhoneSuspendMessage *mhum;
489  struct Channel *ch;
490 
491  for (ch = line->channel_head; NULL != ch; ch = ch->next)
492  if (msg->cid == ch->cid)
493  break;
494  if (NULL == ch)
495  {
496  /* could have been destroyed asynchronously, ignore message */
498  "Channel %u not found\n",
499  msg->cid);
501  return;
502  }
503  if (GNUNET_YES == ch->suspended_local)
504  {
505  GNUNET_break (0);
507  return;
508  }
510  "Received SUSPEND for channel %u which is in state %d\n",
511  msg->cid,
512  ch->status);
513  switch (ch->status)
514  {
515  case CS_CALLEE_INIT:
516  GNUNET_break (0);
518  return;
519  case CS_CALLEE_RINGING:
520  GNUNET_break (0);
522  return;
523  case CS_CALLEE_CONNECTED:
525  break;
526  case CS_CALLEE_SHUTDOWN:
527  /* maybe the other peer closed asynchronously... */
529  return;
530  case CS_CALLER_CALLING:
531  GNUNET_break (0);
533  return;
534  case CS_CALLER_CONNECTED:
536  break;
537  case CS_CALLER_SHUTDOWN:
538  /* maybe the other peer closed asynchronously... */
540  return;
541  }
543  "Sending SUSPEND message via cadet\n");
544  e = GNUNET_MQ_msg (mhum,
546  GNUNET_MQ_send (ch->mq,
547  e);
549 }
550 
551 
558 static void
560  const struct ClientPhoneResumeMessage *msg)
561 {
562  struct Line *line = cls;
563  struct GNUNET_MQ_Envelope *e;
564  struct CadetPhoneResumeMessage *mhum;
565  struct Channel *ch;
566 
567  for (ch = line->channel_head; NULL != ch; ch = ch->next)
568  if (msg->cid == ch->cid)
569  break;
570  if (NULL == ch)
571  {
572  /* could have been destroyed asynchronously, ignore message */
574  "Channel %u not found\n",
575  msg->cid);
577  return;
578  }
579  if (GNUNET_YES != ch->suspended_local)
580  {
581  GNUNET_break (0);
583  return;
584  }
586  "Received RESUME for channel %u which is in state %d\n",
587  msg->cid,
588  ch->status);
589  switch (ch->status)
590  {
591  case CS_CALLEE_INIT:
592  GNUNET_break (0);
594  return;
595  case CS_CALLEE_RINGING:
596  GNUNET_break (0);
598  return;
599  case CS_CALLEE_CONNECTED:
601  break;
602  case CS_CALLEE_SHUTDOWN:
603  /* maybe the other peer closed asynchronously... */
605  return;
606  case CS_CALLER_CALLING:
607  GNUNET_break (0);
609  return;
610  case CS_CALLER_CONNECTED:
612  break;
613  case CS_CALLER_SHUTDOWN:
614  /* maybe the other peer closed asynchronously... */
616  return;
617  }
619  "Sending RESUME message via cadet\n");
620  e = GNUNET_MQ_msg (mhum,
622  GNUNET_MQ_send (ch->mq,
623  e);
625 }
626 
627 
633 static void
635 {
636  struct Channel *ch = cls;
637 
638  ch->env = NULL;
639 }
640 
641 
649 static int
651  const struct ClientAudioMessage *msg)
652 {
653  (void) cls;
654  (void) msg;
655  return GNUNET_OK;
656 }
657 
658 
665 static void
667  const struct ClientAudioMessage *msg)
668 {
669  struct Line *line = cls;
670  struct CadetAudioMessage *mam;
671  struct Channel *ch;
672  size_t size;
673 
674  size = ntohs (msg->header.size) - sizeof (struct ClientAudioMessage);
675  ch = find_channel_by_line (line,
676  msg->cid);
677  if (NULL == ch)
678  {
679  /* could have been destroyed asynchronously, ignore message */
681  "Channel %u not found\n",
682  msg->cid);
684  return;
685  }
686 
687  switch (ch->status)
688  {
689  case CS_CALLEE_INIT:
690  case CS_CALLEE_RINGING:
691  case CS_CALLER_CALLING:
692  GNUNET_break (0);
694  return;
695  case CS_CALLEE_CONNECTED:
696  case CS_CALLER_CONNECTED:
697  /* common case, handled below */
698  break;
699  case CS_CALLEE_SHUTDOWN:
700  case CS_CALLER_SHUTDOWN:
702  "Cadet audio channel in shutdown; audio data dropped\n");
704  return;
705  }
706  if (GNUNET_YES == ch->suspended_local)
707  {
709  "This channel is suspended locally\n");
711  return;
712  }
713  if (NULL != ch->env)
714  {
715  /* NOTE: we may want to not do this and instead combine the data */
717  "Bandwidth insufficient; dropping previous audio data segment\n");
719  ch->env = NULL;
720  }
721 
723  "Received %u bytes of AUDIO data from client CID %u\n",
724  (unsigned int) size,
725  msg->cid);
726  ch->env = GNUNET_MQ_msg_extra (mam,
727  size,
729  GNUNET_memcpy (&mam[1],
730  &msg[1],
731  size);
732  /* FIXME: set options for unreliable transmission */
735  ch);
736  GNUNET_MQ_send (ch->mq,
737  ch->env);
739 }
740 
741 
748 static void
750  const struct CadetPhoneRingMessage *msg)
751 {
752  struct Channel *ch = cls;
753  struct Line *line = ch->line;
754  struct GNUNET_MQ_Envelope *env;
755  struct ClientPhoneRingMessage *cring;
756  struct CadetPhoneRingInfoPS rs;
757 
759  rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
760  rs.line_port = line->line_port;
763 
764  if (GNUNET_OK !=
766  &rs.purpose,
767  &msg->signature,
768  &msg->caller_id))
769  {
770  GNUNET_break_op (0);
772  return;
773  }
775  {
776  /* ancient call, replay? */
777  GNUNET_break_op (0);
778  /* Note that our reliance on time here is awkward; better would be
779  to use a more complex challenge-response protocol against
780  replay attacks. Left for future work ;-). */
782  return;
783  }
784  if (CS_CALLEE_INIT != ch->status)
785  {
786  GNUNET_break_op (0);
788  return;
789  }
792  env = GNUNET_MQ_msg (cring,
794  cring->cid = ch->cid;
795  cring->caller_id = msg->caller_id;
797  "Sending RING message to client. CID is %u\n",
798  (unsigned int) ch->cid);
799  GNUNET_MQ_send (line->mq,
800  env);
801 }
802 
803 
810 static void
812  const struct CadetPhoneHangupMessage *message)
813 {
814  struct Channel *ch = cls;
815  struct Line *line = ch->line;
816  struct GNUNET_MQ_Envelope *env;
817  struct ClientPhoneHangupMessage *hup;
818  enum ChannelStatus status;
819  uint32_t cid;
820 
821  (void) message;
823  cid = ch->cid;
824  status = ch->status;
826  switch (status)
827  {
828  case CS_CALLEE_INIT:
829  GNUNET_break_op (0);
830  return;
831  case CS_CALLEE_RINGING:
832  case CS_CALLEE_CONNECTED:
833  break;
834  case CS_CALLEE_SHUTDOWN:
835  return;
836  case CS_CALLER_CALLING:
837  case CS_CALLER_CONNECTED:
838  break;
839  case CS_CALLER_SHUTDOWN:
840  return;
841  }
843  "Sending HANG UP message to client\n");
844  env = GNUNET_MQ_msg (hup,
846  hup->cid = cid;
847  GNUNET_MQ_send (line->mq,
848  env);
849 }
850 
851 
858 static void
860  const struct CadetPhonePickupMessage *message)
861 {
862  struct Channel *ch = cls;
863  struct Line *line = ch->line;
864  struct GNUNET_MQ_Envelope *env;
865  struct ClientPhonePickedupMessage *pick;
866 
867  (void) message;
869  switch (ch->status)
870  {
871  case CS_CALLEE_INIT:
872  case CS_CALLEE_RINGING:
873  case CS_CALLEE_CONNECTED:
874  GNUNET_break_op (0);
876  return;
877  case CS_CALLEE_SHUTDOWN:
878  GNUNET_break_op (0);
880  return;
881  case CS_CALLER_CALLING:
883  break;
884  case CS_CALLER_CONNECTED:
885  GNUNET_break_op (0);
886  return;
887  case CS_CALLER_SHUTDOWN:
888  GNUNET_break_op (0);
890  return;
891  }
893  "Sending PICKED UP message to client\n");
894  env = GNUNET_MQ_msg (pick,
896  pick->cid = ch->cid;
897  GNUNET_MQ_send (line->mq,
898  env);
899 }
900 
901 
908 static void
910  const struct CadetPhoneSuspendMessage *message)
911 {
912  struct Channel *ch = cls;
913  struct Line *line = ch->line;
914  struct GNUNET_MQ_Envelope *env;
915  struct ClientPhoneSuspendMessage *suspend;
916 
917  (void) message;
920  "Suspending channel CID: %u\n",
921  ch->cid);
922  switch (ch->status)
923  {
924  case CS_CALLEE_INIT:
925  GNUNET_break_op (0);
926  break;
927  case CS_CALLEE_RINGING:
928  GNUNET_break_op (0);
929  break;
930  case CS_CALLEE_CONNECTED:
932  break;
933  case CS_CALLEE_SHUTDOWN:
934  return;
935  case CS_CALLER_CALLING:
936  GNUNET_break_op (0);
937  break;
938  case CS_CALLER_CONNECTED:
940  break;
941  case CS_CALLER_SHUTDOWN:
942  return;
943  }
944  env = GNUNET_MQ_msg (suspend,
946  suspend->cid = ch->cid;
947  GNUNET_MQ_send (line->mq,
948  env);
949 }
950 
951 
958 static void
960  const struct CadetPhoneResumeMessage *msg)
961 {
962  struct Channel *ch = cls;
963  struct Line *line;
964  struct GNUNET_MQ_Envelope *env;
965  struct ClientPhoneResumeMessage *resume;
966 
967  (void) msg;
968  line = ch->line;
970  if (GNUNET_YES != ch->suspended_remote)
971  {
973  "RESUME message received for non-suspended channel, dropping channel.\n");
975  return;
976  }
977  switch (ch->status)
978  {
979  case CS_CALLEE_INIT:
980  GNUNET_break (0);
981  break;
982  case CS_CALLEE_RINGING:
983  GNUNET_break (0);
984  break;
985  case CS_CALLEE_CONNECTED:
987  break;
988  case CS_CALLEE_SHUTDOWN:
989  return;
990  case CS_CALLER_CALLING:
991  GNUNET_break (0);
992  break;
993  case CS_CALLER_CONNECTED:
995  break;
996  case CS_CALLER_SHUTDOWN:
997  return;
998  }
999  env = GNUNET_MQ_msg (resume,
1001  resume->cid = ch->cid;
1002  GNUNET_MQ_send (line->mq,
1003  env);
1004 }
1005 
1006 
1014 static int
1016  const struct CadetAudioMessage *msg)
1017 {
1018  (void) cls;
1019  (void) msg;
1020  return GNUNET_OK; /* any payload is fine */
1021 }
1022 
1023 
1030 static void
1032  const struct CadetAudioMessage *msg)
1033 {
1034  struct Channel *ch = cls;
1035  size_t msize = ntohs (msg->header.size) - sizeof (struct CadetAudioMessage);
1036  struct GNUNET_MQ_Envelope *env;
1037  struct ClientAudioMessage *cam;
1038 
1040  if ( (GNUNET_YES == ch->suspended_local) ||
1041  (GNUNET_YES == ch->suspended_remote) )
1042  {
1044  "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1045  (unsigned int) msize,
1046  ch->cid);
1047  return;
1048  }
1050  "Forwarding %u bytes of AUDIO data to client CID %u\n",
1051  (unsigned int) msize,
1052  ch->cid);
1053  env = GNUNET_MQ_msg_extra (cam,
1054  msize,
1056  cam->cid = ch->cid;
1057  GNUNET_memcpy (&cam[1],
1058  &msg[1],
1059  msize);
1060  GNUNET_MQ_send (ch->line->mq,
1061  env);
1062 }
1063 
1064 
1072 static void
1073 inbound_end (void *cls,
1074  const struct GNUNET_CADET_Channel *channel)
1075 {
1076  struct Channel *ch = cls;
1077 
1078  GNUNET_assert (channel == ch->channel);
1079  ch->channel = NULL;
1081  "Channel destroyed by CADET in state %d\n",
1082  ch->status);
1083  clean_up_channel (ch);
1084 }
1085 
1086 
1093 static void
1095  const struct ClientCallMessage *msg)
1096 {
1097  struct Line *line = cls;
1098  struct Channel *ch = GNUNET_new (struct Channel);
1099  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1100  GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1102  struct CadetPhoneHangupMessage,
1103  ch),
1104  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1106  struct CadetPhonePickupMessage,
1107  ch),
1108  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1110  struct CadetPhoneSuspendMessage,
1111  ch),
1112  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1114  struct CadetPhoneResumeMessage,
1115  ch),
1116  GNUNET_MQ_hd_var_size (cadet_audio_message,
1118  struct CadetAudioMessage,
1119  ch),
1121  };
1122  struct GNUNET_MQ_Envelope *e;
1123  struct CadetPhoneRingMessage *ring;
1124  struct CadetPhoneRingInfoPS rs;
1125 
1126  line->line_port = msg->line_port;
1128  rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
1129  rs.line_port = line->line_port;
1130  rs.target_peer = msg->target;
1131  rs.expiration_time
1133  ch->line = line;
1135  line->channel_tail,
1136  ch);
1137  ch->status = CS_CALLER_CALLING;
1138  ch->channel = GNUNET_CADET_channel_create (cadet,
1139  ch,
1140  &msg->target,
1141  &msg->line_port,
1143  NULL,
1144  &inbound_end,
1145  cadet_handlers);
1146  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1147  e = GNUNET_MQ_msg (ring,
1150  &ring->caller_id);
1151  ring->expiration_time = rs.expiration_time;
1154  &rs.purpose,
1155  &ring->signature));
1157  "Sending RING message via CADET\n");
1158  GNUNET_MQ_send (ch->mq,
1159  e);
1161 }
1162 
1163 
1173 static void *
1174 inbound_channel (void *cls,
1175  struct GNUNET_CADET_Channel *channel,
1176  const struct GNUNET_PeerIdentity *initiator)
1177 {
1178  struct Line *line = cls;
1179  struct Channel *ch;
1180 
1181  (void) initiator;
1183  "Received incoming cadet channel on line %p\n",
1184  line);
1185  ch = GNUNET_new (struct Channel);
1186  ch->status = CS_CALLEE_INIT;
1187  ch->line = line;
1188  ch->channel = channel;
1189  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1190  ch->cid = line->cid_gen++;
1192  line->channel_tail,
1193  ch);
1194  return ch;
1195 }
1196 
1197 
1206 static void *
1208  struct GNUNET_SERVICE_Client *client,
1209  struct GNUNET_MQ_Handle *mq)
1210 {
1211  struct Line *line;
1212 
1213  (void) cls;
1214  line = GNUNET_new (struct Line);
1215  line->client = client;
1216  line->mq = mq;
1217  return line;
1218 }
1219 
1220 
1228 static void
1230  struct GNUNET_SERVICE_Client *client,
1231  void *app_ctx)
1232 {
1233  struct Line *line = app_ctx;
1234  struct Channel *chn;
1235 
1236  (void) cls;
1237  (void) client;
1239  "Client disconnected, closing line\n");
1240  if (NULL != line->port)
1241  {
1242  GNUNET_CADET_close_port (line->port);
1243  line->port = NULL;
1244  }
1245  for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1246  {
1247  chn = ch->next;
1248  ch->line = NULL;
1250  }
1251  GNUNET_free (line);
1252 }
1253 
1254 
1261 static void
1263  const struct ClientPhoneRegisterMessage *msg)
1264 {
1265  struct Line *line = cls;
1266  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1267  GNUNET_MQ_hd_fixed_size (cadet_ring_message,
1269  struct CadetPhoneRingMessage,
1270  NULL),
1271  GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1273  struct CadetPhoneHangupMessage,
1274  NULL),
1275  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1277  struct CadetPhonePickupMessage,
1278  NULL),
1279  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1281  struct CadetPhoneSuspendMessage,
1282  NULL),
1283  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1285  struct CadetPhoneResumeMessage,
1286  NULL),
1287  GNUNET_MQ_hd_var_size (cadet_audio_message,
1289  struct CadetAudioMessage,
1290  NULL),
1292  };
1293 
1294  line->line_port = msg->line_port;
1295  line->port = GNUNET_CADET_open_port (cadet,
1296  &msg->line_port,
1297  &inbound_channel,
1298  line,
1299  NULL,
1300  &inbound_end,
1301  cadet_handlers);
1302  if (NULL == line->port)
1303  {
1305  _("Could not open line, port %s already in use!\n"),
1306  GNUNET_h2s (&msg->line_port));
1308  return;
1309  }
1311 }
1312 
1313 
1319 static void
1321 {
1322  (void) cls;
1323  if (NULL != cadet)
1324  {
1325  GNUNET_CADET_disconnect (cadet);
1326  cadet = NULL;
1327  }
1328 }
1329 
1330 
1338 static void
1339 run (void *cls,
1340  const struct GNUNET_CONFIGURATION_Handle *c,
1342 {
1343  (void) cls;
1344  (void) service;
1345  cfg = c;
1348  &my_identity));
1349  cadet = GNUNET_CADET_connect (cfg);
1350  if (NULL == cadet)
1351  {
1352  GNUNET_break (0);
1354  return;
1355  }
1357  NULL);
1358 }
1359 
1360 
1365 ("conversation",
1367  &run,
1370  NULL,
1371  GNUNET_MQ_hd_fixed_size (client_register_message,
1374  NULL),
1375  GNUNET_MQ_hd_fixed_size (client_pickup_message,
1377  struct ClientPhonePickupMessage,
1378  NULL),
1379  GNUNET_MQ_hd_fixed_size (client_suspend_message,
1382  NULL),
1383  GNUNET_MQ_hd_fixed_size (client_resume_message,
1385  struct ClientPhoneResumeMessage,
1386  NULL),
1387  GNUNET_MQ_hd_fixed_size (client_hangup_message,
1389  struct ClientPhoneHangupMessage,
1390  NULL),
1391  GNUNET_MQ_hd_fixed_size (client_call_message,
1393  struct ClientCallMessage,
1394  NULL),
1395  GNUNET_MQ_hd_var_size (client_audio_message,
1397  struct ClientAudioMessage,
1398  NULL),
1400 
1401 
1402 /* end of gnunet-service-conversation.c */
static void inbound_end(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever an inbound channel is destroyed.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:146
Client -> Service message to call a phone.
Definition: conversation.h:214
struct Channel * prev
This is a DLL.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
ChannelStatus
The possible connection status.
enum ChannelStatus status
Current status of this line.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:849
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
Cadet message to make a phone ring.
Definition: conversation.h:296
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
uint64_t rel_value_us
The actual value.
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.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_CRYPTO_ecdsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
Definition: crypto_ecc.c:1048
static void handle_client_hangup_message(void *cls, const struct ClientPhoneHangupMessage *msg)
Function to handle a hangup request message from the client.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
#define RING_TIMEOUT
How long is our signature on a call valid? Needs to be long enough for time zone differences and netw...
Opaque handle to the service.
Definition: cadet_api.c:38
Handle to a service.
Definition: service.c:116
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
static int check_cadet_audio_message(void *cls, const struct CadetAudioMessage *msg)
Function to check an audio message incoming over cadet.
struct GNUNET_CRYPTO_EcdsaPublicKey caller_id
Who is calling us?
Definition: conversation.h:108
constants for network protocols
static void handle_cadet_resume_message(void *cls, const struct CadetPhoneResumeMessage *msg)
Function to handle a resume message incoming over cadet.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL
Client <- Server message to indicate a ringing phone.
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:245
static void handle_cadet_pickup_message(void *cls, const struct CadetPhonePickupMessage *message)
Function to handle a pickup message incoming over cadet.
#define GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING
Signature of a conversation ring.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
A struct Channel represents a cadet channel, which is a P2P connection to another conversation servic...
Information signed in a struct CadetPhoneRingMessage whereby the caller self-identifies to the receiv...
Definition: conversation.h:267
struct GNUNET_PeerIdentity target_peer
Which peer is the call for?
Definition: conversation.h:283
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO.
Definition: conversation.h:386
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:185
static void handle_client_audio_message(void *cls, const struct ClientAudioMessage *msg)
Function to handle audio data from the client.
static void handle_cadet_audio_message(void *cls, const struct CadetAudioMessage *msg)
Function to handle an audio message incoming over cadet.
Enable channel reliability, lost messages will be retransmitted.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO
Cadet: audio data.
struct GNUNET_PeerIdentity target
Which peer is hosting the line?
Definition: conversation.h:229
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND
Cadet: phone suspended.
static void channel_audio_sent_notify(void *cls)
Transmission of audio data via cadet channel finished.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
static struct Experiment * e
struct GNUNET_CADET_Port * port
Our open port.
Client -> Service message to register a phone.
Definition: conversation.h:70
#define GNUNET_NO
Definition: gnunet_common.h:81
Opaque handle to a channel.
Definition: cadet_api.c:80
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
struct GNUNET_CADET_Channel * channel
Handle for the channel.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP
Cadet: hang up / refuse call.
uint32_t cid_gen
Generator for channel IDs.
struct Channel * channel_tail
This is a DLL.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO
Client <-> Server message to send audio data.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP
Client -> Server message to reject/hangup a call.
Client -> Service pick up phone that is ringing.
Definition: conversation.h:154
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
struct GNUNET_CRYPTO_EcdsaPrivateKey caller_id
Identity of the caller.
Definition: conversation.h:239
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature over a struct CadetPhoneRingInfoPS
Definition: conversation.h:321
We&#39;re in shutdown, sending hangup messages before cleaning up.
static void handle_cadet_ring_message(void *cls, const struct CadetPhoneRingMessage *msg)
Function to handle a ring message incoming over cadet.
We are waiting for the phone to be picked up.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:995
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static void handle_client_register_message(void *cls, const struct ClientPhoneRegisterMessage *msg)
Function to register a phone.
static void handle_client_call_message(void *cls, const struct ClientCallMessage *msg)
Function to handle call request from the client.
Handle to a client that is connected to a service.
Definition: service.c:249
int8_t suspended_local
GNUNET_YES if the channel was suspended by the local client.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING
Client <- Server message to indicate a ringing phone.
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:931
#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:52
static void clean_up_channel(struct Channel *ch)
Channel went down, notify client and free data structure.
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 incomming MQ-based channels.
Definition: cadet_api.c:1029
#define GNUNET_memcpy(dst, src, n)
struct Line * line
Line associated with the channel.
void * cls
Closure for mv and cb.
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:774
Client <-> Service hang up phone that may or may not be ringing.
Definition: conversation.h:174
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t cid
Call ID of the corresponding GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL.
Definition: conversation.h:258
static void handle_client_suspend_message(void *cls, const struct ClientPhoneSuspendMessage *msg)
Function to handle a suspend request message from the client.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP
Service -> Client message to notify that phone was picked up.
struct GNUNET_MQ_Envelope * env
Temporary buffer for audio data in the mq.
We just got the connection, but no introduction yet.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:288
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP
Cadet: pick up phone (establish audio channel)
Our phone is ringing, waiting for the client to pick up.
static void handle_cadet_hangup_message(void *cls, const struct CadetPhoneHangupMessage *message)
Function to handle a hangup message incoming over cadet.
static void destroy_line_cadet_channels(struct Channel *ch)
Destroy a channel.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME
Cadet: phone resumed.
static struct Channel * find_channel_by_line(struct Line *line, uint32_t cid)
Given a cid, find the corresponding channel given a line.
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
Message handler for a specific message type.
static void mq_done_finish_caller_shutdown(void *cls)
We are done signalling shutdown to the other peer.
A struct Line connects a local client with cadet channels.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME
Client <-> Server message to resume connection.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
uint32_t cid
CID, internal caller ID number used in the future to identify which active call we are talking about...
Definition: conversation.h:103
struct GNUNET_MQ_Handle * mq
Message queue for client.
Cadet message for phone suspended.
Definition: conversation.h:355
struct GNUNET_HashCode line_port
Phone line / CADET port to register.
Definition: conversation.h:85
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose for the signature, must be GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING.
Definition: conversation.h:273
Service <-> Client message for phone was resumed.
Definition: conversation.h:135
Service -> Client: other peer has picked up the phone, we are now talking.
Definition: conversation.h:247
Handle to a message queue.
Definition: mq.c:85
static void handle_cadet_suspend_message(void *cls, const struct CadetPhoneSuspendMessage *message)
Function to handle a suspend message incoming over cadet.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
A client disconnected.
struct GNUNET_HashCode line_port
Port number we are listening on (to verify signatures).
struct GNUNET_SERVICE_Client * client
Handle to the line client.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_HashCode line_port
Which phone line to call at the peer?
Definition: conversation.h:234
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:973
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER
Client -> Server message to register a phone.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:165
configuration data
Definition: configuration.c:85
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING
Cadet: call initiation.
Service -> Client message for phone is ringing.
Definition: conversation.h:92
Cadet message for phone resumed.
Definition: conversation.h:368
static void do_shutdown(void *cls)
Shutdown nicely.
struct Channel * channel_head
This is a DLL.
#define GNUNET_log(kind,...)
Message Client <-> Service to transmit the audio.
Definition: conversation.h:193
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 int check_client_audio_message(void *cls, const struct ClientAudioMessage *msg)
Function to check audio data from the client.
Opaque handle to a port.
Definition: cadet_api.c:151
int GNUNET_CRYPTO_get_peer_identity(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst)
Retrieve the identity of the host&#39;s peer.
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:331
static void handle_client_resume_message(void *cls, const struct ClientPhoneResumeMessage *msg)
Function to handle a resume request message from the client.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:882
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO.
Definition: conversation.h:198
#define GNUNET_YES
Definition: gnunet_common.h:80
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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:353
Cadet message for hanging up.
Definition: conversation.h:329
We&#39;re in shutdown, sending hangup messages before cleaning up.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND
Client <-> Server message to suspend connection.
static void handle_client_pickup_message(void *cls, const struct ClientPhonePickupMessage *msg)
Function to handle a pickup request message from the client.
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_fixed_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.
struct GNUNET_MQ_Handle * mq
Message queue for control messages.
Service <-> Client message for phone was suspended.
Definition: conversation.h:116
Cadet message for picking up.
Definition: conversation.h:342
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
void GNUNET_MQ_send_cancel(struct GNUNET_MQ_Envelope *ev)
Cancel sending the message.
Definition: mq.c:916
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:911
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
struct Channel * next
This is a DLL.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP
Client -> Server message to reject/hangup a call.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
int8_t suspended_remote
GNUNET_YES if the channel was suspended by the other peer.
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:127
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:316
Cadet message to transmit the audio.
Definition: conversation.h:381
#define GNUNET_free(ptr)
Wrapper around free.
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, enum GNUNET_CADET_ChannelOption options, 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:1088
struct GNUNET_CRYPTO_EcdsaPublicKey caller_id
Who is calling us? (also who is signing).
Definition: conversation.h:311
uint32_t cid
Channel identifier we use for this call with the client.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1142
struct GNUNET_HashCode line_port
Which port did the call go to?
Definition: conversation.h:278
uint32_t cid
CID, internal caller ID to identify which active call we are sending data to.
Definition: conversation.h:204