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--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 
29 
30 static void
32  struct GNUNET_MESSENGER_SrvTunnel *tunnel,
33  struct GNUNET_MESSENGER_MemberSession *session,
35 {
36  if (session->prev)
37  forward_about_members (room, tunnel, session->prev, map);
38 
39  struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room);
40  struct GNUNET_MESSENGER_ListMessage *element;
41 
42  for (element = session->messages.head; element; element = element->next)
43  {
45  continue;
46 
47  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), NULL,
49  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Forwarding of session message could be duplicated!\n");
50 
51  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, &(element->hash));
52 
53  if (message)
54  forward_tunnel_message(tunnel, message, &(element->hash));
55  }
56 }
57 
58 static int
60  const struct GNUNET_IDENTITY_PublicKey *public_key,
61  struct GNUNET_MESSENGER_MemberSession *session)
62 {
63  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
64 
66  return GNUNET_YES;
67 
69 
70  forward_about_members (tunnel->room, tunnel, session, map);
71 
73  return GNUNET_YES;
74 }
75 
76 int
78  struct GNUNET_MESSENGER_SrvTunnel *tunnel,
79  const struct GNUNET_MESSENGER_Message *message,
80  const struct GNUNET_HashCode *hash)
81 {
82  const uint32_t version = get_tunnel_messenger_version(tunnel);
83 
85  {
86  disconnect_tunnel(tunnel);
87  return GNUNET_NO;
88  }
89 
90  if (version == get_tunnel_messenger_version(tunnel))
91  return GNUNET_NO;
92 
93  if (room->host)
94  {
95  const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(room->host);
96 
97  send_tunnel_message (tunnel, room->host, create_message_info(ego));
98  }
99 
100  struct GNUNET_PeerIdentity peer;
101  get_tunnel_peer_identity(tunnel, &peer);
102 
103  if (GNUNET_YES != contains_list_tunnels(&(room->basement), &peer))
104  {
106 
107  iterate_store_members(member_store, iterate_forward_members, tunnel);
108  }
109 
110  check_room_peer_status(room, tunnel);
111 
112  return GNUNET_NO;
113 }
114 
115 int
117  struct GNUNET_MESSENGER_SrvTunnel *tunnel,
118  const struct GNUNET_MESSENGER_Message *message,
119  const struct GNUNET_HashCode *hash)
120 {
121  struct GNUNET_PeerIdentity peer;
122  GNUNET_PEER_resolve (tunnel->peer, &peer);
123 
124  if (0 == GNUNET_memcmp(&peer, &(message->body.peer.peer)))
125  {
126  if (!tunnel->peer_message)
127  tunnel->peer_message = GNUNET_new(struct GNUNET_HashCode);
128 
129  GNUNET_memcpy(tunnel->peer_message, &hash, sizeof(hash));
130  }
131 
132  return GNUNET_YES;
133 }
134 
135 static void
137  struct GNUNET_MESSENGER_SrvRoom *room,
138  const struct GNUNET_MESSENGER_Message *message,
139  const struct GNUNET_HashCode *hash)
140 {
141  struct GNUNET_MESSENGER_SrvTunnel *tunnel = tunnel;
142 
143  if (!message)
144  {
146 
148  operation_store,
149  hash,
152  );
153  }
154  else
155  forward_tunnel_message (tunnel, message, hash);
156 }
157 
158 /*
159  * Function returns GNUNET_NO to drop forwarding the request.
160  * It will only be forwarded if it can't be answered!
161  */
162 int
164  struct GNUNET_MESSENGER_SrvTunnel *tunnel,
165  const struct GNUNET_MESSENGER_Message *message,
166  const struct GNUNET_HashCode *hash)
167 {
169  struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message);
170 
171  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Request for message (%s)\n", GNUNET_h2s (hash));
172 
173  if (!member)
174  return GNUNET_NO;
175 
176  struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash);
177 
178  if ((!session) || (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO)))
179  return GNUNET_NO;
180 
181  if (GNUNET_NO == request_room_message(room, &(message->body.request.hash), session, callback_found_message, tunnel))
182  return GNUNET_YES;
183 
184  return GNUNET_NO;
185 }
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
const struct GNUNET_MESSENGER_Ego * get_handle_ego(const struct GNUNET_MESSENGER_SrvHandle *handle)
Returns the EGO used by a given handle.
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...
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...
int 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(const struct GNUNET_MESSENGER_Ego *ego)
Creates and allocates a new info message containing the hosts EGO public key and a newly generated un...
static int iterate_forward_members(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
int 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 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)
int 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...
int 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...
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.
GNUnet MESSENGER service.
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.
struct GNUNET_MESSENGER_OperationStore * get_room_operation_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used operation store of a given room.
int request_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_MessageStore * get_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
struct GNUNET_MESSENGER_MemberStore * get_room_member_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used member store of a given room.
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...
#define GNUNET_MESSENGER_REQUEST_DELAY
int send_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message)
Sends a message by packing it automatically into an envelope and passing it through the tunnel.
void forward_tunnel_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Forwards a given message with a known hash through a tunnel.
int 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.
#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_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
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).
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
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:225
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...
Internal representation of the hash map.
A 512-bit hashcode.
An identity key as per LSD0001.
struct GNUNET_MESSENGER_ListMessage * next
struct GNUNET_MESSENGER_ListMessage * 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
uint32_t messenger_version
The version of GNUnet Messenger API.
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_ListTunnels basement
struct GNUNET_MESSENGER_SrvHandle * host
struct GNUNET_MESSENGER_SrvRoom * room
The identity of the host (wraps the signing key of the peer).
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.