GNUnet  0.11.x
gnunet-service-messenger_message_recv.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  */
28 
29 void
31  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
32 {
33  int conflict = GNUNET_CONTAINER_multishortmap_contains (room->members, &(message->body.info.unique_id));
34 
35  if (GNUNET_NO == conflict)
36  {
37  struct GNUNET_MESSENGER_Message *sync_message = create_message_id (&(message->body.info.unique_id));
38  struct GNUNET_HashCode sync_hash;
39 
40  send_room_message_ext (room, room->host, sync_message, &sync_hash, tunnel);
41  destroy_message (sync_message);
42 
43  switch_room_member_id (room, get_room_host_id (room), &(message->body.info.unique_id), NULL);
44 
45  change_room_host_id (room, &(message->body.info.unique_id));
46  }
47 
48  if (!tunnel->contact_id)
49  tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
50 
51  GNUNET_memcpy(tunnel->contact_id, &(message->header.sender_id), sizeof(struct GNUNET_ShortHashCode));
52 
53  struct GNUNET_ShortHashCode original_id;
54 
55  if (GNUNET_YES == conflict)
56  {
57  GNUNET_memcpy(&original_id, get_room_host_id (room), sizeof(struct GNUNET_ShortHashCode));
58 
59  change_room_host_id (room, &(message->body.info.unique_id));
60  }
61 
62  {
63  struct GNUNET_MESSENGER_Message *join_message = create_message_join (room->host->ego);
64  struct GNUNET_HashCode join_hash;
65 
66  send_tunnel_message (tunnel, room->host, join_message, &join_hash);
67  destroy_message (join_message);
68  }
69 
70  if ((GNUNET_YES == conflict) && (0 != GNUNET_memcmp(&original_id, get_room_host_id (room))))
71  {
72  struct GNUNET_MESSENGER_Message *sync_message = create_message_id (&original_id);
73  struct GNUNET_HashCode sync_hash;
74 
75  send_tunnel_message (tunnel, room->host, sync_message, &sync_hash);
76  destroy_message (sync_message);
77  }
78 }
79 
81 {
84 };
85 
86 static int
87 iterate_send_member_infos (void *cls, const struct GNUNET_ShortHashCode *key, void *value)
88 {
89  struct GNUNET_MESSENGER_MemberInfo *info = value;
90  struct GNUNET_MESSENGER_MemberInfoSpread *spread = cls;
91 
92  struct GNUNET_MESSENGER_ListMessage *element = info->session_messages.head;
93 
94  while (element)
95  {
96  const struct GNUNET_MESSENGER_Message *message = get_room_message (spread->room, spread->room->host,
97  &(element->hash), GNUNET_NO);
98 
99  if (message)
100  forward_tunnel_message (spread->tunnel, message, &(element->hash));
101 
102  element = element->next;
103  }
104 
105  return GNUNET_YES;
106 }
107 
108 void
110  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
111 {
112  const struct GNUNET_MESSENGER_Message *info_msg = get_room_message (room, room->host, &(message->header.previous),
113  GNUNET_NO);
114 
115  if ((info_msg) && (0 == GNUNET_memcmp(&(info_msg->header.sender_id), get_room_host_id (room)))
116  && (GNUNET_MESSENGER_KIND_INFO == info_msg->header.kind))
117  {
118  struct GNUNET_MESSENGER_MemberInfoSpread spread;
119 
120  spread.room = room;
121 
122  if ((tunnel) && (tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, &(message->header.sender_id))))
123  spread.tunnel = tunnel;
124  else
125  spread.tunnel = find_room_tunnel_to (room, &(message->header.sender_id));
126 
127  if (spread.tunnel)
129  }
130 
131  handle_message_join (room, tunnel, message, hash);
132 }
133 
134 void
136  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
137 {
138  handle_message_leave (room, tunnel, message, hash);
139 }
140 
141 void
143  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
144 {
145  handle_message_name (room, tunnel, message, hash);
146 }
147 
148 void
150  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
151 {
152  handle_message_key (room, tunnel, message, hash);
153 }
154 
155 void
157  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
158 {
159  struct GNUNET_PeerIdentity peer;
160  GNUNET_PEER_resolve (tunnel->peer, &peer);
161 
162  if (0 == GNUNET_memcmp(&peer, &(message->body.peer.peer)))
163  {
164  if (!tunnel->peer_message)
165  tunnel->peer_message = GNUNET_new(struct GNUNET_HashCode);
166 
167  GNUNET_memcpy(tunnel->peer_message, hash, sizeof(struct GNUNET_HashCode));
168 
169  if (!tunnel->contact_id)
170  tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
171 
172  GNUNET_memcpy(tunnel->contact_id, &(message->header.sender_id), sizeof(struct GNUNET_ShortHashCode));
173  }
174 
175  handle_message_peer (room, tunnel, message, hash);
176 }
177 
178 void
180  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
181 {
182  if ((tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, &(message->header.sender_id))))
183  GNUNET_memcpy(tunnel->contact_id, &(message->body.id.id), sizeof(struct GNUNET_ShortHashCode));
184 
185  handle_message_id (room, tunnel, message, hash);
186 }
187 
188 void
190  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
191 {
192  handle_message_miss (room, tunnel, message, hash);
193 }
194 
195 void
197  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
198 {
199  const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(message->body.request.hash),
200  GNUNET_NO);
201 
202  if (msg)
203  forward_tunnel_message (tunnel, msg, &(message->body.request.hash));
204 }
struct GNUNET_PeerIdentity peer
The peer identity of the sender opening a room.
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.
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
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...
void handle_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 or sent id message to change a members id.
struct GNUNET_MESSENGER_ListMessage * head
struct GNUNET_ShortHashCode unique_id
The new unique id for the receiver in a room.
void handle_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 or sent miss message to drop a peer from the basement in the room.
GNUnet MESSENGER service.
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 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...
struct GNUNET_ShortHashCode id
The new id which will replace the senders id in a room.
struct GNUNET_HashCode hash
The hash of the requested message.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void handle_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 or sent name message to rename a current member.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void handle_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 or sent peer message to make changes of the basement in the room.
struct GNUNET_CONTAINER_MultiShortmap * member_infos
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 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...
A 256-bit hashcode.
struct GNUNET_MESSENGER_Ego * ego
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_MESSENGER_MessageRequest request
static int iterate_send_member_infos(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
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_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 handle_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 or sent key message to change the key of a member and rearrange the contacts accor...
struct GNUNET_MESSENGER_Message * create_message_id(const struct GNUNET_ShortHashCode *unique_id)
Creates and allocates a new id message containing the unique member id to change to.
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...
A 512-bit hashcode.
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...
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.
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_MESSENGER_SrvHandle * host
struct GNUNET_CONTAINER_MultiShortmap * members
struct GNUNET_MESSENGER_MessageInfo info
struct GNUNET_MESSENGER_MessagePeer peer
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.
#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 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 forward_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Forwards a given message with a known hash through a tunnel.
void handle_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 or sent join message to make changes of current member information.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_MESSENGER_ListMessages session_messages
void handle_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 or sent leave message to make changes of current member information.
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...
struct GNUNET_ShortHashCode * contact_id
int GNUNET_CONTAINER_multishortmap_contains(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
struct GNUNET_MESSENGER_MessageId id
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.
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...
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.