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--2021 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 {
48  GNUNET_assert((handle) && (key));
49 
51 
52  room->service = handle->service;
53  room->host = handle;
54  room->port = NULL;
55 
56  GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode));
57 
59 
63 
64  init_list_tunnels (&(room->basement));
66 
67  room->peer_message = NULL;
68 
69  init_list_messages (&(room->handling));
70  room->idle = NULL;
71 
72  if (room->service->dir)
73  load_room (room);
74 
76 
77  return room;
78 }
79 
80 static int
81 iterate_destroy_tunnels (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
82 {
83  struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
84  destroy_tunnel (tunnel);
85  return GNUNET_YES;
86 }
87 
88 static void
90 
91 void
93 {
94  GNUNET_assert(room);
95 
96  if (room->idle)
97  {
99 
100  room->idle = NULL;
101  }
102 
103  if (room->port)
105 
107 
108  handle_room_messages (room);
109 
110  if (room->service->dir)
111  save_room (room);
112 
116 
118 
119  clear_list_tunnels (&(room->basement));
121 
122  if (room->peer_message)
123  GNUNET_free(room->peer_message);
124 
125  GNUNET_free(room);
126 }
127 
130 {
131  GNUNET_assert(room);
132 
133  return &(room->member_store);
134 }
135 
138 {
139  GNUNET_assert(room);
140 
141  return &(room->message_store);
142 }
143 
146 {
147  GNUNET_assert(room);
148 
149  return &(room->operation_store);
150 }
151 
152 const struct GNUNET_ShortHashCode*
154 {
155  GNUNET_assert(room);
156 
157  return get_handle_member_id (room->host, get_room_key(room));
158 }
159 
160 void
162 {
163  GNUNET_assert(room);
164 
165  change_handle_member_id (room->host, get_room_key(room), unique_id);
166 }
167 
168 static int
170  struct GNUNET_MESSENGER_SrvTunnel *tunnel)
171 {
172  if ((!handle) || (!is_tunnel_connected (tunnel)))
173  return GNUNET_NO;
174 
175  return send_tunnel_message (tunnel, handle, create_message_info (get_handle_ego (handle)));
176 }
177 
178 static void*
179 callback_room_connect (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
180 {
181  struct GNUNET_MESSENGER_SrvRoom *room = cls;
182 
183  struct GNUNET_MESSENGER_SrvTunnel *tunnel = create_tunnel (room, source);
184 
185  if ((tunnel) &&
186  (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, source, tunnel,
188  {
189  destroy_tunnel (tunnel);
190  tunnel = NULL;
191  }
192 
193  if (!tunnel)
194  {
195  delayed_disconnect_channel (channel);
196  return NULL;
197  }
198 
199  bind_tunnel(tunnel, channel);
200 
201  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "New tunnel in room (%s) established to peer: %s\n",
202  GNUNET_h2s(get_room_key(room)), GNUNET_i2s (source));
203 
204  if (GNUNET_YES == send_room_info (room, room->host, tunnel))
205  return tunnel;
206 
207  disconnect_tunnel (tunnel);
208 
209  if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (room->tunnels, source, tunnel))
210  destroy_tunnel (tunnel);
211 
212  return NULL;
213 }
214 
215 static int
217  struct GNUNET_MESSENGER_Member *member)
218 {
219  GNUNET_assert((room) && (handle) && (member));
220 
221  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s (get_room_key (room)),
222  GNUNET_sh2s (get_member_id(member)));
223 
224  if (GNUNET_OK != change_handle_member_id (handle, get_room_key(room), get_member_id(member)))
225  return GNUNET_NO;
226 
227  struct GNUNET_MESSENGER_Message *message = create_message_join (get_handle_ego (handle));
228 
229  if (!message)
230  {
231  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be created!\n");
232 
233  return GNUNET_NO;
234  }
235 
236  return send_room_message (room, handle, message);
237 }
238 
240 {
244 };
245 
246 static int
249 {
251 
252  if (notify->session == session)
253  return GNUNET_YES;
254 
255  struct GNUNET_MESSENGER_ListMessage *element;
256 
257  for (element = session->messages.head; element; element = element->next)
258  {
259  const struct GNUNET_MESSENGER_Message *message = get_room_message (
260  notify->room, notify->handle, &(element->hash), GNUNET_NO
261  );
262 
263  if (message)
264  notify_handle_message (notify->handle, get_room_key(notify->room), session, message, &(element->hash));
265  }
266 
267  return GNUNET_YES;
268 }
269 
270 static int
272 {
273  const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, get_room_key(room));
274 
275  struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
276  struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, member_id);
277 
278  if (GNUNET_NO == join_room (room, handle, member))
279  return GNUNET_NO;
280 
281  const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(handle);
282  struct GNUNET_MESSENGER_MemberSession *session = get_member_session (member, &(ego->pub));
283 
284  if (!session)
285  {
286  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "A valid session is required to join a room!\n");
287  return GNUNET_NO;
288  }
289 
290  struct GNUNET_MESSENGER_MemberNotify notify;
291 
292  notify.room = room;
293  notify.handle = handle;
294  notify.session = session;
295 
297 
298  return GNUNET_YES;
299 }
300 
301 extern int
302 check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header);
303 
304 extern void
305 handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header);
306 
307 extern void
308 callback_tunnel_disconnect (void *cls, const struct GNUNET_CADET_Channel *channel);
309 
310 int
312 {
313  GNUNET_assert((room) && (handle));
314 
315  if (room->port)
316  return join_room_locally (room, handle);
317 
318  struct GNUNET_CADET_Handle *cadet = get_room_cadet (room);
319  const struct GNUNET_HashCode *key = get_room_key (room);
320 
322  struct GNUNET_MessageHeader, NULL),
324 
326  handlers);
327 
328  if (room->port)
329  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Port of room (%s) was opened!\n",
330  GNUNET_h2s(get_room_key(room)));
331  else
332  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Port of room (%s) could not be opened!\n",
333  GNUNET_h2s(get_room_key(room)));
334 
335  const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, get_room_key(room));
336 
337  struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
338  struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, member_id);
339 
340  if (member)
341  goto exit_open_room;
342 
343  member = add_store_member(member_store, member_id);
344 
345  if ((GNUNET_NO == join_room (room, handle, member)) && (room->port))
346  {
347  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, therefore it keeps closed!\n");
348 
350  room->port = NULL;
351 
352  return GNUNET_NO;
353  }
354 
355 exit_open_room:
356  return (room->port ? send_room_message (room, handle, create_message_peer (room->service)) : GNUNET_NO);
357 }
358 
359 int
361  const struct GNUNET_PeerIdentity *door)
362 {
363  GNUNET_assert((room) && (handle) && (door));
364 
365  struct GNUNET_PeerIdentity peer;
366 
367  if ((GNUNET_OK == get_service_peer_identity (room->service, &peer)) &&
368  (0 == GNUNET_memcmp(&peer, door)))
369  return join_room_locally (room, handle);
370 
372 
373  if (!tunnel)
374  {
375  tunnel = create_tunnel (room, door);
376 
377  if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, door, tunnel,
379  {
380  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that door!\n");
381  destroy_tunnel (tunnel);
382  return GNUNET_NO;
383  }
384  }
385 
386  if (GNUNET_SYSERR == connect_tunnel (tunnel))
387  {
388  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connection failure during entrance!\n");
389  GNUNET_CONTAINER_multipeermap_remove (room->tunnels, door, tunnel);
390  destroy_tunnel (tunnel);
391  return GNUNET_NO;
392  }
393 
394  return join_room_locally (room, handle);
395 }
396 
397 struct GNUNET_MQ_Envelope*
399  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, int mode)
400 {
401  GNUNET_assert((room) && (handle) && (message) && (hash));
402 
404 
405  const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, get_room_key(room));
406 
407  GNUNET_assert(id);
408 
409  GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode));
410 
411  if (room->last_messages.head)
412  GNUNET_memcpy(&(message->header.previous), &(room->last_messages.head->hash), sizeof(struct GNUNET_HashCode));
413  else
414  memset (&(message->header.previous), 0, sizeof(struct GNUNET_HashCode));
415 
416  return pack_message (message, hash, get_handle_ego (handle), mode);
417 }
418 
420 {
426  int packed;
427 };
428 
429 static int
430 iterate_send_room_message (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
431 {
432  struct GNUNET_MESSENGER_SrvTunnel *tunnel = value;
433 
434  if ((!is_tunnel_connected (tunnel)) ||
436  return GNUNET_YES;
437 
438  struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls;
439 
440  if (tunnel == closure->exclude)
441  return GNUNET_YES;
442 
443  struct GNUNET_MQ_Envelope *env = NULL;
444 
445  if (closure->packed == GNUNET_NO)
446  {
447  env = pack_room_message (closure->room, closure->handle, closure->message, closure->hash,
449 
450  if (env)
451  closure->packed = GNUNET_YES;
452  }
453  else
454  env = pack_message (closure->message, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE);
455 
456  if (env)
457  send_tunnel_envelope (tunnel, env, closure->hash);
458 
459  return GNUNET_YES;
460 }
461 
462 int
464  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
465 
466 void
468  const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
469 
470 int
472  struct GNUNET_MESSENGER_Message *message)
473 {
474  GNUNET_assert((room) && (handle));
475 
476  if (!message)
477  return GNUNET_NO;
478 
479  if (GNUNET_YES == is_message_session_bound(message))
480  merge_room_last_messages(room, handle);
481 
482  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Sending message from handle with member id: %s\n",
484 
485  struct GNUNET_HashCode hash;
486  struct GNUNET_MESSENGER_ClosureSendRoom closure;
487 
488  closure.room = room;
489  closure.handle = handle;
490  closure.exclude = NULL;
491  closure.message = message;
492  closure.hash = &hash;
493  closure.packed = GNUNET_NO;
494 
496 
497  if (GNUNET_NO == closure.packed)
498  pack_room_message (room, handle, message, &hash, GNUNET_MESSENGER_PACK_MODE_UNKNOWN);
499 
500  const int new_message = update_room_message (room, message, &hash);
501 
502  if (GNUNET_YES != new_message)
503  return GNUNET_SYSERR;
504 
505  switch (message->header.kind)
506  {
508  send_message_join (room, handle, message, &hash);
509  break;
511  send_message_peer (room, handle, message, &hash);
512  break;
514  send_message_request (room, handle, message, &hash);
515  break;
516  default:
517  break;
518  }
519 
520  callback_room_handle_message (room, handle, message, &hash);
521  return GNUNET_YES;
522 }
523 
524 void
526  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
527 {
528  GNUNET_assert((room) && (tunnel));
529 
530  if (!message)
531  return;
532 
533  struct GNUNET_MESSENGER_ClosureSendRoom closure;
534  struct GNUNET_HashCode message_hash;
535 
536  GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode));
537 
538  closure.room = room;
539  closure.handle = NULL;
540  closure.exclude = tunnel;
541  closure.message = message;
542  closure.hash = &message_hash;
543  closure.packed = GNUNET_YES;
544 
546 }
547 
548 void
550 {
551  if (!room->peer_message)
552  return;
553 
554  const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, room->peer_message, GNUNET_NO);
555 
556  if (!message)
557  {
558  GNUNET_free(room->peer_message);
559  room->peer_message = NULL;
560  return;
561  }
562 
563  struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
564  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
565 
566  if (!member)
567  goto resend_peer_message;
568 
570 
571  if (GNUNET_YES == is_member_session_closed(session))
572  goto resend_peer_message;
573 
574  if (tunnel)
575  forward_tunnel_message(tunnel, message, room->peer_message);
576 
577  return;
578 
579 resend_peer_message:
580  if (room->host)
581  send_room_message (room, room->host, create_message_peer (room->service));
582 }
583 
584 static void
586  const struct GNUNET_HashCode *hash)
587 {
588  GNUNET_assert((room) && (handle) && (hash));
589 
590  send_room_message (room, handle, create_message_merge (hash));
591 }
592 
593 void
595 {
596  GNUNET_assert(room);
597 
598  if (!handle)
599  return;
600 
601  if (!room->last_messages.head)
602  return;
603 
604  while (room->last_messages.head != room->last_messages.tail)
605  merge_room_message (room, handle, &(room->last_messages.tail->hash));
606 }
607 
608 void
610 {
611  const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, hash, GNUNET_NO);
612 
613  if (message)
614  add_to_list_messages(&(room->last_messages), &(message->header.previous));
615 
617  {
618  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! (%s)\n", GNUNET_h2s(hash));
619  return;
620  }
621 }
622 
623 void
625 {
626  if (!room->host)
627  return;
628 
629  merge_room_message (room, room->host, hash);
630 }
631 
632 int
634  const struct GNUNET_HashCode *hash, const struct GNUNET_TIME_Relative delay)
635 {
636  GNUNET_assert((room) && (session) && (hash));
637 
639 
640  if (0 == GNUNET_memcmp(&forever, &delay))
641  {
642  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Deletion is delayed forever: operation is impossible!\n");
643  return GNUNET_SYSERR;
644  }
645 
646  const struct GNUNET_MESSENGER_Message *message = get_room_message(room, NULL, hash, GNUNET_NO);
647 
648  if (!message)
649  return GNUNET_YES;
650 
651  if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_YES))
652  {
653  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unpermitted request for deletion by member (%s) of message (%s)!\n",
654  GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash));
655 
656  return GNUNET_NO;
657  }
658 
659  struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
660 
661  if (GNUNET_OK != use_store_operation(operation_store, hash, GNUNET_MESSENGER_OP_DELETE, delay))
662  {
663  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Deletion has failed: operation denied!\n");
664  return GNUNET_SYSERR;
665  }
666 
667  return GNUNET_YES;
668 }
669 
670 struct GNUNET_CADET_Handle*
672 {
673  GNUNET_assert(room);
674 
675  return room->service->cadet;
676 }
677 
678 const struct GNUNET_HashCode*
680 {
681  GNUNET_assert(room);
682 
683  return &(room->key);
684 }
685 
686 const struct GNUNET_MESSENGER_SrvTunnel*
688 {
689  GNUNET_assert((room) && (peer));
690 
691  return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer);
692 }
693 
694 const struct GNUNET_MESSENGER_Message*
696  const struct GNUNET_HashCode *hash, int request)
697 {
698  GNUNET_assert((room) && (hash));
699 
700  const struct GNUNET_MESSENGER_Message *message = get_store_message (get_room_message_store(room), hash);
701 
702  if ((message) || (!handle) || (GNUNET_YES != request))
703  return message;
704 
705  struct GNUNET_MESSENGER_OperationStore* operation_store = get_room_operation_store(room);
706 
708  send_room_message (room, handle, create_message_request (hash));
709 
710  return NULL;
711 }
712 
713 void
715 {
716  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
717 
718  if (!room->host)
719  return;
720 
721  struct GNUNET_PeerIdentity identity;
722  get_tunnel_peer_identity(tunnel, &identity);
723 
724  if ((GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove (room->tunnels, &identity, tunnel)) ||
726  return;
727 
728  if (GNUNET_YES == contains_list_tunnels (&(room->basement), &identity))
729  send_room_message (room, room->host, create_message_miss (&identity));
730 }
731 
732 int
734  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
735 {
736  if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind)
737  {
738  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Kind is unknown! (%d)\n", message->header.kind);
739  return GNUNET_SYSERR;
740  }
741 
742  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n",
744 
745  return GNUNET_OK;
746 }
747 
748 static void
750 {
751  struct GNUNET_MESSENGER_SrvRoom *room = cls;
752 
753  room->idle = NULL;
754 
755  struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
756 
757  if ((room->last_messages.head != room->last_messages.tail) &&
760  operation_store,
761  &(room->last_messages.tail->hash),
764  );
765 
770  cls
771  );
772 }
773 
774 void
776 {
777  GNUNET_assert(room);
778 
779  struct GNUNET_PeerIdentity peer;
780  size_t src;
781 
782  if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) ||
783  (!find_list_tunnels (&(room->basement), &peer, &src)))
784  return;
785 
786  size_t count = count_of_tunnels (&(room->basement));
787 
788  struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head;
789  struct GNUNET_MESSENGER_SrvTunnel *tunnel;
790 
791  size_t dst = 0;
792 
793  while (element)
794  {
795  GNUNET_PEER_resolve (element->peer, &peer);
796 
797  tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, &peer);
798 
799  if (!tunnel)
800  {
801  element = remove_from_list_tunnels (&(room->basement), element);
802  continue;
803  }
804 
805  if (GNUNET_YES == required_connection_between (count, src, dst))
806  {
807  if (GNUNET_SYSERR == connect_tunnel (tunnel))
808  {
809  element = remove_from_list_tunnels (&(room->basement), element);
810  continue;
811  }
812  }
813  else
814  disconnect_tunnel (tunnel);
815 
816  element = element->next;
817  dst++;
818  }
819 }
820 
821 static void
823 {
824  while (room->handling.head)
825  {
826  struct GNUNET_MESSENGER_ListMessage *element = room->handling.head;
827 
828  const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(element->hash), GNUNET_NO);
829 
830  if (!msg)
831  goto finish_handling;
832 
833  struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
834  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, msg);
835 
836  if (!member)
837  goto finish_handling;
838 
839  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, msg, &(element->hash));
840 
841  if (session)
842  handle_service_message (room->service, room, session, msg, &(element->hash));
843 
844 finish_handling:
845  GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element);
846  GNUNET_free(element);
847  }
848 }
849 
850 static void
852 {
854 
855  struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
856 
857  if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, hash))
858  cancel_store_operation(operation_store, hash);
859 }
860 
861 int
863  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
864 {
865  GNUNET_assert((room) && (message) && (hash));
866 
867  struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room);
868 
869  const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)?
871  );
872 
873  if (GNUNET_YES == requested)
874  cancel_store_operation(operation_store, hash);
875 
876  const struct GNUNET_MESSENGER_Message *old_message = get_room_message (room, NULL, hash, GNUNET_NO);
877 
878  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", GNUNET_h2s (get_room_key(room)));
879 
880  if ((old_message) || (GNUNET_OK != put_store_message (get_room_message_store(room), hash, message)))
881  {
882  if (old_message != message)
883  destroy_message(message);
884 
885  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Duplicate message got dropped!\n");
886  return GNUNET_NO;
887  }
888 
889  if ((GNUNET_YES == requested) ||
890  (GNUNET_MESSENGER_KIND_INFO == message->header.kind) ||
892  return GNUNET_YES;
893 
894  if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind)
895  remove_room_last_message(room, &(message->body.merge.previous));
896  remove_room_last_message(room, &(message->header.previous));
897 
898  add_to_list_messages (&(room->last_messages), hash);
899 
900  return GNUNET_YES;
901 }
902 
904 {
907 
909 };
910 
912 {
914  const struct GNUNET_HashCode *hash;
915 
918 };
919 
920 static int
921 iterate_update_member_sessions (void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key,
923 {
924  struct GNUNET_MESSENGER_MemberUpdate *update = cls;
925 
926  update_member_session_history(session, update->message, update->hash);
927 
928  if (GNUNET_YES == is_member_session_completed(session))
929  {
932  );
933 
934  element->session = session;
935 
936  GNUNET_CONTAINER_DLL_insert_tail(update->head, update->tail, element);
937  }
938 
939  return GNUNET_YES;
940 }
941 
942 void
944  const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
945 {
946  struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room);
947  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
948 
949  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Callback for message (%s)\n", GNUNET_h2s (hash));
950 
951  if (!member)
952  {
953  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Member is missing!\n");
954  return;
955  }
956 
957  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash);
958 
959  if (!session)
960  {
961  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Session is missing!\n");
962  return;
963  }
964 
965  struct GNUNET_MESSENGER_MemberUpdate update;
966  update.message = message;
967  update.hash = hash;
968 
969  update.head = NULL;
970  update.tail = NULL;
971 
973 
974  while (update.head)
975  {
976  struct GNUNET_MESSENGER_MemberSessionCompletion *element = update.head;
977 
978  remove_member_session (element->session->member, element->session);
979 
980  GNUNET_CONTAINER_DLL_remove(update.head, update.tail, element);
981  GNUNET_free (element);
982  }
983 
984  const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES;
985 
986  add_to_list_messages (&(room->handling), hash);
987 
988  switch (message->header.kind)
989  {
991  handle_message_join (room, session, message, hash);
992  break;
994  handle_message_leave (room, session, message, hash);
995  break;
997  handle_message_name (room, session, message, hash);
998  break;
1000  handle_message_key (room, session, message, hash);
1001  break;
1003  handle_message_peer (room, session, message, hash);
1004  break;
1006  handle_message_id (room, session, message, hash);
1007  break;
1009  handle_message_miss (room, session, message, hash);
1010  break;
1012  handle_message_delete (room, session, message, hash);
1013  break;
1014  default:
1015  break;
1016  }
1017 
1018  if (GNUNET_YES == start_handle)
1019  handle_room_messages (room);
1020 }
1021 
1022 static void
1024 {
1025  GNUNET_assert((room) && (dir));
1026 
1027  GNUNET_asprintf (dir, "%s%s%c%s%c", room->service->dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (get_room_key(room)), DIR_SEPARATOR);
1028 }
1029 
1030 void
1032 {
1033  GNUNET_assert(room);
1034 
1035  char *room_dir;
1036  get_room_data_subdir (room, &room_dir);
1037 
1039  {
1040  load_member_store (get_room_member_store(room), room_dir);
1041  load_message_store (get_room_message_store(room), room_dir);
1043 
1044  char *basement_file;
1045  GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
1046 
1047  load_list_tunnels(&(room->basement), basement_file);
1048  GNUNET_free(basement_file);
1049 
1050  char *last_messages_file;
1051  GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list");
1052 
1053  load_list_messages(&(room->last_messages), last_messages_file);
1054  GNUNET_free(last_messages_file);
1055  }
1056 
1057  GNUNET_free(room_dir);
1058 }
1059 
1060 void
1062 {
1063  GNUNET_assert(room);
1064 
1065  char *room_dir;
1066  get_room_data_subdir (room, &room_dir);
1067 
1068  if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) ||
1069  (GNUNET_OK == GNUNET_DISK_directory_create (room_dir)))
1070  {
1071  save_member_store(get_room_member_store(room), room_dir);
1072  save_message_store (get_room_message_store(room), room_dir);
1074 
1075  char *basement_file;
1076  GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list");
1077 
1078  save_list_tunnels(&(room->basement), basement_file);
1079  GNUNET_free(basement_file);
1080 
1081  char *last_messages_file;
1082  GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list");
1083 
1084  save_list_messages(&(room->last_messages), last_messages_file);
1085  GNUNET_free(last_messages_file);
1086  }
1087 
1088  GNUNET_free(room_dir);
1089 }
#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.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
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. ...
struct GNUNET_MESSENGER_MessageHeader header
Header.
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.
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
struct GNUNET_MESSENGER_MemberStore member_store
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
void save_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...
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_MESSENGER_MessageStore * get_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
struct GNUNET_MESSENGER_MemberSession * session
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
#define GNUNET_MESSENGER_MERGE_DELAY
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
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 delayed_disconnect_channel(struct GNUNET_CADET_Channel *channel)
Starts an urgent task to close a CADET channel asynchronously.
static void idle_request_room_messages(void *cls)
struct GNUNET_TIME_AbsoluteNBO timestamp
The timestamp of the message.
GNUnet MESSENGER service.
struct GNUNET_MESSENGER_MessageStore message_store
struct GNUNET_CADET_Handle * cadet
struct GNUNET_MESSENGER_ListMessage * head
GNUnet MESSENGER service.
static void remove_room_last_message(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
void save_message_store(struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
Saves messages from a message store into a directory.
Opaque handle to the service.
Definition: cadet_api.c:38
static int join_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Member *member)
struct GNUNET_MESSENGER_MemberSession * session
void check_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...
static int iterate_notify_about_members(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
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)
static void * callback_room_connect(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
int is_message_session_bound(const struct GNUNET_MESSENGER_Message *message)
Returns if the message should be bound to a member session.
GNUnet MESSENGER service.
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.
int callback_verify_room_message(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
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.
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.
static void merge_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *hash)
int is_member_session_closed(const struct GNUNET_MESSENGER_MemberSession *session)
Returns if the given member session has been closed.
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 ...
struct GNUNET_MESSENGER_ListTunnel * head
int is_member_session_completed(const struct GNUNET_MESSENGER_MemberSession *session)
Returns if the given member session has been completed.
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_SrvRoom * room
int delete_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Deletes a message in the message store.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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 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.
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.
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.
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
struct GNUNET_MESSENGER_ListTunnel * next
int send_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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_MESSAGE_TYPE_CADET_CLI
Traffic (net-cat style) used by the Command Line Interface.
#define GNUNET_MESSENGER_VERSION
Version number of GNUnet Messenger API.
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...
struct GNUNET_CADET_Port * port
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
int 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 and returns GNUNET_OK...
static int iterate_destroy_tunnels(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
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
struct GNUNET_CADET_Handle * get_room_cadet(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the CADET handle from a rooms service.
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.
const struct GNUNET_MESSENGER_SrvTunnel * get_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, otherwise NULL.
struct GNUNET_MESSENGER_MemberStore * get_room_member_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used member store of a given room.
A 256-bit hashcode.
void callback_room_disconnect(struct GNUNET_MESSENGER_SrvRoom *room, void *cls)
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.
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 save_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Saves members from a member store into a directory.
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 ...
struct GNUNET_MESSENGER_OperationStore operation_store
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)
void callback_room_deletion(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
struct GNUNET_MESSENGER_OperationStore * get_room_operation_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used operation store of a given room.
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
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. ...
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_IDENTITY_PublicKey pub
struct GNUNET_MESSENGER_SrvRoom * room
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_forever_(void)
Return "forever".
Definition: time.c:219
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_HashCode * peer_message
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.
void load_message_store(struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
Loads messages from a directory into a message store.
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...
int check_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
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.
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we&#39;ve connected to it).
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...
GNUnet MESSENGER service.
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_MQ_Envelope * pack_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.
const char * GNUNET_MESSENGER_name_of_kind(enum GNUNET_MESSENGER_MessageKind kind)
Get the name of a message kind.
Definition: messenger_api.c:35
void load_list_messages(struct GNUNET_MESSENGER_ListMessages *messages, const char *path)
Loads the list of message hashes from a file under a given path.
struct GNUNET_MESSENGER_SrvRoom * room
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 (called door).
struct GNUNET_MESSENGER_Message * message
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:476
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...
void clear_operation_store(struct GNUNET_MESSENGER_OperationStore *store)
Clears an operation store, stops all operations and deallocates its memory.
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.
#define GNUNET_MESSENGER_IDLE_DELAY
struct GNUNET_MESSENGER_MessageMerge merge
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.
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 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...
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.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
void clear_member_store(struct GNUNET_MESSENGER_MemberStore *store)
Clears a member store, wipes its content and deallocates its memory.
enum GNUNET_MESSENGER_OperationType get_store_operation_type(const struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash)
Retruns the type of the active operation under a given hash in a specific operation store...
messenger api: client implementation of GNUnet MESSENGER service
Run when otherwise idle.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
void notify_handle_message(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, 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.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
#define DIR_SEPARATOR
Definition: platform.h:170
void handle_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
#define GNUNET_MESSENGER_REQUEST_DELAY
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_MESSENGER_SrvHandle * host
GNUnet MESSENGER service.
GNUnet MESSENGER service.
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 remove_from_list_messages(struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash)
Removes the first entry with a matching hash from the list.
struct GNUNET_MESSENGER_ListMessages messages
int delete_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_MESSENGER_Message * create_message_join(const struct GNUNET_MESSENGER_Ego *ego)
Creates and allocates a new join message containing the clients EGO public key.
#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_MESSENGER_Message * create_message_miss(const struct GNUNET_PeerIdentity *peer)
Creates and allocates a new miss message containing the missing peer identity.
static int iterate_update_member_sessions(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
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
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
const struct GNUNET_HashCode * hash
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.
void clear_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Clears the list of message hashes.
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.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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 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 remove_member_session(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_MemberSession *session)
Removes a given member session from its member.
void save_operation_store(const struct GNUNET_MESSENGER_OperationStore *store, const char *directory)
Saves operations from an operation store into a directory.
const struct GNUNET_MESSENGER_Message * message
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.
Allow multiple values with the same 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.
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.
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_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.
int enter_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...
The identity of the host (wraps the signing key of the peer).
struct GNUNET_MESSENGER_MemberSessionCompletion * tail
An identity key as per LSD0001.
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 init_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels)
Initializes list of tunnels peer identities as empty list.
void save_list_messages(struct GNUNET_MESSENGER_ListMessages *messages, const char *path)
Saves the list of message hashes to a file under a given path.
void callback_room_merge(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash)
struct GNUNET_MESSENGER_MemberSessionCompletion * next
struct GNUNET_MESSENGER_ListTunnels basement
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.
#define GNUNET_log(kind,...)
void load_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Loads members from a directory into a member store.
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 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...
const struct GNUNET_HashCode * get_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
void load_operation_store(struct GNUNET_MESSENGER_OperationStore *store, const char *directory)
Loads operations from a directory into an operation store.
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.
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.
struct GNUNET_MESSENGER_MemberSessionCompletion * head
struct GNUNET_MESSENGER_SrvTunnel * exclude
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.
struct GNUNET_MESSENGER_SrvHandle * handle
static void get_room_data_subdir(struct GNUNET_MESSENGER_SrvRoom *room, char **dir)
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_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.
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...
static void handle_room_messages(struct GNUNET_MESSENGER_SrvRoom *room)
struct GNUNET_CONTAINER_MultiPeerMap * tunnels
int 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)...
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
const struct GNUNET_ShortHashCode * get_member_id(const struct GNUNET_MESSENGER_Member *member)
Returns the current id of a given member.
void load_room(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_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...
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.
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
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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...
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.
struct GNUNET_MESSENGER_MemberSessionCompletion * prev
const struct GNUNET_MESSENGER_Ego * get_handle_ego(const struct GNUNET_MESSENGER_SrvHandle *handle)
Returns the EGO used by a given handle.
GNUnet MESSENGER service.
void forward_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.
const struct GNUNET_ShortHashCode * get_member_session_id(const struct GNUNET_MESSENGER_MemberSession *session)
Returns the member id of a given member session.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
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 * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972