GNUnet 0.21.2
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--2024 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
31
32static void
34 struct GNUNET_MESSENGER_SrvTunnel *tunnel,
35 struct GNUNET_MESSENGER_MemberSession *session,
37{
38 if (session->prev)
39 forward_about_members (room, tunnel, session->prev, map);
40
41 struct GNUNET_MESSENGER_MessageStore *message_store =
43 struct GNUNET_MESSENGER_ListMessage *element;
44
45 for (element = session->messages.head; element; element = element->next)
46 {
48 &(element->hash)))
49 continue;
50
52 NULL,
54
56 "Forwarding of session message could be duplicated!\n");
57
58 const struct GNUNET_MESSENGER_Message *message = get_store_message (
59 message_store, &(element->hash));
60
61 if (message)
62 forward_tunnel_message (tunnel, message, &(element->hash));
63 }
64}
65
66
69 const struct GNUNET_CRYPTO_PublicKey *public_key,
70 struct GNUNET_MESSENGER_MemberSession *session)
71{
72 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
73
75 return GNUNET_YES;
76
79
80 forward_about_members (tunnel->room, tunnel, session, map);
81
83 return GNUNET_YES;
84}
85
86
89 struct GNUNET_MESSENGER_SrvTunnel *tunnel,
90 const struct GNUNET_MESSENGER_Message *message,
91 const struct GNUNET_HashCode *hash)
92{
93 const uint32_t version = get_tunnel_messenger_version (tunnel);
94
96 message->body.info.
97 messenger_version))
98 {
99 disconnect_tunnel (tunnel);
100 return GNUNET_NO;
101 }
102
103 if (version == get_tunnel_messenger_version (tunnel))
104 return GNUNET_NO;
105
106 if (room->host)
108 room->service));
109
110 struct GNUNET_PeerIdentity peer;
111 get_tunnel_peer_identity (tunnel, &peer);
112
113 if (GNUNET_YES != contains_list_tunnels (&(room->basement), &peer))
114 {
115 struct GNUNET_MESSENGER_MessageStore *message_store =
117
118 struct GNUNET_MESSENGER_ListTunnel *element;
119 for (element = room->basement.head; element; element = element->next)
120 {
121 if (! element->hash)
122 continue;
123
124 const struct GNUNET_MESSENGER_Message *message = get_store_message (
125 message_store, element->hash);
126
127 if (message)
128 forward_tunnel_message (tunnel, message, element->hash);
129 }
130 }
131
132 if (GNUNET_YES != contains_list_tunnels (&(room->basement), &peer))
133 {
134 struct GNUNET_MESSENGER_MemberStore *member_store =
136
137 iterate_store_members (member_store, iterate_forward_members, tunnel);
138 }
139
141 return GNUNET_NO;
142}
143
144
147 struct GNUNET_MESSENGER_SrvTunnel *tunnel,
148 const struct GNUNET_MESSENGER_Message *message,
149 const struct GNUNET_HashCode *hash)
150{
151 struct GNUNET_PeerIdentity peer;
152 GNUNET_PEER_resolve (tunnel->peer, &peer);
153
154 if (0 == GNUNET_memcmp (&peer, &(message->body.peer.peer)))
155 {
156 if (! tunnel->peer_message)
157 tunnel->peer_message = GNUNET_new (struct GNUNET_HashCode);
158
159 GNUNET_memcpy (tunnel->peer_message, &hash, sizeof(hash));
160 }
161
162 update_to_list_tunnels (&(room->basement), &(message->body.peer.peer), hash);
163 return GNUNET_YES;
164}
165
166
169 struct GNUNET_MESSENGER_SrvTunnel *tunnel,
170 const struct GNUNET_MESSENGER_Message *message,
171 const struct GNUNET_HashCode *hash)
172{
174
175 if ((GNUNET_YES == service->auto_routing) &&
176 (service->min_routers > count_of_tunnels (&(room->basement))))
177 open_srv_room (room, NULL);
178
179 return GNUNET_YES;
180}
181
182
183static void
185 struct GNUNET_MESSENGER_SrvRoom *room,
186 const struct GNUNET_MESSENGER_Message *message,
187 const struct GNUNET_HashCode *hash)
188{
189 struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
190
191 if (! message)
192 {
193 struct GNUNET_MESSENGER_OperationStore *operation_store =
195
197 operation_store,
198 hash,
201 );
202 }
203 else
204 forward_tunnel_message (tunnel, message, hash);
205}
206
207
208/*
209 * Function returns GNUNET_NO to drop forwarding the request.
210 * It will only be forwarded if it can't be answered!
211 */
214 struct GNUNET_MESSENGER_SrvTunnel *tunnel,
215 const struct GNUNET_MESSENGER_Message *message,
216 const struct GNUNET_HashCode *hash)
217{
218 struct GNUNET_MESSENGER_MemberStore *member_store =
220 struct GNUNET_MESSENGER_Member *member = get_store_member_of (member_store,
221 message);
222
223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request for message (%s)\n",
224 GNUNET_h2s (hash));
225
226 if (! member)
227 return GNUNET_NO;
228
230 member, message, hash);
231
232 if ((! session) || (GNUNET_YES != check_member_session_history (session,
233 &(message->
234 body.request
235 .hash),
236 GNUNET_NO)))
237 return GNUNET_NO;
238
240 &(message->body.request.hash),
241 session, callback_found_message,
242 tunnel))
243 return GNUNET_YES;
244
245 return GNUNET_NO;
246}
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
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_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...
enum GNUNET_GenericReturnValue check_member_session_history(const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue ownership)
Checks the history of a session for a specific message which is identified by its hash and if the own...
enum GNUNET_GenericReturnValue is_member_session_completed(const struct GNUNET_MESSENGER_MemberSession *session)
Returns if the given member session has been completed.
struct GNUNET_MESSENGER_Member * get_store_member_of(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_MESSENGER_Message *message)
Returns the member of a store using a sender id of a given message.
int iterate_store_members(struct GNUNET_MESSENGER_MemberStore *store, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to the members of the given member store and ...
struct GNUNET_MESSENGER_Message * create_message_info(struct GNUNET_MESSENGER_Service *service)
Creates and allocates a new info message containing the hosts service peer identity and version.
enum GNUNET_GenericReturnValue recv_message_request(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, const 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...
enum GNUNET_GenericReturnValue recv_message_miss(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a received miss message to react to activity in the basement of a room.
static void callback_found_message(void *cls, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
static void forward_about_members(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_MemberSession *session, struct GNUNET_CONTAINER_MultiHashMap *map)
enum GNUNET_GenericReturnValue recv_message_info(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, const 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...
enum GNUNET_GenericReturnValue recv_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, const 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.
static enum GNUNET_GenericReturnValue iterate_forward_members(void *cls, const struct GNUNET_CRYPTO_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
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.
enum GNUNET_GenericReturnValue 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.
struct GNUNET_MESSENGER_MessageStore * get_srv_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
void check_srv_room_peer_status(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Checks the current state of opening a given room from this peer and re-publishes it if necessary to a...
enum GNUNET_GenericReturnValue open_srv_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
Tries to open a room for a given handle.
enum GNUNET_GenericReturnValue request_srv_room_message(struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_MemberSession *session, GNUNET_MESSENGER_MessageRequestCallback callback, void *cls)
Requests a message from a room identified by a given hash.
struct GNUNET_MESSENGER_OperationStore * get_srv_room_operation_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used operation store of a given room.
struct GNUNET_MESSENGER_MemberStore * get_srv_room_member_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used member store of a given room.
#define GNUNET_MESSENGER_REQUEST_DELAY
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.
enum GNUNET_GenericReturnValue update_tunnel_messenger_version(struct GNUNET_MESSENGER_SrvTunnel *tunnel, uint32_t version)
Updates the messenger version of the tunnel to a given version if it is compatible to the running pee...
uint32_t get_tunnel_messenger_version(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the current messenger version the peer connected via a given tunnel has reported to be using ...
void get_tunnel_peer_identity(const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer)
Writes the peer identity of the peer connected via tunnel to this peer into the peer parameter.
void disconnect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Disconnects and unbinds a channel from a tunnel.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_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.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition: peer.c:220
void update_to_list_tunnels(struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HashCode *hash)
Updates a specific peer from a tunnel in the list.
enum GNUNET_GenericReturnValue 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...
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition: peer.c:63
Internal representation of the hash map.
An identity key as per LSD0001.
A 512-bit hashcode.
struct GNUNET_MESSENGER_ListMessage * next
struct GNUNET_MESSENGER_ListMessage * head
struct GNUNET_MESSENGER_ListTunnel * next
struct GNUNET_MESSENGER_ListTunnel * head
struct GNUNET_MESSENGER_MemberSession * prev
struct GNUNET_MESSENGER_ListMessages messages
struct GNUNET_MESSENGER_MessageRequest request
struct GNUNET_MESSENGER_MessagePeer peer
struct GNUNET_MESSENGER_MessageInfo info
struct GNUNET_PeerIdentity peer
The peer identity of the sender opening a room.
struct GNUNET_HashCode hash
The hash of the requested message.
struct GNUNET_MESSENGER_MessageBody body
Body.
struct GNUNET_MESSENGER_Service * service
struct GNUNET_MESSENGER_ListTunnels basement
struct GNUNET_MESSENGER_SrvHandle * host
struct GNUNET_MESSENGER_SrvRoom * room
The identity of the host (wraps the signing key of the peer).