GNUnet  0.11.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 
100 struct Channel
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 
157 struct Line
158 {
163 
168 
173 
178 
183 
188  struct GNUNET_HashCode line_port;
189 
193  uint32_t cid_gen;
194 };
195 
196 
200 static const struct GNUNET_CONFIGURATION_Handle *cfg;
201 
205 static struct GNUNET_CADET_Handle *cadet;
206 
211 
212 
221 static struct Channel *
222 find_channel_by_line (struct Line *line, uint32_t cid)
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 
237 static 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 
270  case CS_CALLEE_RINGING:
272  break;
273 
274  case CS_CALLEE_CONNECTED:
275  GNUNET_break (0);
277  return;
278 
279  case CS_CALLEE_SHUTDOWN:
281  "Ignoring client's PICKUP message, line is in SHUTDOWN\n");
282  break;
283 
284  case CS_CALLER_CALLING:
285  case CS_CALLER_CONNECTED:
286  case CS_CALLER_SHUTDOWN:
287  GNUNET_break (0);
289  return;
290  }
292  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICK_UP message to cadet\n");
293  env =
295  GNUNET_MQ_send (ch->mq, env);
297 }
298 
299 
306 static 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:
316  case CS_CALLEE_SHUTDOWN:
317  case CS_CALLER_SHUTDOWN:
318  break;
319 
320  case CS_CALLEE_RINGING:
321  case CS_CALLEE_CONNECTED:
322  case CS_CALLER_CALLING:
323  case CS_CALLER_CONNECTED:
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)
335  GNUNET_free (ch);
336 }
337 
338 
344 static void
346 {
347  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying cadet channels\n");
348  if (NULL != ch->channel)
349  {
351  ch->channel = NULL;
352  }
353  clean_up_channel (ch);
354 }
355 
356 
363 static 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 
374  case CS_CALLEE_RINGING:
375  GNUNET_break (0);
376  break;
377 
378  case CS_CALLEE_CONNECTED:
379  GNUNET_break (0);
380  break;
381 
382  case CS_CALLEE_SHUTDOWN:
384  break;
385 
386  case CS_CALLER_CALLING:
387  GNUNET_break (0);
388  break;
389 
390  case CS_CALLER_CONNECTED:
391  GNUNET_break (0);
392  break;
393 
394  case CS_CALLER_SHUTDOWN:
396  break;
397  }
398 }
399 
400 
407 static 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 
437  case CS_CALLEE_RINGING:
439  break;
440 
441  case CS_CALLEE_CONNECTED:
443  break;
444 
445  case CS_CALLEE_SHUTDOWN:
446  /* maybe the other peer closed asynchronously... */
448  return;
449 
450  case CS_CALLER_CALLING:
452  break;
453 
454  case CS_CALLER_CONNECTED:
456  break;
457 
458  case CS_CALLER_SHUTDOWN:
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 
478 static 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 
514  case CS_CALLEE_RINGING:
515  GNUNET_break (0);
517  return;
518 
519  case CS_CALLEE_CONNECTED:
521  break;
522 
523  case CS_CALLEE_SHUTDOWN:
524  /* maybe the other peer closed asynchronously... */
526  return;
527 
528  case CS_CALLER_CALLING:
529  GNUNET_break (0);
531  return;
532 
533  case CS_CALLER_CONNECTED:
535  break;
536 
537  case CS_CALLER_SHUTDOWN:
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 
556 static 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 
592  case CS_CALLEE_RINGING:
593  GNUNET_break (0);
595  return;
596 
597  case CS_CALLEE_CONNECTED:
599  break;
600 
601  case CS_CALLEE_SHUTDOWN:
602  /* maybe the other peer closed asynchronously... */
604  return;
605 
606  case CS_CALLER_CALLING:
607  GNUNET_break (0);
609  return;
610 
611  case CS_CALLER_CONNECTED:
613  break;
614 
615  case CS_CALLER_SHUTDOWN:
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 
632 static void
634 {
635  struct Channel *ch = cls;
636 
637  ch->env = NULL;
638 }
639 
640 
648 static int
650 {
651  (void) cls;
652  (void) msg;
653  return GNUNET_OK;
654 }
655 
656 
663 static 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);
672  ch = find_channel_by_line (line, msg->cid);
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:
684  case CS_CALLEE_RINGING:
685  case CS_CALLER_CALLING:
686  GNUNET_break (0);
688  return;
689 
690  case CS_CALLEE_CONNECTED:
691  case CS_CALLER_CONNECTED:
692  /* common case, handled below */
693  break;
694 
695  case CS_CALLEE_SHUTDOWN:
696  case CS_CALLER_SHUTDOWN:
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 
732 
739 static void
741 {
742  struct Channel *ch = cls;
743  struct Line *line = ch->line;
744  struct GNUNET_MQ_Envelope *env;
745  struct ClientPhoneRingMessage *cring;
746  struct CadetPhoneRingInfoPS rs;
747 
749  rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
750  rs.line_port = line->line_port;
753 
754  if (GNUNET_OK !=
757  &rs,
758  &msg->signature,
759  &msg->caller_id))
760  {
761  GNUNET_break_op (0);
763  return;
764  }
767  .rel_value_us)
768  {
769  /* ancient call, replay? */
770  GNUNET_break_op (0);
771  /* Note that our reliance on time here is awkward; better would be
772  to use a more complex challenge-response protocol against
773  replay attacks. Left for future work ;-). */
775  return;
776  }
777  if (CS_CALLEE_INIT != ch->status)
778  {
779  GNUNET_break_op (0);
781  return;
782  }
786  cring->cid = ch->cid;
787  cring->caller_id = msg->caller_id;
789  "Sending RING message to client. CID is %u\n",
790  (unsigned int) ch->cid);
791  GNUNET_MQ_send (line->mq, env);
792 }
793 
794 
801 static void
803  const struct CadetPhoneHangupMessage *message)
804 {
805  struct Channel *ch = cls;
806  struct Line *line = ch->line;
807  struct GNUNET_MQ_Envelope *env;
808  struct ClientPhoneHangupMessage *hup;
809  enum ChannelStatus status;
810  uint32_t cid;
811 
812  (void) message;
814  cid = ch->cid;
815  status = ch->status;
817  switch (status)
818  {
819  case CS_CALLEE_INIT:
820  GNUNET_break_op (0);
821  return;
822 
823  case CS_CALLEE_RINGING:
824  case CS_CALLEE_CONNECTED:
825  break;
826 
827  case CS_CALLEE_SHUTDOWN:
828  return;
829 
830  case CS_CALLER_CALLING:
831  case CS_CALLER_CONNECTED:
832  break;
833 
834  case CS_CALLER_SHUTDOWN:
835  return;
836  }
837  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
839  hup->cid = cid;
840  GNUNET_MQ_send (line->mq, env);
841 }
842 
843 
850 static void
852  const struct CadetPhonePickupMessage *message)
853 {
854  struct Channel *ch = cls;
855  struct Line *line = ch->line;
856  struct GNUNET_MQ_Envelope *env;
857  struct ClientPhonePickedupMessage *pick;
858 
859  (void) message;
861  switch (ch->status)
862  {
863  case CS_CALLEE_INIT:
864  case CS_CALLEE_RINGING:
865  case CS_CALLEE_CONNECTED:
866  GNUNET_break_op (0);
868  return;
869 
870  case CS_CALLEE_SHUTDOWN:
871  GNUNET_break_op (0);
873  return;
874 
875  case CS_CALLER_CALLING:
877  break;
878 
879  case CS_CALLER_CONNECTED:
880  GNUNET_break_op (0);
881  return;
882 
883  case CS_CALLER_SHUTDOWN:
884  GNUNET_break_op (0);
886  return;
887  }
888  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
889  env =
891  pick->cid = ch->cid;
892  GNUNET_MQ_send (line->mq, env);
893 }
894 
895 
902 static void
904  const struct CadetPhoneSuspendMessage *message)
905 {
906  struct Channel *ch = cls;
907  struct Line *line = ch->line;
908  struct GNUNET_MQ_Envelope *env;
909  struct ClientPhoneSuspendMessage *suspend;
910 
911  (void) message;
913  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
914  switch (ch->status)
915  {
916  case CS_CALLEE_INIT:
917  GNUNET_break_op (0);
918  break;
919 
920  case CS_CALLEE_RINGING:
921  GNUNET_break_op (0);
922  break;
923 
924  case CS_CALLEE_CONNECTED:
926  break;
927 
928  case CS_CALLEE_SHUTDOWN:
929  return;
930 
931  case CS_CALLER_CALLING:
932  GNUNET_break_op (0);
933  break;
934 
935  case CS_CALLER_CONNECTED:
937  break;
938 
939  case CS_CALLER_SHUTDOWN:
940  return;
941  }
942  env =
944  suspend->cid = ch->cid;
945  GNUNET_MQ_send (line->mq, env);
946 }
947 
948 
955 static void
957  const struct CadetPhoneResumeMessage *msg)
958 {
959  struct Channel *ch = cls;
960  struct Line *line;
961  struct GNUNET_MQ_Envelope *env;
962  struct ClientPhoneResumeMessage *resume;
963 
964  (void) msg;
965  line = ch->line;
967  if (GNUNET_YES != ch->suspended_remote)
968  {
969  GNUNET_log (
971  "RESUME message received for non-suspended channel, dropping channel.\n");
973  return;
974  }
975  switch (ch->status)
976  {
977  case CS_CALLEE_INIT:
978  GNUNET_break (0);
979  break;
980 
981  case CS_CALLEE_RINGING:
982  GNUNET_break (0);
983  break;
984 
985  case CS_CALLEE_CONNECTED:
987  break;
988 
989  case CS_CALLEE_SHUTDOWN:
990  return;
991 
992  case CS_CALLER_CALLING:
993  GNUNET_break (0);
994  break;
995 
996  case CS_CALLER_CONNECTED:
998  break;
999 
1000  case CS_CALLER_SHUTDOWN:
1001  return;
1002  }
1003  env =
1005  resume->cid = ch->cid;
1006  GNUNET_MQ_send (line->mq, env);
1007 }
1008 
1009 
1017 static int
1019 {
1020  (void) cls;
1021  (void) msg;
1022  return GNUNET_OK; /* any payload is fine */
1023 }
1024 
1025 
1032 static void
1034 {
1035  struct Channel *ch = cls;
1036  size_t msize = ntohs (msg->header.size) - sizeof(struct CadetAudioMessage);
1037  struct GNUNET_MQ_Envelope *env;
1038  struct ClientAudioMessage *cam;
1039 
1041  if ((GNUNET_YES == ch->suspended_local) ||
1042  (GNUNET_YES == ch->suspended_remote))
1043  {
1044  GNUNET_log (
1046  "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1047  (unsigned int) msize,
1048  ch->cid);
1049  return;
1050  }
1052  "Forwarding %u bytes of AUDIO data to client CID %u\n",
1053  (unsigned int) msize,
1054  ch->cid);
1055  env =
1057  cam->cid = ch->cid;
1058  GNUNET_memcpy (&cam[1], &msg[1], msize);
1059  GNUNET_MQ_send (ch->line->mq, env);
1060 }
1061 
1062 
1070 static void
1071 inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
1072 {
1073  struct Channel *ch = cls;
1074 
1075  GNUNET_assert (channel == ch->channel);
1076  ch->channel = NULL;
1078  "Channel destroyed by CADET in state %d\n",
1079  ch->status);
1080  clean_up_channel (ch);
1081 }
1082 
1083 
1090 static void
1092 {
1093  struct Line *line = cls;
1094  struct Channel *ch = GNUNET_new (struct Channel);
1095  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1096  { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1098  struct CadetPhoneHangupMessage,
1099  ch),
1100  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1102  struct CadetPhonePickupMessage,
1103  ch),
1104  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1106  struct CadetPhoneSuspendMessage,
1107  ch),
1108  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1110  struct CadetPhoneResumeMessage,
1111  ch),
1112  GNUNET_MQ_hd_var_size (cadet_audio_message,
1114  struct CadetAudioMessage,
1115  ch),
1116  GNUNET_MQ_handler_end () };
1117  struct GNUNET_MQ_Envelope *e;
1118  struct CadetPhoneRingMessage *ring;
1119  struct CadetPhoneRingInfoPS rs;
1120 
1121  line->line_port = msg->line_port;
1123  rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
1124  rs.line_port = line->line_port;
1125  rs.target_peer = msg->target;
1126  rs.expiration_time =
1128  ch->line = line;
1130  ch->status = CS_CALLER_CALLING;
1131  ch->channel = GNUNET_CADET_channel_create (cadet,
1132  ch,
1133  &msg->target,
1134  &msg->line_port,
1135  NULL,
1136  &inbound_end,
1137  cadet_handlers);
1138  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1141  ring->expiration_time = rs.expiration_time;
1142  GNUNET_IDENTITY_sign (&msg->caller_id, &rs, &ring->signature);
1143  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1144  GNUNET_MQ_send (ch->mq, e);
1146 }
1147 
1148 
1158 static void *
1159 inbound_channel (void *cls,
1160  struct GNUNET_CADET_Channel *channel,
1161  const struct GNUNET_PeerIdentity *initiator)
1162 {
1163  struct Line *line = cls;
1164  struct Channel *ch;
1165 
1166  (void) initiator;
1168  "Received incoming cadet channel on line %p\n",
1169  line);
1170  ch = GNUNET_new (struct Channel);
1171  ch->status = CS_CALLEE_INIT;
1172  ch->line = line;
1173  ch->channel = channel;
1174  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1175  ch->cid = line->cid_gen++;
1177  return ch;
1178 }
1179 
1180 
1189 static void *
1191  struct GNUNET_SERVICE_Client *client,
1192  struct GNUNET_MQ_Handle *mq)
1193 {
1194  struct Line *line;
1195 
1196  (void) cls;
1197  line = GNUNET_new (struct Line);
1198  line->client = client;
1199  line->mq = mq;
1200  return line;
1201 }
1202 
1203 
1211 static void
1213  struct GNUNET_SERVICE_Client *client,
1214  void *app_ctx)
1215 {
1216  struct Line *line = app_ctx;
1217  struct Channel *chn;
1218 
1219  (void) cls;
1220  (void) client;
1221  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
1222  if (NULL != line->port)
1223  {
1224  GNUNET_CADET_close_port (line->port);
1225  line->port = NULL;
1226  }
1227  for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1228  {
1229  chn = ch->next;
1230  ch->line = NULL;
1232  }
1233  GNUNET_free (line);
1234 }
1235 
1236 
1243 static void
1245  const struct ClientPhoneRegisterMessage *msg)
1246 {
1247  struct Line *line = cls;
1248  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1249  { GNUNET_MQ_hd_fixed_size (cadet_ring_message,
1251  struct CadetPhoneRingMessage,
1252  NULL),
1253  GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1255  struct CadetPhoneHangupMessage,
1256  NULL),
1257  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1259  struct CadetPhonePickupMessage,
1260  NULL),
1261  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1263  struct CadetPhoneSuspendMessage,
1264  NULL),
1265  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1267  struct CadetPhoneResumeMessage,
1268  NULL),
1269  GNUNET_MQ_hd_var_size (cadet_audio_message,
1271  struct CadetAudioMessage,
1272  NULL),
1273  GNUNET_MQ_handler_end () };
1274 
1275  line->line_port = msg->line_port;
1276  line->port = GNUNET_CADET_open_port (cadet,
1277  &msg->line_port,
1278  &inbound_channel,
1279  line,
1280  NULL,
1281  &inbound_end,
1282  cadet_handlers);
1283  if (NULL == line->port)
1284  {
1286  _ ("Could not open line, port %s already in use!\n"),
1287  GNUNET_h2s (&msg->line_port));
1289  return;
1290  }
1292 }
1293 
1294 
1300 static void
1302 {
1303  (void) cls;
1304  if (NULL != cadet)
1305  {
1306  GNUNET_CADET_disconnect (cadet);
1307  cadet = NULL;
1308  }
1309 }
1310 
1311 
1319 static void
1320 run (void *cls,
1321  const struct GNUNET_CONFIGURATION_Handle *c,
1323 {
1324  (void) cls;
1325  (void) service;
1326  cfg = c;
1329  cadet = GNUNET_CADET_connect (cfg);
1330  if (NULL == cadet)
1331  {
1332  GNUNET_break (0);
1334  return;
1335  }
1337 }
1338 
1339 
1344  "conversation",
1346  &run,
1349  NULL,
1350  GNUNET_MQ_hd_fixed_size (client_register_message,
1353  NULL),
1354  GNUNET_MQ_hd_fixed_size (client_pickup_message,
1356  struct ClientPhonePickupMessage,
1357  NULL),
1358  GNUNET_MQ_hd_fixed_size (client_suspend_message,
1361  NULL),
1362  GNUNET_MQ_hd_fixed_size (client_resume_message,
1364  struct ClientPhoneResumeMessage,
1365  NULL),
1366  GNUNET_MQ_hd_fixed_size (client_hangup_message,
1368  struct ClientPhoneHangupMessage,
1369  NULL),
1370  GNUNET_MQ_hd_fixed_size (client_call_message,
1372  struct ClientCallMessage,
1373  NULL),
1374  GNUNET_MQ_hd_var_size (client_audio_message,
1376  struct ClientAudioMessage,
1377  NULL),
1379 
1380 
1381 /* 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:210
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:775
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
Cadet message to make a phone ring.
Definition: conversation.h:291
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:673
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.
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_IDENTITY_PrivateKey caller_id
Identity of the caller.
Definition: conversation.h:235
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:1331
static int check_cadet_audio_message(void *cls, const struct CadetAudioMessage *msg)
Function to check an audio message incoming over cadet.
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:246
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:262
struct GNUNET_PeerIdentity target_peer
Which peer is the call for?
Definition: conversation.h:278
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO.
Definition: conversation.h:376
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:183
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.
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO
Cadet: audio data.
struct GNUNET_PeerIdentity target
Which peer is hosting the line?
Definition: conversation.h:225
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:72
Opaque handle to a channel.
Definition: cadet.h:116
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#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:153
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:910
#define GNUNET_IDENTITY_sign(priv, ps, sig)
Sign a given block with GNUNET_IDENTITY_PrivateKey.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
static void handle_client_register_message(void *cls, const struct ClientPhoneRegisterMessage *msg)
Function to register a phone.
#define GNUNET_IDENTITY_signature_verify(purp, ps, sig, pub)
Verify a given signature with GNUNET_IDENTITY_PublicKey.
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:250
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.
#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:970
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:787
Client <-> Service hang up phone that may or may not be ringing.
Definition: conversation.h:172
#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:254
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:283
#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.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:175
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:2325
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
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
struct GNUNET_MQ_Handle * mq
Message queue for client.
Cadet message for phone suspended.
Definition: conversation.h:347
struct GNUNET_HashCode line_port
Phone line / CADET port to register.
Definition: conversation.h:87
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose for the signature, must be GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING.
Definition: conversation.h:268
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:243
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:230
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:888
#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:164
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:1031
configuration data
Definition: configuration.c:84
struct GNUNET_IDENTITY_Signature signature
Signature over a struct CadetPhoneRingInfoPS
Definition: conversation.h:316
struct GNUNET_IDENTITY_PublicKey caller_id
Who is calling us? (also who is signing).
Definition: conversation.h:306
#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING
Cadet: call initiation.
Service -> Client message for phone is ringing.
Definition: conversation.h:94
Cadet message for phone resumed.
Definition: conversation.h:359
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:190
struct GNUNET_IDENTITY_PublicKey caller_id
Who is calling us?
Definition: conversation.h:110
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:79
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:808
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO.
Definition: conversation.h:195
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:355
Cadet message for hanging up.
Definition: conversation.h:323
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:117
Cadet message for picking up.
Definition: conversation.h:335
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
void GNUNET_MQ_send_cancel(struct GNUNET_MQ_Envelope *ev)
Cancel sending the message.
Definition: mq.c:929
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
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:128
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:311
Cadet message to transmit the audio.
Definition: conversation.h:371
#define GNUNET_free(ptr)
Wrapper around free.
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:1082
struct GNUNET_HashCode line_port
Which port did the call go to?
Definition: conversation.h:273
uint32_t cid
CID, internal caller ID to identify which active call we are sending data to.
Definition: conversation.h:201