GNUnet  0.19.2
gnunet-service-messenger_tunnel.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020--2022 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  */
26 #include "platform.h"
28 
34 #include "messenger_api_util.h"
35 
38  const struct GNUNET_PeerIdentity *door)
39 {
40  GNUNET_assert((room) && (door));
41 
43 
44  tunnel->room = room;
45  tunnel->channel = NULL;
46 
47  tunnel->peer = GNUNET_PEER_intern (door);
48 
49  tunnel->messenger_version = 0;
50 
51  tunnel->peer_message = NULL;
52 
53  init_message_state(&(tunnel->state));
54 
55  return tunnel;
56 }
57 
58 void
60 {
61  GNUNET_assert(tunnel);
62 
63  if (tunnel->channel)
65 
66  GNUNET_PEER_change_rc (tunnel->peer, -1);
67 
68  if (tunnel->peer_message)
69  GNUNET_free(tunnel->peer_message);
70 
71  clear_message_state(&(tunnel->state));
72 
73  GNUNET_free(tunnel);
74 }
75 
76 void
79 {
80  GNUNET_assert(tunnel);
81 
82  if (tunnel->channel)
84 
85  tunnel->channel = channel;
86 }
87 
88 extern void
90  void *cls);
91 
92 void
94  const struct GNUNET_CADET_Channel *channel)
95 {
96  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
97 
98  if (tunnel)
99  {
100  tunnel->channel = NULL;
101 
102  callback_room_disconnect (tunnel->room, cls);
103  }
104 }
105 
106 extern int
108  void *cls,
109  struct GNUNET_MESSENGER_Message *message,
110  struct GNUNET_HashCode *hash);
111 
112 int
114  const struct GNUNET_MessageHeader *header)
115 {
116  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
117 
118  if (!tunnel)
119  return GNUNET_SYSERR;
120 
121  const uint16_t length = ntohs (header->size) - sizeof(*header);
122  const char *buffer = (const char*) &header[1];
123 
124  struct GNUNET_MESSENGER_Message message;
125 
127  {
128  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length);
129  return GNUNET_SYSERR;
130  }
131 
132  uint16_t padding = 0;
133 
134  if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding))
135  {
136  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n");
137  return GNUNET_SYSERR;
138  }
139 
140  struct GNUNET_HashCode hash;
141  hash_message (&message, length - padding, buffer, &hash);
142 
143  return callback_verify_room_message (tunnel->room, cls, &message, &hash);
144 }
145 
146 extern int
148  struct GNUNET_MESSENGER_Message *message,
149  const struct GNUNET_HashCode *hash);
150 
151 extern void
154  const struct GNUNET_MESSENGER_Message *message,
155  const struct GNUNET_HashCode *hash);
156 
157 static void
159  const struct GNUNET_HashCode *hash)
160 {
161  struct GNUNET_MESSENGER_OperationStore *operation_store = get_srv_room_operation_store(tunnel->room);
162 
163  const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)?
165  );
166 
167  struct GNUNET_MESSENGER_MessageStore *message_store = get_srv_room_message_store(tunnel->room);
168 
169  const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash);
170 
171  if (message)
172  update_message_state(&(tunnel->state), requested, message, hash);
173 }
174 
175 void
177 {
178  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
179 
180  if (!tunnel)
181  return;
182 
183  const uint16_t length = ntohs (header->size) - sizeof(*header);
184  const char *buffer = (const char*) &header[1];
185 
186  struct GNUNET_MESSENGER_Message message;
187  struct GNUNET_HashCode hash;
188 
189  uint16_t padding = 0;
190 
191  decode_message (&message, length, buffer, GNUNET_YES, &padding);
192  hash_message (&message, length - padding, buffer, &hash);
193 
194  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n",
196 
197  const int new_message = update_room_message (
198  tunnel->room, copy_message (&message), &hash
199  );
200 
201  if (GNUNET_YES != new_message)
202  goto receive_done;
203 
204  update_tunnel_last_message (tunnel, &hash);
205 
206  int forward_message = GNUNET_YES;
207 
208  switch (message.header.kind)
209  {
211  forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash);
212  break;
214  forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash);
215  break;
217  forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash);
218  break;
219  default:
220  break;
221  }
222 
223  if (GNUNET_YES == forward_message)
224  {
225  forward_srv_room_message (tunnel->room, tunnel, &message, &hash);
226  callback_room_handle_message (tunnel->room, NULL, &message, &hash);
227  }
228 
229 receive_done:
230  cleanup_message(&message);
231 
233 }
234 
235 int
237 {
238  GNUNET_assert(tunnel);
239 
240  if (tunnel->channel)
241  return GNUNET_NO;
242 
243  const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
244 
245  struct GNUNET_CADET_Handle *cadet = get_srv_room_cadet (tunnel->room);
246  const struct GNUNET_HashCode *key = get_srv_room_key (tunnel->room);
247 
249  struct GNUNET_MessageHeader, NULL),
251 
252  struct GNUNET_HashCode port;
255 
256  return GNUNET_YES;
257 }
258 
259 void
261 {
262  GNUNET_assert(tunnel);
263 
264  if (tunnel->channel)
265  {
267 
268  tunnel->channel = NULL;
269  }
270 }
271 
272 int
274 {
275  GNUNET_assert(tunnel);
276 
277  return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
278 }
279 
281 {
283  struct GNUNET_HashCode hash;
284 };
285 
286 static void
288 {
289  struct GNUNET_MESSENGER_MessageSent *sent = cls;
290 
291  if (sent->tunnel)
292  update_tunnel_last_message (sent->tunnel, &(sent->hash));
293 
294  GNUNET_free(sent);
295 }
296 
297 void
299  struct GNUNET_MQ_Envelope *env,
300  const struct GNUNET_HashCode *hash)
301 {
302  GNUNET_assert((tunnel) && (env) && (hash));
303 
304  struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
305 
307 
308  GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode));
309 
310  sent->tunnel = tunnel;
311 
313  GNUNET_MQ_send (mq, env);
314 }
315 
316 int
318  void *handle,
319  struct GNUNET_MESSENGER_Message *message)
320 {
321  GNUNET_assert((tunnel) && (handle));
322 
323  if (!message)
324  return GNUNET_NO;
325 
326  struct GNUNET_HashCode hash;
328  tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
330  );
331 
332  destroy_message(message);
333 
334  if (!env)
335  return GNUNET_NO;
336 
337  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n",
338  GNUNET_h2s(&hash));
339 
340  send_tunnel_envelope (tunnel, env, &hash);
341  return GNUNET_YES;
342 }
343 
344 void
346  const struct GNUNET_MESSENGER_Message *message,
347  const struct GNUNET_HashCode *hash)
348 {
349  GNUNET_assert((tunnel) && (message) && (hash));
350 
351  struct GNUNET_MESSENGER_Message *copy = copy_message(message);
353 
354  destroy_message(copy);
355 
356  if (!env)
357  return;
358 
359  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n",
360  GNUNET_h2s(hash));
361 
362  send_tunnel_envelope (tunnel, env, hash);
363 }
364 
365 const struct GNUNET_HashCode*
367 {
368  GNUNET_assert(tunnel);
369 
370  return tunnel->peer_message;
371 }
372 
373 void
375  struct GNUNET_PeerIdentity *peer)
376 {
377  GNUNET_assert(tunnel);
378 
379  GNUNET_PEER_resolve(tunnel->peer, peer);
380 }
381 
382 uint32_t
384 {
385  GNUNET_assert(tunnel);
386 
387  return tunnel->messenger_version;
388 }
389 
390 int
392  uint32_t version)
393 {
394  GNUNET_assert(tunnel);
395 
396  if (version != GNUNET_MESSENGER_VERSION)
397  return GNUNET_SYSERR;
398 
399  if (version > tunnel->messenger_version)
400  tunnel->messenger_version = version;
401 
402  return GNUNET_OK;
403 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
GNUnet MESSENGER service.
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.
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...
void update_message_state(struct GNUNET_MESSENGER_MessageState *state, int requested, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
void clear_message_state(struct GNUNET_MESSENGER_MessageState *state)
void init_message_state(struct GNUNET_MESSENGER_MessageState *state)
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.
enum GNUNET_MESSENGER_OperationType get_store_operation_type(const struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash)
Returns the type of the active operation under a given hash in a specific operation store.
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_MQ_Envelope * pack_srv_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.
void forward_srv_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.
struct GNUNET_CADET_Handle * get_srv_room_cadet(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the CADET handle from a rooms service.
const struct GNUNET_HashCode * get_srv_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
struct GNUNET_MESSENGER_MessageStore * get_srv_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
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.
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.
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...
int connect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Tries to connect a tunnel by creating a new CADET channel and binding it.
void handle_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
static void callback_tunnel_sent(void *cls)
int is_tunnel_connected(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the status of a currently bound channel of a tunnel.
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).
void destroy_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Destroys a tunnel and frees its memory fully.
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...
int callback_verify_room_message(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
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 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 check_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
void callback_tunnel_disconnect(void *cls, const struct GNUNET_CADET_Channel *channel)
const struct GNUNET_HashCode * get_tunnel_peer_message(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the hash of the latest peer message published through a given tunnel and matching the tunnels...
void disconnect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Disconnects and unbinds a channel from a tunnel.
int update_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
static void update_tunnel_last_message(struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_HashCode *hash)
void callback_room_disconnect(struct GNUNET_MESSENGER_SrvRoom *room, void *cls)
GNUnet MESSENGER service.
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:872
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1066
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSENGER_VERSION
Version number of GNUnet Messenger API.
const char * GNUNET_MESSENGER_name_of_kind(enum GNUNET_MESSENGER_MessageKind kind)
Get the name of a message kind.
Definition: messenger_api.c:36
@ GNUNET_MESSENGER_KIND_INFO
The info kind.
@ GNUNET_MESSENGER_KIND_REQUEST
The request kind.
@ GNUNET_MESSENGER_KIND_PEER
The peer kind.
@ GNUNET_MESSENGER_KIND_UNKNOWN
The unknown kind.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:638
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition: peer.c:192
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
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition: peer.c:234
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition: peer.c:108
#define GNUNET_MESSAGE_TYPE_CADET_CLI
Traffic (net-cat style) used by the Command Line Interface.
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...
struct GNUNET_MESSENGER_Message * copy_message(const struct GNUNET_MESSENGER_Message *message)
Creates and allocates a copy of a given message.
void hash_message(const struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, struct GNUNET_HashCode *hash)
Calculates a hash of a given buffer with a length in bytes from a message.
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.
int decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, int include_header, uint16_t *padding)
Decodes a message from a given buffer of a maximal length in bytes.
uint16_t get_message_kind_size(enum GNUNET_MESSENGER_MessageKind kind, int include_header)
Returns the minimal size in bytes to encode a message of a specific kind.
void cleanup_message(struct GNUNET_MESSENGER_Message *message)
Frees the messages body memory.
#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE
void convert_messenger_key_to_port(const struct GNUNET_HashCode *key, struct GNUNET_HashCode *port)
Converts a Messenger service key of a room to the specific port which gets used for the CADET channel...
void delayed_disconnect_channel(struct GNUNET_CADET_Channel *channel)
Starts an urgent task to close a CADET channel asynchronously.
messenger api: client implementation of GNUnet MESSENGER service
Opaque handle to a channel.
Definition: cadet.h:116
Opaque handle to the service.
Definition: cadet_api.c:39
A 512-bit hashcode.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_MESSENGER_SrvTunnel * tunnel
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_CADET_Channel * channel
struct GNUNET_MESSENGER_MessageState state
struct GNUNET_MESSENGER_SrvRoom * room
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.