GNUnet  0.11.x
gnunet-service-messenger_tunnel.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  */
27 
30 
33 {
34  GNUNET_assert((room) && (door));
35 
37 
38  tunnel->room = room;
39  tunnel->channel = NULL;
40 
41  tunnel->peer = GNUNET_PEER_intern (door);
42  tunnel->contact_id = NULL;
43 
44  tunnel->peer_message = NULL;
45  tunnel->last_message = NULL;
46 
47  return tunnel;
48 }
49 
50 void
52 {
53  GNUNET_assert(tunnel);
54 
55  if (tunnel->channel)
57 
58  GNUNET_PEER_change_rc (tunnel->peer, -1);
59 
60  if (tunnel->contact_id)
61  GNUNET_free(tunnel->contact_id);
62 
63  if (tunnel->peer_message)
64  GNUNET_free(tunnel->peer_message);
65 
66  if (tunnel->last_message)
67  GNUNET_free(tunnel->last_message);
68 
69  GNUNET_free(tunnel);
70 }
71 
72 int
74 {
75  GNUNET_assert(tunnel);
76 
77  if (tunnel->channel)
78  {
79  if (tunnel->contact_id)
80  return GNUNET_NO;
81 
83  }
84 
85  tunnel->channel = channel;
86 
87  return GNUNET_YES;
88 }
89 
90 extern void
92 
93 void
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  struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash);
109 
110 int
111 check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
112 {
113  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
114 
115  if (!tunnel)
116  return GNUNET_NO;
117 
118  const uint16_t length = ntohs (header->size) - sizeof(*header);
119  const char *buffer = (const char*) &header[1];
120 
121  struct GNUNET_MESSENGER_Message message;
122 
123  if (length < sizeof(message.header))
124  return GNUNET_NO;
125 
126  if (GNUNET_YES != decode_message (&message, length, buffer))
127  return GNUNET_NO;
128 
129  struct GNUNET_HashCode hash;
130  hash_message (length, buffer, &hash);
131 
132  int result = callback_verify_room_message (tunnel->room, cls, &message, &hash);
133 
134  if (GNUNET_MESSENGER_KIND_PEER == message.header.kind)
135  {
136  struct GNUNET_PeerIdentity identity;
137 
138  GNUNET_PEER_resolve (tunnel->peer, &identity);
139 
140  if (0 == GNUNET_memcmp(&(message.body.peer.peer), &(identity)))
141  {
142  if (tunnel->contact_id)
143  {
144  if (0 != GNUNET_memcmp(tunnel->contact_id, &(message.header.sender_id)))
145  result = GNUNET_SYSERR;
146  }
147  else
148  {
149  tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
150 
151  GNUNET_memcpy(tunnel->contact_id, &(message.header.sender_id), sizeof(struct GNUNET_ShortHashCode));
152  }
153  }
154  }
155 
156  return (result == GNUNET_YES ? GNUNET_OK : GNUNET_NO);
157 }
158 
159 extern void
160 callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message,
161  const struct GNUNET_HashCode *hash);
162 
163 void
164 handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header)
165 {
166  struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls;
167 
168  const uint16_t length = ntohs (header->size) - sizeof(*header);
169  const char *buffer = (const char*) &header[1];
170 
171  struct GNUNET_MESSENGER_Message message;
172  struct GNUNET_HashCode hash;
173 
174  decode_message (&message, length, buffer);
175  hash_message (length, buffer, &hash);
176 
177  if (tunnel)
178  {
179  if (!tunnel->last_message)
180  tunnel->last_message = GNUNET_new(struct GNUNET_HashCode);
181 
182  GNUNET_memcpy(tunnel->last_message, &hash, sizeof(struct GNUNET_HashCode));
183 
184  callback_room_recv (tunnel->room, cls, copy_message (&message), &hash);
185  }
186 
188 }
189 
190 int
192 {
193  GNUNET_assert(tunnel);
194 
195  if (tunnel->channel)
196  return GNUNET_NO;
197 
198  const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer);
199 
200  struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room);
201  struct GNUNET_HashCode *key = get_room_key (tunnel->room);
202 
204  struct GNUNET_MessageHeader, NULL),
206 
207  tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, key, NULL, callback_tunnel_disconnect, handlers);
208 
209  return GNUNET_YES;
210 }
211 
212 void
214 {
215  if (tunnel->channel)
216  {
218 
219  tunnel->channel = NULL;
220  }
221 }
222 
223 int
225 {
226  return (tunnel->channel ? GNUNET_YES : GNUNET_NO);
227 }
228 
230 {
232  struct GNUNET_HashCode hash;
233 };
234 
235 extern void
237  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash);
238 
239 static void
241 {
242  struct GNUNET_MESSENGER_MessageSent *sent = cls;
243 
244  if (sent->tunnel)
245  {
246  if (!sent->tunnel->last_message)
248 
249  GNUNET_memcpy(sent->tunnel->last_message, &(sent->hash), sizeof(struct GNUNET_HashCode));
250  }
251 
252  GNUNET_free(sent);
253 }
254 
255 void
257  struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
258 {
259  struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel);
260 
262 
263  GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode));
264 
265  sent->tunnel = tunnel;
266 
268  GNUNET_MQ_send (mq, env);
269 
270  callback_room_sent (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, tunnel, message, hash);
271 }
272 
273 void
275  struct GNUNET_HashCode *hash)
276 {
277  struct GNUNET_MQ_Envelope *env = pack_room_message (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle,
278  message, hash,
280 
281  if (env)
282  send_tunnel_envelope (tunnel, handle, env, copy_message (message), hash);
283 }
284 
285 void
287  const struct GNUNET_HashCode *hash)
288 {
289  struct GNUNET_MESSENGER_Message *clone = copy_message (message);
291 
292  if (env)
293  send_tunnel_envelope (tunnel, NULL, env, clone, hash);
294 }
295 
296 const struct GNUNET_HashCode*
298 {
299  return tunnel->peer_message;
300 }
int decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer)
Decodes a message from a given buffer of a maximal length in bytes.
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition: peer.c:245
struct GNUNET_PeerIdentity peer
The peer identity of the sender opening a room.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_ShortHashCode sender_id
The senders id inside of the room the message was sent in.
void delayed_disconnect_channel(struct GNUNET_CADET_Channel *channel)
Starts an urgent task to close a CADET channel asynchronously.
struct GNUNET_HashCode * get_room_key(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
Opaque handle to the service.
Definition: cadet_api.c:38
void handle_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void hash_message(uint16_t length, const char *buffer, struct GNUNET_HashCode *hash)
Calculates a hash of a given buffer of a length in bytes.
void callback_tunnel_disconnect(void *cls, const struct GNUNET_CADET_Channel *channel)
int check_tunnel_message(void *cls, const struct GNUNET_MessageHeader *header)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int connect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Tries to connect a tunnel by creating a new CADET channel and binding it.
Opaque handle to a channel.
Definition: cadet.h:116
#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.
GNUnet MESSENGER service.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
GNUnet MESSENGER service.
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.
A 256-bit hashcode.
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...
int is_tunnel_connected(const struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Returns the status of a currently bound channel of a tunnel.
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...
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:787
int callback_verify_room_message(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash)
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_MESSENGER_MessageBody body
Body.
void send_tunnel_envelope(struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Sends an envelope containing a message with a given hash through a tunnel by a given handle...
struct GNUNET_MESSENGER_SrvRoom * room
void callback_room_recv(struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
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.
void destroy_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Destroys a tunnel and frees its memory fully.
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.
Message handler for a specific message type.
struct GNUNET_MESSENGER_SrvTunnel * tunnel
struct GNUNET_HashCode key
The key used in the DHT.
GNUnet MESSENGER service.
struct GNUNET_MESSENGER_Message * copy_message(const struct GNUNET_MESSENGER_Message *message)
Creates and allocates a copy of a given message.
#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE
struct GNUNET_MESSENGER_MessagePeer peer
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void callback_room_disconnect(struct GNUNET_MESSENGER_SrvRoom *room, void *cls)
struct GNUNET_CADET_Channel * channel
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
Handle to a message queue.
Definition: mq.c:85
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.
The identity of the host (wraps the signing key of the peer).
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:888
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:1031
void callback_room_sent(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
struct GNUNET_MQ_Envelope * pack_room_message(struct GNUNET_MESSENGER_SrvRoom *room, 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.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition: peer.c:197
int bind_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel)
Binds a CADET channel to a tunnel on returns GNUNET_YES only if the bounds channel was replaced succe...
Header for all communications.
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:355
void disconnect_tunnel(struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Disconnects and unbinds a channel from a tunnel.
struct GNUNET_ShortHashCode * contact_id
static void callback_tunnel_sent(void *cls)
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition: peer.c:107
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
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:1082