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 !=
756  &rs.purpose,
757  &msg->signature,
758  &msg->caller_id))
759  {
760  GNUNET_break_op (0);
762  return;
763  }
766  .rel_value_us)
767  {
768  /* ancient call, replay? */
769  GNUNET_break_op (0);
770  /* Note that our reliance on time here is awkward; better would be
771  to use a more complex challenge-response protocol against
772  replay attacks. Left for future work ;-). */
774  return;
775  }
776  if (CS_CALLEE_INIT != ch->status)
777  {
778  GNUNET_break_op (0);
780  return;
781  }
785  cring->cid = ch->cid;
786  cring->caller_id = msg->caller_id;
788  "Sending RING message to client. CID is %u\n",
789  (unsigned int) ch->cid);
790  GNUNET_MQ_send (line->mq, env);
791 }
792 
793 
800 static void
802  const struct CadetPhoneHangupMessage *message)
803 {
804  struct Channel *ch = cls;
805  struct Line *line = ch->line;
806  struct GNUNET_MQ_Envelope *env;
807  struct ClientPhoneHangupMessage *hup;
808  enum ChannelStatus status;
809  uint32_t cid;
810 
811  (void) message;
813  cid = ch->cid;
814  status = ch->status;
816  switch (status)
817  {
818  case CS_CALLEE_INIT:
819  GNUNET_break_op (0);
820  return;
821 
822  case CS_CALLEE_RINGING:
823  case CS_CALLEE_CONNECTED:
824  break;
825 
826  case CS_CALLEE_SHUTDOWN:
827  return;
828 
829  case CS_CALLER_CALLING:
830  case CS_CALLER_CONNECTED:
831  break;
832 
833  case CS_CALLER_SHUTDOWN:
834  return;
835  }
836  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
838  hup->cid = cid;
839  GNUNET_MQ_send (line->mq, env);
840 }
841 
842 
849 static void
851  const struct CadetPhonePickupMessage *message)
852 {
853  struct Channel *ch = cls;
854  struct Line *line = ch->line;
855  struct GNUNET_MQ_Envelope *env;
856  struct ClientPhonePickedupMessage *pick;
857 
858  (void) message;
860  switch (ch->status)
861  {
862  case CS_CALLEE_INIT:
863  case CS_CALLEE_RINGING:
864  case CS_CALLEE_CONNECTED:
865  GNUNET_break_op (0);
867  return;
868 
869  case CS_CALLEE_SHUTDOWN:
870  GNUNET_break_op (0);
872  return;
873 
874  case CS_CALLER_CALLING:
876  break;
877 
878  case CS_CALLER_CONNECTED:
879  GNUNET_break_op (0);
880  return;
881 
882  case CS_CALLER_SHUTDOWN:
883  GNUNET_break_op (0);
885  return;
886  }
887  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
888  env =
890  pick->cid = ch->cid;
891  GNUNET_MQ_send (line->mq, env);
892 }
893 
894 
901 static void
903  const struct CadetPhoneSuspendMessage *message)
904 {
905  struct Channel *ch = cls;
906  struct Line *line = ch->line;
907  struct GNUNET_MQ_Envelope *env;
908  struct ClientPhoneSuspendMessage *suspend;
909 
910  (void) message;
912  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
913  switch (ch->status)
914  {
915  case CS_CALLEE_INIT:
916  GNUNET_break_op (0);
917  break;
918 
919  case CS_CALLEE_RINGING:
920  GNUNET_break_op (0);
921  break;
922 
923  case CS_CALLEE_CONNECTED:
925  break;
926 
927  case CS_CALLEE_SHUTDOWN:
928  return;
929 
930  case CS_CALLER_CALLING:
931  GNUNET_break_op (0);
932  break;
933 
934  case CS_CALLER_CONNECTED:
936  break;
937 
938  case CS_CALLER_SHUTDOWN:
939  return;
940  }
941  env =
943  suspend->cid = ch->cid;
944  GNUNET_MQ_send (line->mq, env);
945 }
946 
947 
954 static void
956  const struct CadetPhoneResumeMessage *msg)
957 {
958  struct Channel *ch = cls;
959  struct Line *line;
960  struct GNUNET_MQ_Envelope *env;
961  struct ClientPhoneResumeMessage *resume;
962 
963  (void) msg;
964  line = ch->line;
966  if (GNUNET_YES != ch->suspended_remote)
967  {
968  GNUNET_log (
970  "RESUME message received for non-suspended channel, dropping channel.\n");
972  return;
973  }
974  switch (ch->status)
975  {
976  case CS_CALLEE_INIT:
977  GNUNET_break (0);
978  break;
979 
980  case CS_CALLEE_RINGING:
981  GNUNET_break (0);
982  break;
983 
984  case CS_CALLEE_CONNECTED:
986  break;
987 
988  case CS_CALLEE_SHUTDOWN:
989  return;
990 
991  case CS_CALLER_CALLING:
992  GNUNET_break (0);
993  break;
994 
995  case CS_CALLER_CONNECTED:
997  break;
998 
999  case CS_CALLER_SHUTDOWN:
1000  return;
1001  }
1002  env =
1004  resume->cid = ch->cid;
1005  GNUNET_MQ_send (line->mq, env);
1006 }
1007 
1008 
1016 static int
1018 {
1019  (void) cls;
1020  (void) msg;
1021  return GNUNET_OK; /* any payload is fine */
1022 }
1023 
1024 
1031 static void
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  {
1043  GNUNET_log (
1045  "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
1046  (unsigned int) msize,
1047  ch->cid);
1048  return;
1049  }
1051  "Forwarding %u bytes of AUDIO data to client CID %u\n",
1052  (unsigned int) msize,
1053  ch->cid);
1054  env =
1056  cam->cid = ch->cid;
1057  GNUNET_memcpy (&cam[1], &msg[1], msize);
1058  GNUNET_MQ_send (ch->line->mq, env);
1059 }
1060 
1061 
1069 static void
1070 inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
1071 {
1072  struct Channel *ch = cls;
1073 
1074  GNUNET_assert (channel == ch->channel);
1075  ch->channel = NULL;
1077  "Channel destroyed by CADET in state %d\n",
1078  ch->status);
1079  clean_up_channel (ch);
1080 }
1081 
1082 
1089 static void
1091 {
1092  struct Line *line = cls;
1093  struct Channel *ch = GNUNET_new (struct Channel);
1094  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1095  { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1097  struct CadetPhoneHangupMessage,
1098  ch),
1099  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1101  struct CadetPhonePickupMessage,
1102  ch),
1103  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1105  struct CadetPhoneSuspendMessage,
1106  ch),
1107  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1109  struct CadetPhoneResumeMessage,
1110  ch),
1111  GNUNET_MQ_hd_var_size (cadet_audio_message,
1113  struct CadetAudioMessage,
1114  ch),
1115  GNUNET_MQ_handler_end () };
1116  struct GNUNET_MQ_Envelope *e;
1117  struct CadetPhoneRingMessage *ring;
1118  struct CadetPhoneRingInfoPS rs;
1119 
1120  line->line_port = msg->line_port;
1122  rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
1123  rs.line_port = line->line_port;
1124  rs.target_peer = msg->target;
1125  rs.expiration_time =
1127  ch->line = line;
1129  ch->status = CS_CALLER_CALLING;
1130  ch->channel = GNUNET_CADET_channel_create (cadet,
1131  ch,
1132  &msg->target,
1133  &msg->line_port,
1134  NULL,
1135  &inbound_end,
1136  cadet_handlers);
1137  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1140  ring->expiration_time = rs.expiration_time;
1142  &rs.purpose,
1143  &ring->signature));
1144  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1145  GNUNET_MQ_send (ch->mq, e);
1147 }
1148 
1149 
1159 static void *
1160 inbound_channel (void *cls,
1161  struct GNUNET_CADET_Channel *channel,
1162  const struct GNUNET_PeerIdentity *initiator)
1163 {
1164  struct Line *line = cls;
1165  struct Channel *ch;
1166 
1167  (void) initiator;
1169  "Received incoming cadet channel on line %p\n",
1170  line);
1171  ch = GNUNET_new (struct Channel);
1172  ch->status = CS_CALLEE_INIT;
1173  ch->line = line;
1174  ch->channel = channel;
1175  ch->mq = GNUNET_CADET_get_mq (ch->channel);
1176  ch->cid = line->cid_gen++;
1178  return ch;
1179 }
1180 
1181 
1190 static void *
1192  struct GNUNET_SERVICE_Client *client,
1193  struct GNUNET_MQ_Handle *mq)
1194 {
1195  struct Line *line;
1196 
1197  (void) cls;
1198  line = GNUNET_new (struct Line);
1199  line->client = client;
1200  line->mq = mq;
1201  return line;
1202 }
1203 
1204 
1212 static void
1214  struct GNUNET_SERVICE_Client *client,
1215  void *app_ctx)
1216 {
1217  struct Line *line = app_ctx;
1218  struct Channel *chn;
1219 
1220  (void) cls;
1221  (void) client;
1222  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
1223  if (NULL != line->port)
1224  {
1225  GNUNET_CADET_close_port (line->port);
1226  line->port = NULL;
1227  }
1228  for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
1229  {
1230  chn = ch->next;
1231  ch->line = NULL;
1233  }
1234  GNUNET_free (line);
1235 }
1236 
1237 
1244 static void
1246  const struct ClientPhoneRegisterMessage *msg)
1247 {
1248  struct Line *line = cls;
1249  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1250  { GNUNET_MQ_hd_fixed_size (cadet_ring_message,
1252  struct CadetPhoneRingMessage,
1253  NULL),
1254  GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
1256  struct CadetPhoneHangupMessage,
1257  NULL),
1258  GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
1260  struct CadetPhonePickupMessage,
1261  NULL),
1262  GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
1264  struct CadetPhoneSuspendMessage,
1265  NULL),
1266  GNUNET_MQ_hd_fixed_size (cadet_resume_message,
1268  struct CadetPhoneResumeMessage,
1269  NULL),
1270  GNUNET_MQ_hd_var_size (cadet_audio_message,
1272  struct CadetAudioMessage,
1273  NULL),
1274  GNUNET_MQ_handler_end () };
1275 
1276  line->line_port = msg->line_port;
1277  line->port = GNUNET_CADET_open_port (cadet,
1278  &msg->line_port,
1279  &inbound_channel,
1280  line,
1281  NULL,
1282  &inbound_end,
1283  cadet_handlers);
1284  if (NULL == line->port)
1285  {
1287  _ ("Could not open line, port %s already in use!\n"),
1288  GNUNET_h2s (&msg->line_port));
1290  return;
1291  }
1293 }
1294 
1295 
1301 static void
1303 {
1304  (void) cls;
1305  if (NULL != cadet)
1306  {
1307  GNUNET_CADET_disconnect (cadet);
1308  cadet = NULL;
1309  }
1310 }
1311 
1312 
1320 static void
1321 run (void *cls,
1322  const struct GNUNET_CONFIGURATION_Handle *c,
1324 {
1325  (void) cls;
1326  (void) service;
1327  cfg = c;
1330  cadet = GNUNET_CADET_connect (cfg);
1331  if (NULL == cadet)
1332  {
1333  GNUNET_break (0);
1335  return;
1336  }
1338 }
1339 
1340 
1345  "conversation",
1347  &run,
1350  NULL,
1351  GNUNET_MQ_hd_fixed_size (client_register_message,
1354  NULL),
1355  GNUNET_MQ_hd_fixed_size (client_pickup_message,
1357  struct ClientPhonePickupMessage,
1358  NULL),
1359  GNUNET_MQ_hd_fixed_size (client_suspend_message,
1362  NULL),
1363  GNUNET_MQ_hd_fixed_size (client_resume_message,
1365  struct ClientPhoneResumeMessage,
1366  NULL),
1367  GNUNET_MQ_hd_fixed_size (client_hangup_message,
1369  struct ClientPhoneHangupMessage,
1370  NULL),
1371  GNUNET_MQ_hd_fixed_size (client_call_message,
1373  struct ClientCallMessage,
1374  NULL),
1375  GNUNET_MQ_hd_var_size (client_audio_message,
1377  struct ClientAudioMessage,
1378  NULL),
1380 
1381 
1382 /* 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:144
Client -> Service message to call a phone.
Definition: conversation.h:208
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:841
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
Cadet message to make a phone ring.
Definition: conversation.h:289
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.
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:1046
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:1300
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: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:260
struct GNUNET_PeerIdentity target_peer
Which peer is the call for?
Definition: conversation.h:276
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO.
Definition: conversation.h:374
uint32_t cid
CID, internal caller ID to identify which active call we are talking about.
Definition: conversation.h:181
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:223
#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:70
#define GNUNET_NO
Definition: gnunet_common.h:78
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:75
#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:151
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
struct GNUNET_CRYPTO_EcdsaPrivateKey caller_id
Identity of the caller.
Definition: conversation.h:233
#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:314
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:976
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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: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.
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:929
#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:1010
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:170
#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:252
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:281
#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:2324
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:239
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:345
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:266
Service <-> Client message for phone was resumed.
Definition: conversation.h:133
Service -> Client: other peer has picked up the phone, we are now talking.
Definition: conversation.h:241
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:228
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:954
#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:162
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:1068
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:357
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:188
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:145
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:874
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO.
Definition: conversation.h:193
#define GNUNET_YES
Definition: gnunet_common.h:77
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:321
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:115
Cadet message for picking up.
Definition: conversation.h:333
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:916
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:903
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
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:126
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition: conversation.h:309
Cadet message to transmit the audio.
Definition: conversation.h:369
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EcdsaPublicKey caller_id
Who is calling us? (also who is signing).
Definition: conversation.h:304
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:1119
struct GNUNET_HashCode line_port
Which port did the call go to?
Definition: conversation.h:271
uint32_t cid
CID, internal caller ID to identify which active call we are sending data to.
Definition: conversation.h:199