GNUnet  0.11.x
gnunet-service-messenger_room.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020 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 
29 
32 
33 static void
34 idle_request_room_messages (void *cls);
35 
38 {
39  GNUNET_assert((handle) && (key));
40 
42 
43  room->service = handle->service;
44  room->host = handle;
45  room->port = NULL;
46 
47  GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode));
48 
52 
53  init_message_store (&(room->store));
55 
56  init_list_tunnels (&(room->basement));
58 
59  room->peer_message = NULL;
60 
61  init_list_messages (&(room->handling));
62  room->idle = NULL;
63 
64  room->strict_access = GNUNET_NO;
65 
66  if (room->service->dir)
68 
70 
71  return room;
72 }
73 
74 static int
75 iterate_destroy_tunnels (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
76 {
77  struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
78  destroy_tunnel (tunnel);
79  return GNUNET_YES;
80 }
81 
82 static int
83 iterate_clear_members (void *cls, const struct GNUNET_ShortHashCode *key, void *value)
84 {
85  struct GNUNET_MESSENGER_SrvContact *contact = value;
86 
87  if (GNUNET_YES == decrease_contact_rc (contact))
88  {
89  struct GNUNET_MESSENGER_SrvRoom *room = cls;
90 
91  const struct GNUNET_HashCode *id = get_contact_id_from_key (contact);
92 
94  destroy_contact (contact);
95  }
96 
97  return GNUNET_YES;
98 }
99 
100 static int
102 {
103  struct GNUNET_MESSENGER_MemberInfo *info = value;
104 
106 
107  GNUNET_free(info);
108  return GNUNET_YES;
109 }
110 
111 void
113 {
114  GNUNET_assert(room);
115 
116  if (room->idle)
117  {
119 
120  room->idle = NULL;
121  }
122 
123  if (room->port)
125 
126  merge_room_last_messages (room, room->host);
127 
129  NULL);
130 
131  handle_room_messages (room);
132 
133  if (room->service->dir)
135 
138 
139  clear_message_store (&(room->store));
140 
142 
146 
147  clear_list_tunnels (&(room->basement));
149 
150  if (room->peer_message)
151  GNUNET_free(room->peer_message);
152 
153  GNUNET_free(room);
154 }
155 
158 {
159  GNUNET_assert((room) && (room->members));
160 
161  return GNUNET_CONTAINER_multishortmap_get (room->members, id);
162 }
163 
164 void
166  const struct GNUNET_IDENTITY_PublicKey *pubkey)
167 {
168  struct GNUNET_MESSENGER_SrvContact *contact = get_service_contact_by_pubkey (room->service, pubkey);
169 
170  if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put (room->members, id, contact,
172  increase_contact_rc (contact);
173 }
174 
177 {
178  GNUNET_assert((room) && (room->member_infos));
179 
181 }
182 
183 struct GNUNET_ShortHashCode*
185 {
186  struct GNUNET_ShortHashCode *unique_id = GNUNET_new(struct GNUNET_ShortHashCode);
187 
188  GNUNET_assert(room);
189 
190  if (GNUNET_YES == generate_free_member_id (unique_id, room->members))
191  return unique_id;
192  else
193  {
194  GNUNET_free(unique_id);
195  return NULL;
196  }
197 }
198 
199 const struct GNUNET_ShortHashCode*
201 {
202  GNUNET_assert(room);
203 
204  return get_handle_member_id (room->host, &(room->key));
205 }
206 
207 void
209 {
210  GNUNET_assert(room);
211 
212  change_handle_member_id (room->host, &(room->key), unique_id);
213 }
214 
215 static int
217  struct GNUNET_MESSENGER_SrvTunnel *tunnel)
218 {
219  if (!handle)
220  return GNUNET_NO;
221 
222  merge_room_last_messages (room, handle);
223 
224  if (!is_tunnel_connected (tunnel))
225  return GNUNET_NO;
226 
227  struct GNUNET_MESSENGER_Message *message = create_message_info (get_handle_ego(handle), room->members);
228 
229  if (!message)
230  return GNUNET_NO;
231 
232  if ((tunnel->peer_message) && (tunnel->contact_id))
233  {
234  GNUNET_memcpy(&(message->body.info.unique_id), &(tunnel->contact_id), sizeof(struct GNUNET_ShortHashCode));
235  GNUNET_free(tunnel->contact_id);
236 
237  tunnel->contact_id = NULL;
238  }
239 
240  struct GNUNET_HashCode hash;
241 
242  send_tunnel_message (tunnel, handle, message, &hash);
243  destroy_message (message);
244 
245  if (tunnel->contact_id)
246  {
247  GNUNET_free(tunnel->contact_id);
248 
249  tunnel->contact_id = NULL;
250  }
251 
252  return GNUNET_YES;
253 }
254 
255 static void*
256 callback_room_connect (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
257 {
258  struct GNUNET_MESSENGER_SrvRoom *room = cls;
259 
261 
262  if (tunnel)
263  {
264  if (GNUNET_YES == bind_tunnel (tunnel, channel))
265  {
266  if (GNUNET_YES == send_room_info (room, room->host, tunnel))
267  return tunnel;
268  else
269  {
270  disconnect_tunnel (tunnel);
271  return NULL;
272  }
273  }
274  else
275  {
276  delayed_disconnect_channel (channel);
277  return NULL;
278  }
279  }
280  else
281  {
282  tunnel = create_tunnel (room, source);
283 
284  if ((GNUNET_YES == bind_tunnel (tunnel, channel)) && (GNUNET_OK
285  == GNUNET_CONTAINER_multipeermap_put (room->tunnels, source, tunnel,
287  {
288  if (GNUNET_YES == send_room_info (room, room->host, tunnel))
289  return tunnel;
290  else
291  {
292  GNUNET_CONTAINER_multipeermap_remove (room->tunnels, source, tunnel);
293 
294  disconnect_tunnel (tunnel);
295  destroy_tunnel (tunnel);
296  return NULL;
297  }
298  }
299  else
300  {
301  tunnel->channel = NULL;
302  destroy_tunnel (tunnel);
303 
304  delayed_disconnect_channel (channel);
305  return NULL;
306  }
307  }
308 }
309 
310 static int
312  const struct GNUNET_ShortHashCode *member_id)
313 {
314  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s(get_room_key(room)), GNUNET_sh2s(member_id));
315 
316  struct GNUNET_MESSENGER_Message *message = create_message_join (get_handle_ego(handle));
317 
318  if (!message)
319  {
320  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be created!\n");
321 
322  return GNUNET_NO;
323  }
324 
325  struct GNUNET_HashCode hash;
326 
327  send_room_message (room, handle, message, &hash);
328  destroy_message (message);
329 
331 
334 
335  if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_put (room->member_infos, member_id, info,
337  {
338  change_handle_member_id (handle, &(room->key), member_id);
339 
340  add_to_list_messages (&(info->session_messages), &hash);
341  return GNUNET_YES;
342  }
343  else
344  {
345  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Your member information could not be registered!\n");
346 
347  GNUNET_free(info);
348  return GNUNET_NO;
349  }
350 }
351 
352 static int
354 {
355  const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, &(room->key));
356 
358 
359  if ((!info) && (GNUNET_NO == join_room (room, handle, member_id)))
360  return GNUNET_NO;
361 
362  return GNUNET_YES;
363 }
364 
365 extern int
366 check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header);
367 extern void
368 handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header);
369 
370 extern void
371 callback_tunnel_disconnect (void *cls, const struct GNUNET_CADET_Channel *channel);
372 
373 int
375 {
376  if (room->port)
377  return join_room_locally (room, handle);
378 
379  struct GNUNET_CADET_Handle *cadet = get_room_cadet (room);
380  struct GNUNET_HashCode *key = get_room_key (room);
381 
383  struct GNUNET_MessageHeader, NULL),
385 
386  room->port = GNUNET_CADET_open_port (cadet, key, callback_room_connect, room, NULL,
387  callback_tunnel_disconnect, handlers);
388 
389  const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, &(room->key));
390 
392 
393  if ((!info) && (GNUNET_NO == join_room (room, handle, member_id)) && (room->port))
394  {
395  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, therefore it keeps closed!\n");
396 
398  room->port = NULL;
399 
400  return GNUNET_NO;
401  }
402 
403  struct GNUNET_MESSENGER_Message *message = create_message_peer (room->service);
404 
405  if (message)
406  {
407  struct GNUNET_HashCode hash;
408 
409  send_room_message (room, handle, message, &hash);
410  destroy_message (message);
411  }
412 
413  return (room->port ? GNUNET_YES : GNUNET_NO);
414 }
415 
416 int
418  const struct GNUNET_PeerIdentity *door)
419 {
420  if (room->peer_message)
421  {
422  const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, handle, room->peer_message, GNUNET_NO);
423 
424  if (0 == GNUNET_memcmp(&(msg->body.peer.peer), door))
425  return join_room_locally (room, handle);
426  }
427 
429 
430  if (tunnel)
431  {
432  switch (connect_tunnel (tunnel))
433  {
434  case GNUNET_YES:
435  return GNUNET_YES;
436  case GNUNET_NO:
437  return join_room_locally (room, handle);
438  default:
439  return GNUNET_NO;
440  }
441  }
442 
443  tunnel = create_tunnel (room, door);
444 
445  if ((GNUNET_YES == connect_tunnel (tunnel)) &&
446  (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (room->tunnels, door, tunnel,
448  return GNUNET_YES;
449  else
450  {
451  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that door!\n");
452 
453  destroy_tunnel (tunnel);
454  return GNUNET_NO;
455  }
456 }
457 
459 {
462 };
463 
464 static int
465 iterate_find_tunnel (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
466 {
468  struct GNUNET_MESSENGER_SrvTunnelFinder *finder = cls;
469 
470  if ((tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, finder->needle)))
471  {
472  finder->tunnel = tunnel;
473  return GNUNET_NO;
474  }
475 
476  return GNUNET_YES;
477 }
478 
481 {
482  struct GNUNET_MESSENGER_SrvTunnelFinder finder;
483 
484  finder.needle = contact_id;
485  finder.tunnel = NULL;
486 
488 
489  return finder.tunnel;
490 }
491 
492 struct GNUNET_MQ_Envelope*
494  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, int mode)
495 {
497 
498  const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, &(room->key));
499 
500  GNUNET_assert(id);
501 
502  GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode));
503 
504  if (room->last_messages.head)
505  GNUNET_memcpy(&(message->header.previous), &(room->last_messages.head->hash), sizeof(struct GNUNET_HashCode));
506  else
507  memset (&(message->header.previous), 0, sizeof(struct GNUNET_HashCode));
508 
509  return pack_message (message, hash, get_handle_ego (handle), mode);
510 }
511 
513 {
519  int packed;
520 };
521 
522 static int
523 iterate_send_room_message (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
524 {
526 
527  if ((!is_tunnel_connected (tunnel)) || (!tunnel->contact_id))
528  return GNUNET_YES;
529 
530  struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls;
531 
532  if (tunnel == closure->exclude)
533  return GNUNET_YES;
534 
535  struct GNUNET_MQ_Envelope *env = NULL;
536 
537  if (closure->packed == GNUNET_NO)
538  {
539  env = pack_room_message (closure->room, closure->handle, closure->message, closure->hash,
541 
542  if (env)
543  {
544  closure->message = copy_message (closure->message);
545  closure->packed = GNUNET_YES;
546  }
547  }
548  else
549  {
550  env = pack_message (closure->message, NULL, NULL,
552  }
553 
554  if (env)
555  send_tunnel_envelope (tunnel, closure->handle, env, closure->message, closure->hash);
556 
557  return GNUNET_YES;
558 }
559 
560 void
562  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
563 
564 void
566  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
567 {
568  struct GNUNET_MESSENGER_ClosureSendRoom closure;
569 
570  closure.room = room;
571  closure.handle = handle;
572  closure.exclude = NULL;
573  closure.message = message;
574  closure.hash = hash;
575  closure.packed = GNUNET_NO;
576 
578 
579  if ((GNUNET_NO == closure.packed) && (closure.message == message))
580  {
581  pack_room_message (room, handle, message, hash,
583 
584  callback_room_sent (room, handle, NULL, copy_message (message), hash);
585  }
586 }
587 
588 void
590  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash,
592 {
593  struct GNUNET_MESSENGER_ClosureSendRoom closure;
594 
595  closure.room = room;
596  closure.handle = handle;
597  closure.exclude = tunnel;
598  closure.message = message;
599  closure.hash = hash;
600  closure.packed = GNUNET_NO;
601 
603 
604  if ((GNUNET_NO == closure.packed) && (closure.message == message))
605  {
606  pack_room_message (room, handle, message, hash,
608 
609  callback_room_sent (room, handle, NULL, copy_message (message), hash);
610  }
611 }
612 
613 void
615  const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
616 {
617  struct GNUNET_MESSENGER_ClosureSendRoom closure;
618  struct GNUNET_HashCode message_hash;
619 
620  GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode));
621 
622  closure.room = room;
623  closure.handle = NULL;
624  closure.exclude = tunnel;
625  closure.message = copy_message (message);
626  closure.hash = &message_hash;
627  closure.packed = GNUNET_YES;
628 
630 }
631 
632 void
634 {
635  if (!handle)
636  return;
637 
638  if (!room->last_messages.head)
639  return;
640 
641  while (room->last_messages.head != room->last_messages.tail)
642  {
643  struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.tail;
644 
645  struct GNUNET_MESSENGER_Message *message = create_message_merge (&(element->hash));
646 
647  if (message)
648  {
649  struct GNUNET_HashCode hash;
650 
651  send_room_message (room, handle, message, &hash);
652  destroy_message (message);
653  }
654 
655  if (element->prev)
657  }
658 }
659 
660 struct GNUNET_CADET_Handle*
662 {
663  return room->service->cadet;
664 }
665 
666 struct GNUNET_HashCode*
668 {
669  return &(room->key);
670 }
671 
672 const struct GNUNET_MESSENGER_SrvTunnel*
674 {
675  return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer);
676 }
677 
678 const struct GNUNET_MESSENGER_Message*
680  const struct GNUNET_HashCode *hash, int request)
681 {
682  const struct GNUNET_MESSENGER_Message *message = get_store_message (&(room->store), hash);
683 
684  if ((message) || (!handle) || (GNUNET_YES != request)
686  return message;
687 
688  struct GNUNET_MESSENGER_Message *request_msg = create_message_request (hash);
689 
690  if (request_msg)
691  {
693  {
694  struct GNUNET_HashCode request_hash;
695 
696  send_room_message (room, handle, request_msg, &request_hash);
697  }
698 
699  destroy_message (request_msg);
700  }
701 
702  return message;
703 }
704 
705 void
707 {
708  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
709 
710  if (!room->host)
711  return;
712 
713  struct GNUNET_PeerIdentity identity;
714 
715  GNUNET_PEER_resolve (tunnel->peer, &identity);
716 
717  if (GNUNET_YES == contains_list_tunnels (&(room->basement), &identity))
718  {
719  struct GNUNET_MESSENGER_Message *message = create_message_miss (&identity);
720 
721  if (message)
722  {
723  struct GNUNET_HashCode hash;
724 
725  send_room_message (room, room->host, message, &hash);
726  destroy_message (message);
727  }
728  }
729 }
730 
731 int
733  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
734 {
735  if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind)
736  return GNUNET_SYSERR;
737 
739  &(message->header.sender_id));
740 
741  if (!contact)
742  {
743  if (GNUNET_MESSENGER_KIND_INFO == message->header.kind)
744  contact = get_service_contact_by_pubkey (room->service, &(message->body.info.host_key));
745  else if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)
746  contact = get_service_contact_by_pubkey (room->service, &(message->body.join.key));
747  }
748 
749  if ((!contact) || (GNUNET_SYSERR == verify_message (message, hash, get_contact_key (contact))))
750  return GNUNET_SYSERR;
751 
752  if (GNUNET_YES == room->strict_access)
753  {
755  &(message->header.sender_id));
756 
757  if ((info) && (GNUNET_MESSENGER_MEMBER_BLOCKED == info->access))
758  return GNUNET_SYSERR;
759  }
760 
761  if (GNUNET_YES == contains_store_message (&(room->store), hash))
762  return GNUNET_NO;
763 
764  return GNUNET_YES;
765 }
766 
767 static void
769 {
770  const struct GNUNET_MESSENGER_Message *message = get_room_message (room, room->host, hash, GNUNET_YES);
771 
772  if (!message)
773  return;
774 
775  if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind)
776  search_room_for_message (room, &(message->body.merge.previous));
777 
778  search_room_for_message (room, &(message->header.previous));
779 }
780 
781 static void
783 {
784  struct GNUNET_MESSENGER_SrvRoom *room = cls;
785 
786  room->idle = NULL;
787 
788  struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.head;
789 
790  while (element)
791  {
792  search_room_for_message (room, &(element->hash));
793 
794  element = element->next;
795  }
796 
797  merge_room_last_messages (room, room->host);
798 
801  cls);
802 }
803 
804 void
806  const struct GNUNET_HashCode *hash)
807 {
808  struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.head;
809  struct GNUNET_MESSENGER_ListMessage *merging = NULL;
810 
811  if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind)
812  {
813  merging = room->last_messages.head;
814 
815  while (merging)
816  {
817  if (0 == GNUNET_CRYPTO_hash_cmp (&(merging->hash), &(message->body.merge.previous)))
818  break;
819 
820  merging = merging->next;
821  }
822 
823  if (merging)
824  element = merging->next;
825  }
826 
827  while (element)
828  {
829  if (0 == GNUNET_CRYPTO_hash_cmp (&(element->hash), &(message->header.previous)))
830  break;
831 
832  element = element->next;
833  }
834 
835  if ((merging) && (!element))
836  {
837  element = merging;
838  merging = NULL;
839  }
840 
841  if (element)
842  {
843  GNUNET_memcpy(&(element->hash), hash, sizeof(struct GNUNET_HashCode));
844 
845  if (merging)
847  }
848  else
849  add_to_list_messages (&(room->last_messages), hash);
850 
853 }
854 
855 void
857  const struct GNUNET_ShortHashCode *new_id, const struct GNUNET_HashCode *hash)
858 {
860 
861  if ((contact) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (room->members, old_id, contact)))
862  GNUNET_CONTAINER_multishortmap_put (room->members, new_id, contact,
864 
866 
867  if ((!info) || (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->member_infos, old_id, contact))
868  || (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put (room->member_infos, new_id, contact,
870  return;
871 
872  if (hash)
873  add_to_list_messages (&(info->session_messages), hash);
874 }
875 
876 void
878 {
879  struct GNUNET_PeerIdentity peer;
880  size_t src;
881 
882  if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) || (!find_list_tunnels (&(room->basement), &peer,
883  &src)))
884  return;
885 
886  size_t count = count_of_tunnels (&(room->basement));
887 
888  struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head;
890 
891  size_t dst = 0;
892 
893  while (element)
894  {
895  GNUNET_PEER_resolve (element->peer, &peer);
896 
897  tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, &peer);
898 
899  if (!tunnel)
900  {
901  element = remove_from_list_tunnels (&(room->basement), element);
902  continue;
903  }
904 
905  if (GNUNET_YES == required_connection_between (count, src, dst))
906  {
907  if (GNUNET_SYSERR == connect_tunnel (tunnel))
908  {
909  element = remove_from_list_tunnels (&(room->basement), element);
910  continue;
911  }
912  }
913  else
914  disconnect_tunnel (tunnel);
915 
916  element = element->next;
917  dst++;
918  }
919 }
920 
921 void
923 {
924  while (room->handling.head)
925  {
926  struct GNUNET_MESSENGER_ListMessage *element = room->handling.head;
927 
928  const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(element->hash), GNUNET_NO);
929 
930  if (msg)
931  handle_service_message (room->service, room, msg, &(element->hash));
932 
933  GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element);
934  GNUNET_free(element);
935  }
936 }
937 
939 
940 void
941 callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message,
942  const struct GNUNET_HashCode *hash)
943 {
944  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
945 
946  if (GNUNET_OK != put_store_message (&(room->store), hash, message))
947  return;
948 
949  update_room_last_messages (room, message, hash);
950 
951  if (GNUNET_MESSENGER_KIND_INFO != message->header.kind)
952  forward_room_message (room, tunnel, message, hash);
953 
954  const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES;
955 
956  add_to_list_messages (&(room->handling), hash);
957 
958  switch (message->header.kind)
959  {
961  recv_message_info (room, tunnel, message, hash);
962  break;
964  recv_message_join (room, tunnel, message, hash);
965  break;
967  recv_message_leave (room, tunnel, message, hash);
968  break;
970  recv_message_name (room, tunnel, message, hash);
971  break;
973  recv_message_key (room, tunnel, message, hash);
974  break;
976  recv_message_peer (room, tunnel, message, hash);
977  break;
979  recv_message_id (room, tunnel, message, hash);
980  break;
982  recv_message_miss (room, tunnel, message, hash);
983  break;
985  recv_message_request (room, tunnel, message, hash);
986  break;
987  default:
988  break;
989  }
990 
991  if (GNUNET_YES == start_handle)
992  handle_room_messages (room);
993 }
994 
996 
997 void
999  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
1000 {
1001  const struct GNUNET_MESSENGER_Message *old_message = get_room_message (room, handle, hash, GNUNET_NO);
1002 
1003  if ((old_message) || (GNUNET_OK != put_store_message (&(room->store), hash, message)))
1004  {
1005  if (old_message != message)
1006  GNUNET_free(message);
1007  }
1008  else
1009  {
1010  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; // may be NULL
1011 
1012  update_room_last_messages (room, message, hash);
1013 
1014  const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES;
1015 
1016  add_to_list_messages (&(room->handling), hash);
1017 
1018  switch (message->header.kind)
1019  {
1021  send_message_info (room, handle, tunnel, message, hash);
1022  break;
1024  send_message_join (room, handle, tunnel, message, hash);
1025  break;
1027  send_message_leave (room, handle, tunnel, message, hash);
1028  break;
1030  send_message_name (room, handle, tunnel, message, hash);
1031  break;
1033  send_message_key (room, handle, tunnel, message, hash);
1034  break;
1036  send_message_peer (room, handle, tunnel, message, hash);
1037  break;
1039  send_message_id (room, handle, tunnel, message, hash);
1040  break;
1042  send_message_miss (room, handle, tunnel, message, hash);
1043  break;
1044  default:
1045  break;
1046  }
1047 
1048  if (GNUNET_YES == start_handle)
1049  handle_room_messages (room);
1050  }
1051 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int open_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
Tries to open a room for a given handle.
struct GNUNET_PeerIdentity peer
The peer identity of the sender opening a room.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
void recv_message_miss(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received miss message.
struct GNUNET_MESSENGER_MessageHeader header
Header.
void recv_message_key(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received key message.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
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...
GNUnet MESSENGER service.
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.
struct GNUNET_ShortHashCode sender_id
The senders id inside of the room the message was sent in.
struct GNUNET_MESSENGER_ListMessage * next
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static void idle_request_room_messages(void *cls)
struct GNUNET_TIME_AbsoluteNBO timestamp
The timestamp of the message.
GNUnet MESSENGER service.
void delayed_disconnect_channel(struct GNUNET_CADET_Channel *channel)
Starts an urgent task to close a CADET channel asynchronously.
void recv_message_info(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received info message to change the current member id to the one generated by the host conn...
struct GNUNET_MESSENGER_Ego * get_handle_ego(struct GNUNET_MESSENGER_SrvHandle *handle)
Returns the EGO used by a given handle.
struct GNUNET_CADET_Handle * cadet
struct GNUNET_MESSENGER_ListMessage * head
struct GNUNET_ShortHashCode unique_id
The new unique id for the receiver in a room.
static void search_room_for_message(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
struct GNUNET_HashCode * get_room_key(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
void send_message_leave(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent leave message.
Opaque handle to the service.
Definition: cadet_api.c:38
const struct GNUNET_ShortHashCode * needle
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:1199
struct GNUNET_MESSENGER_Service * service
static int iterate_send_room_message(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
void forward_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, const 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.
static void * callback_room_connect(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
GNUnet MESSENGER service.
void send_message_join(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent join message to ensure growth of the decentralized room structure. ...
void recv_message_name(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received name message.
void destroy_contact(struct GNUNET_MESSENGER_SrvContact *contact)
Destroys a contact and frees its memory fully.
GNUnet MESSENGER service.
int callback_verify_room_message(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
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.
void destroy_room(struct GNUNET_MESSENGER_SrvRoom *room)
Destroys a room and frees its memory fully.
struct GNUNET_MESSENGER_SrvHandle * handle
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int decrease_contact_rc(struct GNUNET_MESSENGER_SrvContact *contact)
Decreases the reference counter if possible (can not underflow!) of a given contact and returns GNUNE...
void recv_message_request(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received request message by checking for the requested message and forwarding it back if th...
static int join_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_ShortHashCode *member_id)
struct GNUNET_IDENTITY_PublicKey host_key
The senders key to verify its signatures.
struct GNUNET_MESSENGER_ListTunnel * head
void callback_room_sent(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
static int iterate_clear_members(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
void update_room_last_messages(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Updates the last messages of a room by replacing them if the previous hash of a given message matches...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
void handle_room_messages(struct GNUNET_MESSENGER_SrvRoom *room)
Handles all queued up messages of a room to handle in correct order.
int connect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Tries to connect a tunnel by creating a new CADET channel and binding it.
int 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.
Opaque handle to a channel.
Definition: cadet.h:116
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_MESSENGER_PACK_MODE_UNKNOWN
void load_service_room_and_messages(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room)
Loads the local configuration for a given room of a service which contains the last messages hash and...
struct GNUNET_MESSENGER_ListTunnel * next
struct GNUNET_MESSENGER_ListMessage * prev
void change_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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_CONTAINER_multihashmap_remove_all(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Remove all entries for the given key from the map.
#define GNUNET_MESSAGE_TYPE_CADET_CLI
Traffic (net-cat style) used by the Command Line Interface.
struct GNUNET_CADET_Port * port
struct GNUNET_MESSENGER_Message * create_message_info(struct GNUNET_MESSENGER_Ego *ego, struct GNUNET_CONTAINER_MultiShortmap *members)
Creates and allocates a new info message containing the hosts public key and a newly generated unique...
struct GNUNET_CONTAINER_MultiShortmap * member_infos
int 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)...
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
static int iterate_destroy_tunnels(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
GNUnet MESSENGER service.
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_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition: peer.c:225
void save_service_room_and_messages(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room)
Saves the configuration for a given room of a service which contains the last messages hash and the r...
struct GNUNET_CADET_Handle * get_room_cadet(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the CADET handle from a rooms service.
const struct GNUNET_MESSENGER_SrvTunnel * get_room_tunnel(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, otherwise NULL.
void recv_message_join(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received join message to forward all member information to the new member if the message wa...
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
struct GNUNET_MESSENGER_MemberInfo * get_room_member_info(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id)
Returns the member information of a member in a room identified by a given id.
A 256-bit hashcode.
void callback_room_disconnect(struct GNUNET_MESSENGER_SrvRoom *room, void *cls)
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...
void send_message_miss(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent miss message.
int is_tunnel_connected(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the status of a currently bound channel of a tunnel.
const struct GNUNET_ShortHashCode * get_room_host_id(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the member id of the member representing the handle currently hosting this room...
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...
static int send_room_info(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
struct GNUNET_MESSENGER_SrvContact * get_room_contact(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id)
Returns the contact of a member in a room identified by a given id.
void send_message_id(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent id message.
void increase_contact_rc(struct GNUNET_MESSENGER_SrvContact *contact)
Increases the reference counter of a given contact which is zero as default.
struct GNUNET_SCHEDULER_Task * idle
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:1223
void init_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Initializes list of message hashes as empty list.
struct GNUNET_MESSENGER_ListMessages last_messages
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:970
struct GNUNET_MESSENGER_Service * service
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
struct GNUNET_ShortHashCode * generate_room_member_id(const struct GNUNET_MESSENGER_SrvRoom *room)
Tries to generate and allocate a new unique member id checking all current members for possible dupli...
struct GNUNET_IDENTITY_PublicKey key
The senders public key to verify its signatures.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
static char * value
Value of the record to add/remove.
struct GNUNET_MESSENGER_Message * create_message_request(const struct GNUNET_HashCode *hash)
Creates and allocates a new request message containing the hash of a missing message.
struct GNUNET_MESSENGER_SrvRoom * room
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_HashCode * peer_message
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_HashCode previous
The hash of a second previous message.
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.
int check_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
void merge_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...
struct GNUNET_MESSENGER_MessageBody body
Body.
struct GNUNET_MESSENGER_Message * create_message_join(struct GNUNET_MESSENGER_Ego *ego)
Creates and allocates a new join message containing the clients public key.
void send_tunnel_envelope(struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Sends an envelope containing a message with a given hash through a tunnel by a given handle...
struct GNUNET_MESSENGER_SrvRoom * room
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
int GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
int contains_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Checks if a message matching a given hash is stored in a message store.
void clear_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels)
Clears the list of tunnels peer identities.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
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.
struct GNUNET_MESSENGER_Message * message
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_MessageMerge merge
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void send_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
Sends a message by packing it automatically into an envelope and passing it through the tunnel...
void send_message_info(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent info message to setup a tunnels linked member id.
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).
struct GNUNET_MESSENGER_ListMessages handling
A 512-bit hashcode.
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.
Message handler for a specific message type.
void switch_room_member_id(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *old_id, const struct GNUNET_ShortHashCode *new_id, const struct GNUNET_HashCode *hash)
Changes an id of a current member from an old id to a new one and adds optionally the hash of an id m...
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
void recv_message_id(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received id message to change the tunnels linked member id if necessary.
const struct GNUNET_IDENTITY_PublicKey * get_contact_key(const struct GNUNET_MESSENGER_SrvContact *contact)
Returns the public key of a given contact.
Run when otherwise idle.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
void handle_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
void add_room_contact(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id, const struct GNUNET_IDENTITY_PublicKey *pubkey)
Adds a contact from the service to a room under a specific id with a given public key...
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CONTAINER_MultiShortmap * members
struct GNUNET_MESSENGER_SrvHandle * host
struct GNUNET_MESSENGER_MessageInfo info
struct GNUNET_MESSENGER_Message * copy_message(const struct GNUNET_MESSENGER_Message *message)
Creates and allocates a copy of a given message.
void callback_tunnel_disconnect(void *cls, const struct GNUNET_CADET_Channel *channel)
#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE
struct GNUNET_MESSENGER_MessagePeer peer
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_MESSENGER_Message * create_message_miss(const struct GNUNET_PeerIdentity *peer)
Creates and allocates a new miss message containing the missing peer identity.
void send_room_message_ext(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Sends a message from a given handle into a room excluding one specific tunnel.
void rebuild_room_basement_structure(struct GNUNET_MESSENGER_SrvRoom *room)
Rebuilds the decentralized structure for a room by ensuring all required connections are made dependi...
struct GNUNET_MESSENGER_ListMessage * tail
void send_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
Sends a message from a given handle into a room.
int 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_CADET_Channel * channel
struct GNUNET_MESSENGER_SrvContact * get_service_contact_by_pubkey(struct GNUNET_MESSENGER_Service *service, const struct GNUNET_IDENTITY_PublicKey *pubkey)
Returns a contact of a service identified by a given public key.
void clear_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Clears the list of message hashes.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
const struct GNUNET_HashCode * get_contact_id_from_key(const struct GNUNET_MESSENGER_SrvContact *contact)
Returns the resulting hashcode of the public key from a given contact.
const struct GNUNET_MESSENGER_Message * get_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *hash, int request)
Returns a message from a room identified by a given hash.
void recv_message_leave(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received leave message.
void send_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent peer message to update the rooms peer message of this service.
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.
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.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_second_(void)
Return relative time of 1s.
Definition: time.c:183
struct GNUNET_MESSENGER_SrvRoom * create_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Creates and allocates a new room for a handle with a given key.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CONTAINER_MultiHashMap * contacts
An identity key as per LSD0001.
void init_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels)
Initializes list of tunnels peer identities as empty list.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_MESSENGER_ListTunnels basement
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:311
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.
struct GNUNET_MQ_Envelope * pack_room_message(struct GNUNET_MESSENGER_SrvRoom *room, 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.
#define GNUNET_log(kind,...)
int bind_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
Binds a CADET channel to a tunnel on returns GNUNET_YES only if the bounds channel was replaced succe...
struct GNUNET_MESSENGER_ListMessages session_messages
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void init_message_store(struct GNUNET_MESSENGER_MessageStore *store)
Initializes a message store as fully empty.
Header for all communications.
const struct GNUNET_ShortHashCode * get_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.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
void disconnect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Disconnects and unbinds a channel from a tunnel.
void recv_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received peer message to link it to its origin tunnel if the peer identity matches...
enum GNUNET_MESSENGER_MemberAccess access
struct GNUNET_MESSENGER_SrvTunnel * exclude
static int iterate_find_tunnel(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
struct GNUNET_ShortHashCode * contact_id
struct GNUNET_MESSENGER_MessageJoin join
struct GNUNET_CONTAINER_MultiHashMap * requested
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.
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 send_message_name(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent name message.
struct GNUNET_CONTAINER_MultiPeerMap * tunnels
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
static int iterate_destroy_member_infos(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
struct GNUNET_MESSENGER_SrvTunnel * find_room_tunnel_to(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *contact_id)
Returns a tunnel granting a direct connection to a specific member in a room.
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.
int entry_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 send_message_key(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent key message.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void change_room_host_id(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *unique_id)
Changes the member id of the member representing the handle currently hosting this room...
int verify_message(const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, const struct GNUNET_IDENTITY_PublicKey *key)
Verifies the signature of a given message and its hash with a specific public key.
GNUnet MESSENGER service.
struct GNUNET_MESSENGER_MessageStore store
#define GNUNET_free(ptr)
Wrapper around free.
void handle_service_message(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, 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...
static int join_room_locally(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
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...
void clear_message_store(struct GNUNET_MESSENGER_MessageStore *store)
Clears a message store, wipes its content and deallocates its memory.
void callback_room_recv(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
struct GNUNET_MESSENGER_SrvTunnel * tunnel