GNUnet  0.17.6
gnunet-service-messenger_room.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020--2022 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 
30 
34 
36 
40 #include "messenger_api_util.h"
41 
42 static void
43 idle_request_room_messages (void *cls);
44 
47  const struct GNUNET_HashCode *key)
48 {
49  GNUNET_assert((handle) && (key));
50 
52 
53  room->service = handle->service;
54  room->host = handle;
55  room->port = NULL;
56 
57  GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode));
58 
60 
64 
65  init_list_tunnels (&(room->basement));
66  init_message_state(&(room->state));
67 
68  room->peer_message = NULL;
69 
70  init_list_messages (&(room->handling));
71  room->idle = NULL;
72 
73  if (room->service->dir)
74  load_srv_room (room);
75 
77 
78  return room;
79 }
80 
81 static int
83  const struct GNUNET_PeerIdentity *key,
84  void *value)
85 {
86  struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
87  destroy_tunnel (tunnel);
88  return GNUNET_YES;
89 }
90 
91 static void
93 
94 void
96  int deletion)
97 {
99 
100  if (room->idle)
101  {
103  room->idle = NULL;
104  }
105 
106  if (room->port)
108 
111 
112  if (!(room->service->dir))
113  goto skip_saving;
114 
115  if (GNUNET_YES == deletion)
117  else
119 
120 skip_saving:
124 
128 
129  if (room->peer_message)
131 
132  GNUNET_free(room);
133 }
134 
137 {
139 
140  return &(room->member_store);
141 }
142 
145 {
146  GNUNET_assert(room);
147 
148  return &(room->message_store);
149 }
150 
153 {
155 
156  return &(room->operation_store);
157 }
158 
159 static int
162  struct GNUNET_MESSENGER_SrvTunnel *tunnel)
163 {
164  if ((!handle) || (!is_tunnel_connected (tunnel)))
165  return GNUNET_NO;
166 
168 }
169 
170 static void*
172  struct GNUNET_CADET_Channel *channel,
173  const struct GNUNET_PeerIdentity *source)
174 {
175  struct GNUNET_MESSENGER_SrvRoom *room = cls;
176 
178 
179  if ((tunnel) &&
182  {
183  destroy_tunnel (tunnel);
184  tunnel = NULL;
185  }
186 
187  if (!tunnel)
188  {
190  return NULL;
191  }
192 
193  bind_tunnel(tunnel, channel);
194 
195  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "New tunnel in room (%s) established to peer: %s\n",
197 
198  if (GNUNET_YES == send_room_info (room, room->host, tunnel))
199  return tunnel;
200 
201  disconnect_tunnel (tunnel);
202 
204  destroy_tunnel (tunnel);
205 
206  return NULL;
207 }
208 
209 static int
212  struct GNUNET_MESSENGER_Member *member)
213 {
214  GNUNET_assert((room) && (handle) && (member));
215 
216  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s (get_srv_room_key (room)),
217  GNUNET_sh2s (get_member_id(member)));
218 
219  const struct GNUNET_ShortHashCode *member_id = get_member_id(member);
220 
222  return GNUNET_NO;
223 
225 
226  if (!message)
227  {
228  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be created!\n");
229 
230  return GNUNET_NO;
231  }
232 
233  GNUNET_memcpy(&(message->header.sender_id), member_id, sizeof(*member_id));
234  return send_srv_room_message (room, handle, message);
235 }
236 
238 {
242 };
243 
244 static void
246  struct GNUNET_MESSENGER_MemberSession *session,
248  int check_permission)
249 {
250  if (session->prev)
252 
253  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(notify->room);
254  struct GNUNET_MESSENGER_ListMessage *element;
255 
256  for (element = session->messages.head; element; element = element->next)
257  {
259  continue;
260 
261  if ((GNUNET_YES == check_permission) &&
262  (GNUNET_YES != check_member_session_history(notify->session, &(element->hash), GNUNET_NO)))
263  continue;
264 
265  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), NULL,
267  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notification of session message could be duplicated!\n");
268 
269  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, &(element->hash));
270 
271  if (message)
272  notify_srv_handle_message (notify->handle, notify->room, session, message, &(element->hash));
273  }
274 }
275 
276 static int
278  const struct GNUNET_IDENTITY_PublicKey *public_key,
279  struct GNUNET_MESSENGER_MemberSession *session)
280 {
282 
283  if ((notify->session == session) || (GNUNET_YES == is_member_session_completed(session)))
284  return GNUNET_YES;
285 
287 
289 
291  return GNUNET_YES;
292 }
293 
294 static int
297 {
298  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (handle, get_srv_room_key(room));
299 
301  struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, member_id);
302 
303  if (GNUNET_NO == join_room (room, handle, member))
304  return GNUNET_NO;
305 
306  const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle);
307  struct GNUNET_MESSENGER_MemberSession *session = get_member_session (member, &(ego->pub));
308 
309  if (!session)
310  {
311  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "A valid session is required to join a room!\n");
312  return GNUNET_NO;
313  }
314 
316 
317  notify.room = room;
318  notify.handle = handle;
319  notify.session = session;
320 
322 
323  return GNUNET_YES;
324 }
325 
326 extern int
327 check_tunnel_message (void *cls,
328  const struct GNUNET_MessageHeader *header);
329 
330 extern void
331 handle_tunnel_message (void *cls,
332  const struct GNUNET_MessageHeader *header);
333 
334 extern void
335 callback_tunnel_disconnect (void *cls,
336  const struct GNUNET_CADET_Channel *channel);
337 
338 int
341 {
342  GNUNET_assert((room) && (handle));
343 
344  if (room->port)
345  return join_room_locally (room, handle);
346 
348  const struct GNUNET_HashCode *key = get_srv_room_key (room);
349 
351  struct GNUNET_MessageHeader, NULL),
353 
354  struct GNUNET_HashCode port;
357  handlers);
358 
359  if (room->port)
360  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Port of room (%s) was opened!\n",
362  else
363  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Port of room (%s) could not be opened!\n",
365 
366  const struct GNUNET_ShortHashCode *member_id = get_srv_handle_member_id (handle, get_srv_room_key(room));
367 
369  struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, member_id);
370 
371  if ((GNUNET_NO == join_room (room, handle, member)) && (room->port))
372  {
373  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, therefore it keeps closed!\n");
374 
376  room->port = NULL;
377 
378  return GNUNET_NO;
379  }
380 
381  struct GNUNET_MESSENGER_Message *peer_msg = create_message_peer (room->service);
382  GNUNET_memcpy(&(peer_msg->header.sender_id), member_id, sizeof(*member_id));
383  return (room->port ? send_srv_room_message (room, handle, peer_msg) : GNUNET_NO);
384 }
385 
386 int
389  const struct GNUNET_PeerIdentity *door)
390 {
391  GNUNET_assert((room) && (handle) && (door));
392 
393  struct GNUNET_PeerIdentity peer;
394 
395  if ((GNUNET_OK == get_service_peer_identity (room->service, &peer)) &&
396  (0 == GNUNET_memcmp(&peer, door)))
397  return join_room_locally (room, handle);
398 
400 
401  if (!tunnel)
402  {
403  tunnel = create_tunnel (room, door);
404 
407  {
408  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that door!\n");
409  destroy_tunnel (tunnel);
410  return GNUNET_NO;
411  }
412  }
413 
414  if (GNUNET_SYSERR == connect_tunnel (tunnel))
415  {
416  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connection failure during entrance!\n");
418  destroy_tunnel (tunnel);
419  return GNUNET_NO;
420  }
421 
422  return join_room_locally (room, handle);
423 }
424 
425 struct GNUNET_MQ_Envelope*
427  const struct GNUNET_MESSENGER_SrvHandle *handle,
428  struct GNUNET_MESSENGER_Message *message,
429  struct GNUNET_HashCode *hash,
430  int mode)
431 {
432  GNUNET_assert((room) && (handle) && (message) && (hash));
433 
435 
437 
438  GNUNET_assert(id);
439 
440  GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode));
441  get_message_state_chain_hash (&(room->state), &(message->header.previous));
442 
443  return pack_message (message, hash, get_srv_handle_ego (handle), mode);
444 }
445 
447 {
453  int packed;
454 };
455 
456 static int
458  const struct GNUNET_PeerIdentity *key,
459  void *value)
460 {
461  struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
462 
463  if ((!is_tunnel_connected (tunnel)) ||
465  return GNUNET_YES;
466 
467  struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls;
468 
469  if (tunnel == closure->exclude)
470  return GNUNET_YES;
471 
472  struct GNUNET_MQ_Envelope *env = NULL;
473 
474  if (closure->packed == GNUNET_NO)
475  {
476  env = pack_srv_room_message (closure->room, closure->handle, closure->message, closure->hash,
478 
479  if (env)
480  closure->packed = GNUNET_YES;
481  }
482  else
484 
485  if (env)
486  send_tunnel_envelope (tunnel, env, closure->hash);
487 
488  return GNUNET_YES;
489 }
490 
491 int
493  struct GNUNET_MESSENGER_Message *message,
494  const struct GNUNET_HashCode *hash);
495 
496 void
499  const struct GNUNET_MESSENGER_Message *message,
500  const struct GNUNET_HashCode *hash);
501 
502 int
505  struct GNUNET_MESSENGER_Message *message)
506 {
507  GNUNET_assert((room) && (handle));
508 
509  if (!message)
510  return GNUNET_NO;
511 
512  if (GNUNET_YES == is_message_session_bound(message))
514 
515  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Sending message from handle with member id: %s\n",
517 
518  struct GNUNET_HashCode hash;
519  struct GNUNET_MESSENGER_ClosureSendRoom closure;
520 
521  closure.room = room;
522  closure.handle = handle;
523  closure.exclude = NULL;
524  closure.message = message;
525  closure.hash = &hash;
526  closure.packed = GNUNET_NO;
527 
529 
530  if (GNUNET_NO == closure.packed)
532 
533  const int new_message = update_room_message (room, message, &hash);
534 
535  if (GNUNET_YES != new_message)
536  return GNUNET_SYSERR;
537 
538  switch (message->header.kind)
539  {
542  break;
545  break;
548  break;
551  break;
552  default:
553  break;
554  }
555 
557  return GNUNET_YES;
558 }
559 
560 void
562  struct GNUNET_MESSENGER_SrvTunnel *tunnel,
564  const struct GNUNET_HashCode *hash)
565 {
566  GNUNET_assert((room) && (tunnel));
567 
568  if (!message)
569  return;
570 
571  struct GNUNET_MESSENGER_ClosureSendRoom closure;
572  struct GNUNET_HashCode message_hash;
573 
574  GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode));
575 
576  closure.room = room;
577  closure.handle = NULL;
578  closure.exclude = tunnel;
579  closure.message = message;
580  closure.hash = &message_hash;
581  closure.packed = GNUNET_YES;
582 
584 }
585 
586 void
588  struct GNUNET_MESSENGER_SrvTunnel *tunnel)
589 {
590  if (!room->peer_message)
591  return;
592 
593  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
594 
595  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, room->peer_message);
596 
597  if (!message)
598  {
599  GNUNET_free(room->peer_message);
600  room->peer_message = NULL;
601  return;
602  }
603 
605  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
606 
607  if (!member)
608  goto resend_peer_message;
609 
610  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, room->peer_message);
611 
612  if (GNUNET_YES == is_member_session_closed(session))
613  goto resend_peer_message;
614 
615  if (tunnel)
616  forward_tunnel_message(tunnel, message, room->peer_message);
617 
618  return;
619 
620 resend_peer_message:
621  if (room->host)
622  send_srv_room_message (room, room->host, create_message_peer (room->service));
623 }
624 
625 void
628 {
629  GNUNET_assert(room);
630 
631  if (!handle)
632  return;
633 
634  const struct GNUNET_HashCode *hash;
635 
636 merge_next:
637  hash = get_message_state_merge_hash (&(room->state));
638 
639  if (!hash)
640  return;
641 
643  goto merge_next;
644 }
645 
646 void
648  const struct GNUNET_HashCode *hash)
649 {
651  {
652  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! (%s)\n", GNUNET_h2s(hash));
653  return;
654  }
655 }
656 
657 void
659  const struct GNUNET_HashCode *hash)
660 {
661  if (!room->host)
662  return;
663 
664  send_srv_room_message (room, room->host, create_message_merge (hash));
665 }
666 
667 int
669  struct GNUNET_MESSENGER_MemberSession *session,
670  const struct GNUNET_HashCode *hash,
671  const struct GNUNET_TIME_Relative delay)
672 {
673  GNUNET_assert((room) && (session) && (hash));
674 
676 
677  if (0 == GNUNET_memcmp(&forever, &delay))
678  {
679  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Deletion is delayed forever: operation is impossible!\n");
680  return GNUNET_SYSERR;
681  }
682 
683  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
684 
685  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
686 
687  if (!message)
688  return GNUNET_YES;
689 
690  if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_YES))
691  {
692  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unpermitted request for deletion by member (%s) of message (%s)!\n",
693  GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash));
694 
695  return GNUNET_NO;
696  }
697 
699 
700  if (GNUNET_OK != use_store_operation(operation_store, hash, GNUNET_MESSENGER_OP_DELETE, delay))
701  {
702  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Deletion has failed: operation denied!\n");
703  return GNUNET_SYSERR;
704  }
705 
706  return GNUNET_YES;
707 }
708 
709 struct GNUNET_CADET_Handle*
711 {
712  GNUNET_assert(room);
713 
714  return room->service->cadet;
715 }
716 
717 const struct GNUNET_HashCode*
719 {
720  GNUNET_assert(room);
721 
722  return &(room->key);
723 }
724 
725 const struct GNUNET_MESSENGER_SrvTunnel*
727  const struct GNUNET_PeerIdentity *peer)
728 {
729  GNUNET_assert((room) && (peer));
730 
732 }
733 
734 static int
736  const struct GNUNET_HashCode *hash,
737  const struct GNUNET_MESSENGER_MemberSession *session,
739  void* cls)
740 {
741  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
742 
744  message_store, hash, GNUNET_YES
745  );
746 
747  if (!link)
748  goto forward;
749 
750  int result = request_room_message_step(room, &(link->first), session, callback, cls);
751 
752  if ((GNUNET_YES == link->multiple) &&
753  (GNUNET_YES == request_room_message_step(room, &(link->second), session, callback, cls)))
754  return GNUNET_YES;
755  else
756  return result;
757 
758 forward:
759  if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO))
760  return GNUNET_YES;
761 
762  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
763 
764  if (!message)
765  return GNUNET_NO;
766 
767  if (callback)
768  callback (cls, room, message, hash);
769 
770  return GNUNET_YES;
771 }
772 
773 int
775  const struct GNUNET_HashCode *hash,
776  const struct GNUNET_MESSENGER_MemberSession *session,
778  void* cls)
779 {
780  GNUNET_assert((room) && (hash));
781 
782  int result = request_room_message_step (room, hash, session, callback, cls);
783 
784  if ((GNUNET_NO == result) && (callback))
785  callback (cls, room, NULL, hash);
786 
787  return result;
788 }
789 
790 void
792  void *cls)
793 {
794  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
795 
796  if (!room->host)
797  return;
798 
801 
804  return;
805 
808 }
809 
810 int
812  void *cls,
813  struct GNUNET_MESSENGER_Message *message,
814  struct GNUNET_HashCode *hash)
815 {
816  if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind)
817  {
818  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Kind is unknown! (%d)\n", message->header.kind);
819  return GNUNET_SYSERR;
820  }
821 
822  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
823 
824  const struct GNUNET_MESSENGER_Message *previous = get_store_message(message_store, &(message->header.previous));
825 
826  if (!previous)
827  goto skip_time_comparison;
828 
829  struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh(message->header.timestamp);
831 
832  if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(timestamp, last).rel_value_us)
833  {
834  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Timestamp does not check out!\n");
835  return GNUNET_SYSERR;
836  }
837 
838 skip_time_comparison:
839  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n",
841 
842  return GNUNET_OK;
843 }
844 
845 static void
847 {
848  struct GNUNET_MESSENGER_SrvRoom *room = cls;
849 
850  room->idle = NULL;
851 
853  const struct GNUNET_HashCode *hash = get_message_state_merge_hash(&(room->state));
854 
855  if ((hash) &&
856  (GNUNET_MESSENGER_OP_UNKNOWN == get_store_operation_type(operation_store, hash)))
858  operation_store,
859  hash,
862  );
863 
868  cls
869  );
870 }
871 
872 void
874  const struct GNUNET_IDENTITY_PublicKey *public_key,
875  const struct GNUNET_ShortHashCode *member_id,
876  struct GNUNET_TIME_Absolute timestamp)
877 {
878  GNUNET_assert ((room) && (public_key) && (member_id));
879 
881  struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, member_id);
882 
883  if ((!member) || (1 >= GNUNET_CONTAINER_multihashmap_size(member->sessions)))
884  return;
885 
886  struct GNUNET_MESSENGER_ListHandles *handles = &(room->service->handles);
887  struct GNUNET_MESSENGER_ListHandle* element;
888 
889  for (element = handles->head; element; element = element->next)
890  {
891  if (0 != GNUNET_memcmp(member_id, get_srv_handle_member_id(element->handle, get_srv_room_key(room))))
892  continue;
893 
894  if (0 == GNUNET_memcmp(public_key, &(get_srv_handle_ego(element->handle)->pub)))
895  continue;
896 
898 
899  if (!session)
900  continue;
901 
903 
904  if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(start, timestamp).rel_value_us)
905  continue;
906 
907  struct GNUNET_ShortHashCode random_id;
908  generate_free_member_id (&random_id, member_store->members);
909 
910  send_srv_room_message(room, element->handle, create_message_id(&random_id));
911  }
912 }
913 
914 void
916 {
917  GNUNET_assert(room);
918 
919  struct GNUNET_PeerIdentity peer;
920  size_t src;
921 
922  if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) ||
923  (!find_list_tunnels (&(room->basement), &peer, &src)))
924  return;
925 
926  size_t count = count_of_tunnels (&(room->basement));
927 
928  struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head;
929  struct GNUNET_MESSENGER_SrvTunnel *tunnel;
930 
931  size_t dst = 0;
932 
933  while (element)
934  {
935  GNUNET_PEER_resolve (element->peer, &peer);
936 
938 
939  if (!tunnel)
940  {
941  element = remove_from_list_tunnels (&(room->basement), element);
942  continue;
943  }
944 
945  if (GNUNET_YES == required_connection_between (count, src, dst))
946  {
947  if (GNUNET_SYSERR == connect_tunnel (tunnel))
948  {
949  element = remove_from_list_tunnels (&(room->basement), element);
950  continue;
951  }
952  }
953  else
954  disconnect_tunnel (tunnel);
955 
956  element = element->next;
957  dst++;
958  }
959 }
960 
961 static void
963 {
964  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
966 
967  while (room->handling.head)
968  {
969  struct GNUNET_MESSENGER_ListMessage *element = room->handling.head;
970 
971  const struct GNUNET_MESSENGER_Message *message = get_store_message (message_store, &(element->hash));
972 
973  if (!message)
974  goto finish_handling;
975 
976  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
977 
978  if (!member)
979  goto finish_handling;
980 
981  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, &(element->hash));
982 
983  if (session)
984  handle_service_message (room->service, room, session, message, &(element->hash));
985 
986 finish_handling:
987  GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element);
988  GNUNET_free(element);
989  }
990 }
991 
992 int
994  struct GNUNET_MESSENGER_Message *message,
995  const struct GNUNET_HashCode *hash)
996 {
997  GNUNET_assert((room) && (message) && (hash));
998 
1000 
1001  const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)?
1003  );
1004 
1005  if (GNUNET_YES == requested)
1006  cancel_store_operation(operation_store, hash);
1007 
1008  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(room);
1009 
1010  const struct GNUNET_MESSENGER_Message *old_message = get_store_message (message_store, hash);
1011 
1012  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", GNUNET_h2s (get_srv_room_key(room)));
1013 
1014  if ((old_message) || (GNUNET_OK != put_store_message (message_store, hash, message)))
1015  {
1016  if (old_message != message)
1017  destroy_message(message);
1018 
1019  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Duplicate message got dropped!\n");
1020  return GNUNET_NO;
1021  }
1022 
1023  update_message_state(&(room->state), requested, message, hash);
1024 
1025  if ((GNUNET_YES == requested) ||
1026  (GNUNET_MESSENGER_KIND_INFO == message->header.kind) ||
1028  return GNUNET_YES;
1029 
1030  if ((GNUNET_MESSENGER_KIND_MERGE == message->header.kind) &&
1031  (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->body.merge.previous))))
1032  cancel_store_operation(operation_store, &(message->body.merge.previous));
1033 
1034  if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->header.previous)))
1035  cancel_store_operation(operation_store, &(message->header.previous));
1036 
1037  return GNUNET_YES;
1038 }
1039 
1041 {
1044 
1046 };
1047 
1049 {
1051  const struct GNUNET_HashCode *hash;
1052 
1055 };
1056 
1057 static int
1059  const struct GNUNET_IDENTITY_PublicKey *public_key,
1061 {
1062  struct GNUNET_MESSENGER_MemberUpdate *update = cls;
1063 
1064  update_member_session_history(session, update->message, update->hash);
1065 
1066  if (GNUNET_YES == is_member_session_completed(session))
1067  {
1070  );
1071 
1072  element->session = session;
1073 
1074  GNUNET_CONTAINER_DLL_insert_tail(update->head, update->tail, element);
1075  }
1076 
1077  return GNUNET_YES;
1078 }
1079 
1080 static void
1083 
1084 void
1087  const struct GNUNET_MESSENGER_Message *message,
1088  const struct GNUNET_HashCode *hash)
1089 {
1091  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
1092 
1093  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Callback for message (%s)\n", GNUNET_h2s (hash));
1094 
1095  if (!member)
1096  {
1097  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Member is missing!\n");
1098  return;
1099  }
1100 
1101  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash);
1102 
1103  if (!session)
1104  {
1105  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Session is missing!\n");
1106  return;
1107  }
1108 
1109  struct GNUNET_MESSENGER_MemberUpdate update;
1110  update.message = message;
1111  update.hash = hash;
1112 
1113  update.head = NULL;
1114  update.tail = NULL;
1115 
1116  iterate_store_members(member_store, iterate_update_member_sessions, &update);
1117 
1118  while (update.head)
1119  {
1120  struct GNUNET_MESSENGER_MemberSessionCompletion *element = update.head;
1121 
1122  remove_room_member_session (room, element->session);
1123 
1124  GNUNET_CONTAINER_DLL_remove(update.head, update.tail, element);
1125  GNUNET_free (element);
1126  }
1127 
1128  const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES;
1129 
1130  add_to_list_messages (&(room->handling), hash);
1131 
1132  switch (message->header.kind)
1133  {
1135  handle_message_join (room, session, message, hash);
1136  break;
1138  handle_message_leave (room, session, message, hash);
1139  break;
1141  handle_message_name (room, session, message, hash);
1142  break;
1144  handle_message_key (room, session, message, hash);
1145  break;
1147  handle_message_peer (room, session, message, hash);
1148  break;
1150  handle_message_id (room, session, message, hash);
1151  break;
1153  handle_message_miss (room, session, message, hash);
1154  break;
1156  handle_message_delete (room, session, message, hash);
1157  break;
1158  default:
1159  break;
1160  }
1161 
1162  if (GNUNET_YES == start_handle)
1163  handle_room_messages (room);
1164 }
1165 
1166 static void
1168  char **dir)
1169 {
1170  GNUNET_assert((room) && (dir));
1171 
1172  GNUNET_asprintf (dir, "%s%s%c%s%c", room->service->dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (get_srv_room_key(room)), DIR_SEPARATOR);
1173 }
1174 
1175 void
1177 {
1178  GNUNET_assert(room);
1179 
1180  char *room_dir;
1181  get_room_data_subdir (room, &room_dir);
1182 
1184  {
1185  load_member_store (get_srv_room_member_store(room), room_dir);
1188 
1189  char *basement_file;
1190  GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
1191 
1192  load_list_tunnels(&(room->basement), basement_file);
1193  GNUNET_free(basement_file);
1194 
1195  load_message_state(&(room->state), room_dir);
1196  }
1197 
1198  GNUNET_free(room_dir);
1199 }
1200 
1201 void
1203 {
1204  GNUNET_assert(room);
1205 
1206  char *room_dir;
1207  get_room_data_subdir (room, &room_dir);
1208 
1209  if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) ||
1210  (GNUNET_OK == GNUNET_DISK_directory_create (room_dir)))
1211  {
1215 
1216  char *basement_file;
1217  GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
1218 
1219  save_list_tunnels(&(room->basement), basement_file);
1220  GNUNET_free(basement_file);
1221 
1222  save_message_state(&(room->state), room_dir);
1223  }
1224 
1225  GNUNET_free(room_dir);
1226 }
1227 
1228 void
1230 {
1231  GNUNET_assert(room);
1232 
1233  char *room_dir;
1234  get_room_data_subdir (room, &room_dir);
1235 
1237  GNUNET_DISK_directory_remove(room_dir);
1238 
1239  GNUNET_free(room_dir);
1240 }
1241 
1242 static void
1245 {
1246  GNUNET_assert ((room) && (session));
1247 
1249 
1250  const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session);
1251 
1252  struct GNUNET_HashCode hash;
1253  GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
1254 
1255  char *room_dir;
1256  get_room_data_subdir (room, &room_dir);
1257 
1258  char* session_dir;
1259  GNUNET_asprintf (
1260  &session_dir, "%s%s%c%s%c%s%c%s%c", room_dir,
1261  "members", DIR_SEPARATOR,
1263  "sessions", DIR_SEPARATOR,
1264  GNUNET_h2s(&hash), DIR_SEPARATOR
1265  );
1266 
1267  GNUNET_free (room_dir);
1268 
1269  GNUNET_DISK_directory_remove(session_dir);
1270  GNUNET_free (session_dir);
1271 
1272  destroy_member_session(session);
1273 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static int forward
Search direction: forward.
Definition: gnunet-abd.c:162
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we've connected to it).
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static char * value
Value of the record to add/remove.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static int result
Global testing status.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
GNUnet MESSENGER service.
int required_connection_between(size_t count, size_t src, size_t dst)
Returns GNUNET_YES or GNUNET_NO to determine if the peers of index src and index dst should be connec...
size_t count_of_tunnels(const struct GNUNET_MESSENGER_ListTunnels *tunnels)
Returns the count of peers in a list (typically from the basement of a room).
int change_srv_handle_member_id(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, const struct GNUNET_ShortHashCode *unique_id)
Changes the member id of a given handle in a specific room to match a unique_id and returns GNUNET_OK...
void notify_srv_handle_message(struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Notifies the handle that a new message was received or sent.
const struct GNUNET_ShortHashCode * get_srv_handle_member_id(const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Returns the member id of a given handle in a specific room.
const struct GNUNET_MESSENGER_Ego * get_srv_handle_ego(const struct GNUNET_MESSENGER_SrvHandle *handle)
Returns the EGO used by a given handle.
void init_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Initializes list of message hashes as empty list.
void add_to_list_messages(struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash)
Adds a specific hash from a message to the end of the list.
void remove_member_session(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_MemberSession *session)
Removes a given member session from its member.
struct GNUNET_MESSENGER_MemberSession * get_member_session(const struct GNUNET_MESSENGER_Member *member, const struct GNUNET_IDENTITY_PublicKey *public_key)
Returns the member session of a member identified by a given public key.
const struct GNUNET_ShortHashCode * get_member_id(const struct GNUNET_MESSENGER_Member *member)
Returns the current id of a given member.
struct GNUNET_MESSENGER_MemberSession * get_member_session_of(struct GNUNET_MESSENGER_Member *member, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Returns the member session of a member using a public key which can verify the signature of a given m...
GNUnet MESSENGER service.
const struct GNUNET_ShortHashCode * get_member_session_id(const struct GNUNET_MESSENGER_MemberSession *session)
Returns the member id of a given member session.
void destroy_member_session(struct GNUNET_MESSENGER_MemberSession *session)
Destroys a member session and frees its memory fully.
int check_member_session_history(const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_HashCode *hash, int ownership)
Checks the history of a session for a specific message which is identified by its hash and if the own...
struct GNUNET_TIME_Absolute get_member_session_start(const struct GNUNET_MESSENGER_MemberSession *session)
Returns the timestamp of the member session's start.
void update_member_session_history(struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Adds a given message to the history of a session using the messages hash.
int is_member_session_completed(const struct GNUNET_MESSENGER_MemberSession *session)
Returns if the given member session has been completed.
const struct GNUNET_IDENTITY_PublicKey * get_member_session_public_key(const struct GNUNET_MESSENGER_MemberSession *session)
Returns the public key from an EGO of a given member session.
int is_member_session_closed(const struct GNUNET_MESSENGER_MemberSession *session)
Returns if the given member session has been closed.
struct GNUNET_MESSENGER_Member * get_store_member_of(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_MESSENGER_Message *message)
Returns the member of a store using a sender id of a given message.
int iterate_store_members(struct GNUNET_MESSENGER_MemberStore *store, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to the members of the given member store and ...
void save_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Saves members from a member store into a directory.
void load_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Loads members from a directory into a member store.
struct GNUNET_MESSENGER_Member * get_store_member(const struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Returns the member in a store identified by a given id.
void init_member_store(struct GNUNET_MESSENGER_MemberStore *store, struct GNUNET_MESSENGER_SrvRoom *room)
Initializes a member store as fully empty connected to a room.
struct GNUNET_MESSENGER_Member * add_store_member(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Adds a member to a store under a specific id and returns it on success.
void clear_member_store(struct GNUNET_MESSENGER_MemberStore *store)
Clears a member store, wipes its content and deallocates its memory.
void handle_message_key(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent key message to change the key of a member and rearrange the contacts accor...
void handle_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent peer message to make changes of the basement in the room.
void handle_message_join(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent join message to make changes of current member information.
void handle_message_miss(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent miss message to drop a peer from the basement in the room.
void handle_message_id(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent id message to change a members id.
void handle_message_name(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent name message to rename a current member.
void handle_message_leave(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent leave message to make changes of current member information.
void handle_message_delete(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received or sent delete message to delete a specific message from the store.
struct GNUNET_MESSENGER_Message * create_message_merge(const struct GNUNET_HashCode *previous)
Creates and allocates a new merge message containing the hash of a second previous message besides th...
struct GNUNET_MESSENGER_Message * create_message_info(const struct GNUNET_MESSENGER_Ego *ego)
Creates and allocates a new info message containing the hosts EGO public key and a newly generated un...
struct GNUNET_MESSENGER_Message * create_message_miss(const struct GNUNET_PeerIdentity *peer)
Creates and allocates a new miss message containing the missing peer identity.
struct GNUNET_MESSENGER_Message * create_message_peer(const struct GNUNET_MESSENGER_Service *service)
Creates and allocates a new peer message containing a services peer identity.
struct GNUNET_MESSENGER_Message * create_message_id(const struct GNUNET_ShortHashCode *unique_id)
Creates and allocates a new id message containing the unique member id to change to.
struct GNUNET_MESSENGER_Message * create_message_join(const struct GNUNET_MESSENGER_Ego *ego)
Creates and allocates a new join message containing the clients EGO public key.
void send_message_id(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent id message to update the handles member id in the room.
void send_message_request(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent request message to trigger the request operation for this service.
void send_message_join(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent join message to ensure growth of the decentralized room structure.
void send_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent peer message to update the rooms peer message of this service.
void save_message_state(const struct GNUNET_MESSENGER_MessageState *state, const char *path)
void update_message_state(struct GNUNET_MESSENGER_MessageState *state, int requested, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
void clear_message_state(struct GNUNET_MESSENGER_MessageState *state)
void get_message_state_chain_hash(const struct GNUNET_MESSENGER_MessageState *state, struct GNUNET_HashCode *hash)
void init_message_state(struct GNUNET_MESSENGER_MessageState *state)
void load_message_state(struct GNUNET_MESSENGER_MessageState *state, const char *path)
const struct GNUNET_HashCode * get_message_state_merge_hash(const struct GNUNET_MESSENGER_MessageState *state)
void save_message_store(struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
Saves messages from a message store into a directory.
const struct GNUNET_MESSENGER_Message * get_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the message from a message store matching a given hash.
void clear_message_store(struct GNUNET_MESSENGER_MessageStore *store)
Clears a message store, wipes its content and deallocates its memory.
void init_message_store(struct GNUNET_MESSENGER_MessageStore *store)
Initializes a message store as fully empty.
int delete_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Deletes a message in the message store.
void load_message_store(struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
Loads messages from a directory into a message store.
int put_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, struct GNUNET_MESSENGER_Message *message)
Stores a message into the message store.
const struct GNUNET_MESSENGER_MessageLink * get_store_message_link(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, int deleted_only)
Returns the message link from a message store matching a given hash.
GNUnet MESSENGER service.
void cancel_store_operation(struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash)
Stops any active operation under a given hash in a specific operation store.
void save_operation_store(const struct GNUNET_MESSENGER_OperationStore *store, const char *directory)
Saves operations from an operation store into a directory.
void clear_operation_store(struct GNUNET_MESSENGER_OperationStore *store)
Clears an operation store, stops all operations and deallocates its memory.
void load_operation_store(struct GNUNET_MESSENGER_OperationStore *store, const char *directory)
Loads operations from a directory into an operation store.
enum GNUNET_MESSENGER_OperationType get_store_operation_type(const struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash)
Returns the type of the active operation under a given hash in a specific operation store.
void init_operation_store(struct GNUNET_MESSENGER_OperationStore *store, struct GNUNET_MESSENGER_SrvRoom *room)
Initializes an operation store as fully empty with a given room.
int use_store_operation(struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash, enum GNUNET_MESSENGER_OperationType type, struct GNUNET_TIME_Relative delay)
Tries to use an operation under a given hash in a specific operation store.
int send_srv_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Message *message)
Sends a message from a given handle into a room.
static void notify_about_members(struct GNUNET_MESSENGER_MemberNotify *notify, struct GNUNET_MESSENGER_MemberSession *session, struct GNUNET_CONTAINER_MultiHashMap *map, int check_permission)
static int join_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Member *member)
int open_srv_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
Tries to open a room for a given handle.
static void get_room_data_subdir(struct GNUNET_MESSENGER_SrvRoom *room, char **dir)
struct GNUNET_MESSENGER_OperationStore * get_srv_room_operation_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used operation store of a given room.
void save_srv_room(struct GNUNET_MESSENGER_SrvRoom *room)
Saves the configuration for a given room of a service which contains the last messages hash and the r...
void rebuild_srv_room_basement_structure(struct GNUNET_MESSENGER_SrvRoom *room)
Rebuilds the decentralized structure for a room by ensuring all required connections are made dependi...
static int iterate_notify_about_members(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
static void remove_room_member_session(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session)
const struct GNUNET_MESSENGER_SrvTunnel * get_srv_room_tunnel(const struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *peer)
Returns a tunnel inside of a room leading towards a given peer if such a tunnel exists,...
void handle_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
void solve_srv_room_member_collisions(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_IDENTITY_PublicKey *public_key, const struct GNUNET_ShortHashCode *member_id, struct GNUNET_TIME_Absolute timestamp)
Checks for potential collisions with member ids and solves them changing active handles ids if they u...
static int send_room_info(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
static void idle_request_room_messages(void *cls)
int enter_srv_room_at(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door)
Connects a tunnel to a hosting peer of a room through a so called door which is represented by a peer...
void merge_srv_room_last_messages(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
Reduces all current forks inside of the message history of a room to one remaining last message by me...
void check_srv_room_peer_status(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Checks the current state of opening a given room from this peer and re-publishes it if necessary to a...
void remove_srv_room(struct GNUNET_MESSENGER_SrvRoom *room)
Removes the configuration for a given room of a service.
struct GNUNET_MQ_Envelope * pack_srv_room_message(const struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, int mode)
Packs a message depending on the selected mode into a newly allocated envelope.
static int iterate_destroy_tunnels(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
void forward_srv_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Forwards a message with a given hash to a specific tunnel inside of a room.
int delete_srv_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_HashCode *hash, const struct GNUNET_TIME_Relative delay)
Deletes a message from the room with a given hash in a specific delay if the provided member by its s...
struct GNUNET_CADET_Handle * get_srv_room_cadet(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the CADET handle from a rooms service.
int callback_verify_room_message(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
static int join_room_locally(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
static void * callback_room_connect(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
static void handle_room_messages(struct GNUNET_MESSENGER_SrvRoom *room)
static int request_room_message_step(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_MemberSession *session, GNUNET_MESSENGER_MessageRequestCallback callback, void *cls)
struct GNUNET_MESSENGER_SrvRoom * create_srv_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Creates and allocates a new room for a handle with a given key.
void callback_room_handle_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
int check_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
static int iterate_update_member_sessions(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
void callback_tunnel_disconnect(void *cls, const struct GNUNET_CADET_Channel *channel)
int update_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
void destroy_srv_room(struct GNUNET_MESSENGER_SrvRoom *room, int deletion)
Destroys a room and frees its memory fully.
void callback_room_deletion(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
const struct GNUNET_HashCode * get_srv_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
struct GNUNET_MESSENGER_MemberStore * get_srv_room_member_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used member store of a given room.
struct GNUNET_MESSENGER_MessageStore * get_srv_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
void callback_room_disconnect(struct GNUNET_MESSENGER_SrvRoom *room, void *cls)
static int iterate_send_room_message(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
int request_srv_room_message(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_MemberSession *session, GNUNET_MESSENGER_MessageRequestCallback callback, void *cls)
Requests a message from a room identified by a given hash.
void callback_room_merge(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
void load_srv_room(struct GNUNET_MESSENGER_SrvRoom *room)
Loads the local configuration for a given room of a service which contains the last messages hash and...
GNUnet MESSENGER service.
#define GNUNET_MESSENGER_MERGE_DELAY
#define GNUNET_MESSENGER_IDLE_DELAY
void() GNUNET_MESSENGER_MessageRequestCallback(void *cls, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Method called whenever a message is found during a request in a room.
void handle_service_message(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Sends a received or sent message with a given hash to each handle of a service which is currently mem...
int get_service_peer_identity(const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer)
Tries to write the peer identity of the peer running a service on to the peer parameter.
GNUnet MESSENGER service.
int send_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
Sends a message by packing it automatically into an envelope and passing it through the tunnel.
void forward_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Forwards a given message with a known hash through a tunnel.
void send_tunnel_envelope(struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env, const struct GNUNET_HashCode *hash)
Sends an envelope containing a message with a given hash through a tunnel.
int connect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Tries to connect a tunnel by creating a new CADET channel and binding it.
int is_tunnel_connected(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the status of a currently bound channel of a tunnel.
struct GNUNET_MESSENGER_SrvTunnel * create_tunnel(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door)
Creates and allocates a tunnel of a room to a specific peer identity (called door).
void bind_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
Binds a CADET channel to a tunnel and replaces its channel the tunnel is currently bound to if necess...
uint32_t get_tunnel_messenger_version(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the current messenger version the peer connected via a given tunnel has reported to be using ...
void get_tunnel_peer_identity(const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer)
Writes the peer identity of the peer connected via tunnel to this peer into the peer parameter.
void disconnect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Disconnects and unbinds a channel from a tunnel.
GNUnet MESSENGER service.
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:802
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition: cadet_api.c:955
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1085
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:404
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL).
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_SCHEDULER_PRIORITY_IDLE
Run when otherwise idle.
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSENGER_VERSION
Version number of GNUnet Messenger API.
const char * GNUNET_MESSENGER_name_of_kind(enum GNUNET_MESSENGER_MessageKind kind)
Get the name of a message kind.
Definition: messenger_api.c:35
@ GNUNET_MESSENGER_KIND_INFO
The info kind.
@ GNUNET_MESSENGER_KIND_MISS
The miss kind.
@ GNUNET_MESSENGER_KIND_REQUEST
The request kind.
@ GNUNET_MESSENGER_KIND_NAME
The name kind.
@ GNUNET_MESSENGER_KIND_LEAVE
The leave kind.
@ GNUNET_MESSENGER_KIND_PEER
The peer kind.
@ GNUNET_MESSENGER_KIND_UNKNOWN
The unknown kind.
@ GNUNET_MESSENGER_KIND_KEY
The key kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
@ GNUNET_MESSENGER_KIND_DELETE
The delete kind.
@ GNUNET_MESSENGER_KIND_MERGE
The merge kind.
@ GNUNET_MESSENGER_KIND_ID
The id kind.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition: peer.c:225
#define GNUNET_MESSAGE_TYPE_CADET_CLI
Traffic (net-cat style) used by the Command Line Interface.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1184
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1208
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_zero_(void)
Return relative time of 0ms.
Definition: time.c:132
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_forever_(void)
Return "forever".
Definition: time.c:195
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute end)
Compute the time difference between the given start and end times.
Definition: time.c:420
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
void load_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, const char *path)
Loads the list of tunnels peer identities from a file under a given path.
void init_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels)
Initializes list of tunnels peer identities as empty list.
void save_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, const char *path)
Saves the list of tunnels peer identities to a file under a given path.
struct GNUNET_MESSENGER_ListTunnel * remove_from_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, struct GNUNET_MESSENGER_ListTunnel *element)
Removes a specific element from the list of tunnels peer identities and returns the next element in t...
struct GNUNET_MESSENGER_ListTunnel * find_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer, size_t *index)
Searches linearly through the list of tunnels peer identities for matching a specific peer identity a...
void clear_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels)
Clears the list of tunnels peer identities.
int contains_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer)
Tests linearly if the list of tunnels peer identities contains a specific peer identity and returns G...
struct GNUNET_MQ_Envelope * pack_message(struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego, int mode)
Encodes the message to pack it into a newly allocated envelope if mode is equal to GNUNET_MESSENGER_P...
int is_message_session_bound(const struct GNUNET_MESSENGER_Message *message)
Returns if the message should be bound to a member session.
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.
#define GNUNET_MESSENGER_PACK_MODE_UNKNOWN
#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE
void convert_messenger_key_to_port(const struct GNUNET_HashCode *key, struct GNUNET_HashCode *port)
Converts a Messenger service key of a room to the specific port which gets used for the CADET channel...
int generate_free_member_id(struct GNUNET_ShortHashCode *id, const struct GNUNET_CONTAINER_MultiShortmap *members)
Tries to generate an unused member id and store it into the id parameter.
void delayed_disconnect_channel(struct GNUNET_CADET_Channel *channel)
Starts an urgent task to close a CADET channel asynchronously.
messenger api: client implementation of GNUnet MESSENGER service
#define DIR_SEPARATOR
Definition: platform.h:164
Opaque handle to a channel.
Definition: cadet.h:117
Opaque handle to the service.
Definition: cadet_api.c:39
Internal representation of the hash map.
A 512-bit hashcode.
An identity key as per LSD0001.
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_MESSENGER_Message * message
struct GNUNET_MESSENGER_SrvTunnel * exclude
struct GNUNET_MESSENGER_SrvRoom * room
struct GNUNET_IDENTITY_PublicKey pub
struct GNUNET_MESSENGER_ListHandle * next
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_MESSENGER_ListHandle * head
struct GNUNET_MESSENGER_ListMessage * next
struct GNUNET_MESSENGER_ListMessage * head
struct GNUNET_MESSENGER_ListMessage * tail
struct GNUNET_MESSENGER_ListTunnel * next
struct GNUNET_MESSENGER_ListTunnel * head
struct GNUNET_MESSENGER_MemberSession * session
struct GNUNET_MESSENGER_SrvRoom * room
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_MESSENGER_MemberSessionCompletion * prev
struct GNUNET_MESSENGER_MemberSession * session
struct GNUNET_MESSENGER_MemberSessionCompletion * next
struct GNUNET_MESSENGER_MemberSession * prev
struct GNUNET_MESSENGER_ListMessages messages
struct GNUNET_CONTAINER_MultiShortmap * members
struct GNUNET_MESSENGER_MemberSessionCompletion * head
const struct GNUNET_MESSENGER_Message * message
struct GNUNET_MESSENGER_MemberSessionCompletion * tail
struct GNUNET_CONTAINER_MultiHashMap * sessions
struct GNUNET_MESSENGER_MessageMerge merge
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_TIME_AbsoluteNBO timestamp
The timestamp of the message.
struct GNUNET_ShortHashCode sender_id
The senders id inside of the room the message was sent in.
struct GNUNET_HashCode previous
The hash of a second previous message.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.
struct GNUNET_CADET_Handle * cadet
struct GNUNET_MESSENGER_ListHandles handles
struct GNUNET_HashCode * peer_message
struct GNUNET_CONTAINER_MultiPeerMap * tunnels
struct GNUNET_MESSENGER_MemberStore member_store
struct GNUNET_MESSENGER_Service * service
struct GNUNET_CADET_Port * port
struct GNUNET_MESSENGER_ListTunnels basement
struct GNUNET_SCHEDULER_Task * idle
struct GNUNET_MESSENGER_MessageStore message_store
struct GNUNET_MESSENGER_MessageState state
struct GNUNET_MESSENGER_ListMessages handling
struct GNUNET_MESSENGER_OperationStore operation_store
struct GNUNET_MESSENGER_SrvHandle * host
struct GNUNET_CADET_Channel * channel
struct GNUNET_MESSENGER_SrvRoom * room
Message handler for a specific message type.
Header for all communications.
The identity of the host (wraps the signing key of the peer).
A 256-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.