diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_tunnel.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_tunnel.c | 233 |
1 files changed, 152 insertions, 81 deletions
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c index df9e5c4c7..f7e8713c6 100644 --- a/src/messenger/gnunet-service-messenger_tunnel.c +++ b/src/messenger/gnunet-service-messenger_tunnel.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2020 GNUnet e.V. | 3 | Copyright (C) 2020--2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -26,7 +26,8 @@ | |||
26 | #include "gnunet-service-messenger_tunnel.h" | 26 | #include "gnunet-service-messenger_tunnel.h" |
27 | 27 | ||
28 | #include "gnunet-service-messenger_handle.h" | 28 | #include "gnunet-service-messenger_handle.h" |
29 | #include "gnunet-service-messenger_util.h" | 29 | #include "gnunet-service-messenger_message_recv.h" |
30 | #include "messenger_api_util.h" | ||
30 | 31 | ||
31 | struct GNUNET_MESSENGER_SrvTunnel* | 32 | struct GNUNET_MESSENGER_SrvTunnel* |
32 | create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) | 33 | create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) |
@@ -39,7 +40,8 @@ create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerId | |||
39 | tunnel->channel = NULL; | 40 | tunnel->channel = NULL; |
40 | 41 | ||
41 | tunnel->peer = GNUNET_PEER_intern (door); | 42 | tunnel->peer = GNUNET_PEER_intern (door); |
42 | tunnel->contact_id = NULL; | 43 | |
44 | tunnel->messenger_version = 0; | ||
43 | 45 | ||
44 | tunnel->peer_message = NULL; | 46 | tunnel->peer_message = NULL; |
45 | tunnel->last_message = NULL; | 47 | tunnel->last_message = NULL; |
@@ -57,9 +59,6 @@ destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | |||
57 | 59 | ||
58 | GNUNET_PEER_change_rc (tunnel->peer, -1); | 60 | GNUNET_PEER_change_rc (tunnel->peer, -1); |
59 | 61 | ||
60 | if (tunnel->contact_id) | ||
61 | GNUNET_free(tunnel->contact_id); | ||
62 | |||
63 | if (tunnel->peer_message) | 62 | if (tunnel->peer_message) |
64 | GNUNET_free(tunnel->peer_message); | 63 | GNUNET_free(tunnel->peer_message); |
65 | 64 | ||
@@ -69,22 +68,15 @@ destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | |||
69 | GNUNET_free(tunnel); | 68 | GNUNET_free(tunnel); |
70 | } | 69 | } |
71 | 70 | ||
72 | int | 71 | void |
73 | bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) | 72 | bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) |
74 | { | 73 | { |
75 | GNUNET_assert(tunnel); | 74 | GNUNET_assert(tunnel); |
76 | 75 | ||
77 | if (tunnel->channel) | 76 | if (tunnel->channel) |
78 | { | ||
79 | if (tunnel->contact_id) | ||
80 | return GNUNET_NO; | ||
81 | |||
82 | delayed_disconnect_channel (tunnel->channel); | 77 | delayed_disconnect_channel (tunnel->channel); |
83 | } | ||
84 | 78 | ||
85 | tunnel->channel = channel; | 79 | tunnel->channel = channel; |
86 | |||
87 | return GNUNET_YES; | ||
88 | } | 80 | } |
89 | 81 | ||
90 | extern void | 82 | extern void |
@@ -113,52 +105,49 @@ check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) | |||
113 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | 105 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; |
114 | 106 | ||
115 | if (!tunnel) | 107 | if (!tunnel) |
116 | return GNUNET_NO; | 108 | return GNUNET_SYSERR; |
117 | 109 | ||
118 | const uint16_t length = ntohs (header->size) - sizeof(*header); | 110 | const uint16_t length = ntohs (header->size) - sizeof(*header); |
119 | const char *buffer = (const char*) &header[1]; | 111 | const char *buffer = (const char*) &header[1]; |
120 | 112 | ||
121 | struct GNUNET_MESSENGER_Message message; | 113 | struct GNUNET_MESSENGER_Message message; |
122 | 114 | ||
123 | if (length < sizeof(message.header)) | 115 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN)) |
124 | return GNUNET_NO; | 116 | { |
125 | 117 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length); | |
126 | if (GNUNET_YES != decode_message (&message, length, buffer)) | 118 | return GNUNET_SYSERR; |
127 | return GNUNET_NO; | 119 | } |
128 | |||
129 | struct GNUNET_HashCode hash; | ||
130 | hash_message (length, buffer, &hash); | ||
131 | 120 | ||
132 | int result = callback_verify_room_message (tunnel->room, cls, &message, &hash); | 121 | uint16_t padding = 0; |
133 | 122 | ||
134 | if (GNUNET_MESSENGER_KIND_PEER == message.header.kind) | 123 | if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding)) |
135 | { | 124 | { |
136 | struct GNUNET_PeerIdentity identity; | 125 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n"); |
137 | 126 | return GNUNET_SYSERR; | |
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 | } | 127 | } |
155 | 128 | ||
156 | return (result == GNUNET_YES ? GNUNET_OK : GNUNET_NO); | 129 | struct GNUNET_HashCode hash; |
130 | hash_message (&message, length - padding, buffer, &hash); | ||
131 | |||
132 | return callback_verify_room_message (tunnel->room, cls, &message, &hash); | ||
157 | } | 133 | } |
158 | 134 | ||
135 | extern int | ||
136 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
137 | struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); | ||
138 | |||
159 | extern void | 139 | extern void |
160 | callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, | 140 | callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, |
161 | const struct GNUNET_HashCode *hash); | 141 | const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); |
142 | |||
143 | static void | ||
144 | update_tunnel_last_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_HashCode *hash) | ||
145 | { | ||
146 | if (!tunnel->last_message) | ||
147 | tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); | ||
148 | |||
149 | GNUNET_memcpy(tunnel->last_message, hash, sizeof(*hash)); | ||
150 | } | ||
162 | 151 | ||
163 | void | 152 | void |
164 | handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) | 153 | handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) |
@@ -171,19 +160,48 @@ handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) | |||
171 | struct GNUNET_MESSENGER_Message message; | 160 | struct GNUNET_MESSENGER_Message message; |
172 | struct GNUNET_HashCode hash; | 161 | struct GNUNET_HashCode hash; |
173 | 162 | ||
174 | decode_message (&message, length, buffer); | 163 | uint16_t padding = 0; |
175 | hash_message (length, buffer, &hash); | ||
176 | 164 | ||
177 | if (tunnel) | 165 | decode_message (&message, length, buffer, GNUNET_YES, &padding); |
178 | { | 166 | hash_message (&message, length - padding, buffer, &hash); |
179 | if (!tunnel->last_message) | 167 | |
180 | tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); | 168 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n", |
169 | GNUNET_MESSENGER_name_of_kind(message.header.kind)); | ||
170 | |||
171 | if (!tunnel) | ||
172 | return; | ||
173 | |||
174 | const int new_message = update_room_message (tunnel->room, copy_message (&message), &hash); | ||
175 | |||
176 | if (GNUNET_YES != new_message) | ||
177 | goto receive_done; | ||
181 | 178 | ||
182 | GNUNET_memcpy(tunnel->last_message, &hash, sizeof(struct GNUNET_HashCode)); | 179 | update_tunnel_last_message (tunnel, &hash); |
183 | 180 | ||
184 | callback_room_recv (tunnel->room, cls, copy_message (&message), &hash); | 181 | int forward_message = GNUNET_YES; |
182 | |||
183 | switch (message.header.kind) | ||
184 | { | ||
185 | case GNUNET_MESSENGER_KIND_INFO: | ||
186 | forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash); | ||
187 | break; | ||
188 | case GNUNET_MESSENGER_KIND_PEER: | ||
189 | forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash); | ||
190 | break; | ||
191 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
192 | forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash); | ||
193 | break; | ||
194 | default: | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | if (GNUNET_YES == forward_message) | ||
199 | { | ||
200 | forward_room_message (tunnel->room, tunnel, &message, &hash); | ||
201 | callback_room_handle_message (tunnel->room, NULL, &message, &hash); | ||
185 | } | 202 | } |
186 | 203 | ||
204 | receive_done: | ||
187 | GNUNET_CADET_receive_done (tunnel->channel); | 205 | GNUNET_CADET_receive_done (tunnel->channel); |
188 | } | 206 | } |
189 | 207 | ||
@@ -198,7 +216,7 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | |||
198 | const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); | 216 | const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); |
199 | 217 | ||
200 | struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); | 218 | struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); |
201 | struct GNUNET_HashCode *key = get_room_key (tunnel->room); | 219 | const struct GNUNET_HashCode *key = get_room_key (tunnel->room); |
202 | 220 | ||
203 | struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, | 221 | struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, |
204 | struct GNUNET_MessageHeader, NULL), | 222 | struct GNUNET_MessageHeader, NULL), |
@@ -212,6 +230,8 @@ connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | |||
212 | void | 230 | void |
213 | disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 231 | disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) |
214 | { | 232 | { |
233 | GNUNET_assert(tunnel); | ||
234 | |||
215 | if (tunnel->channel) | 235 | if (tunnel->channel) |
216 | { | 236 | { |
217 | delayed_disconnect_channel (tunnel->channel); | 237 | delayed_disconnect_channel (tunnel->channel); |
@@ -223,6 +243,8 @@ disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | |||
223 | int | 243 | int |
224 | is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 244 | is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) |
225 | { | 245 | { |
246 | GNUNET_assert(tunnel); | ||
247 | |||
226 | return (tunnel->channel ? GNUNET_YES : GNUNET_NO); | 248 | return (tunnel->channel ? GNUNET_YES : GNUNET_NO); |
227 | } | 249 | } |
228 | 250 | ||
@@ -232,30 +254,23 @@ struct GNUNET_MESSENGER_MessageSent | |||
232 | struct GNUNET_HashCode hash; | 254 | struct GNUNET_HashCode hash; |
233 | }; | 255 | }; |
234 | 256 | ||
235 | extern void | ||
236 | callback_room_sent (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, | ||
237 | struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); | ||
238 | |||
239 | static void | 257 | static void |
240 | callback_tunnel_sent (void *cls) | 258 | callback_tunnel_sent (void *cls) |
241 | { | 259 | { |
242 | struct GNUNET_MESSENGER_MessageSent *sent = cls; | 260 | struct GNUNET_MESSENGER_MessageSent *sent = cls; |
243 | 261 | ||
244 | if (sent->tunnel) | 262 | if (sent->tunnel) |
245 | { | 263 | update_tunnel_last_message (sent->tunnel, &(sent->hash)); |
246 | if (!sent->tunnel->last_message) | ||
247 | sent->tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); | ||
248 | |||
249 | GNUNET_memcpy(sent->tunnel->last_message, &(sent->hash), sizeof(struct GNUNET_HashCode)); | ||
250 | } | ||
251 | 264 | ||
252 | GNUNET_free(sent); | 265 | GNUNET_free(sent); |
253 | } | 266 | } |
254 | 267 | ||
255 | void | 268 | void |
256 | send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, | 269 | send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MQ_Envelope *env, |
257 | struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) | 270 | const struct GNUNET_HashCode *hash) |
258 | { | 271 | { |
272 | GNUNET_assert((tunnel) && (env) && (hash)); | ||
273 | |||
259 | struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); | 274 | struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); |
260 | 275 | ||
261 | struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); | 276 | struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); |
@@ -266,35 +281,91 @@ send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, s | |||
266 | 281 | ||
267 | GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); | 282 | GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); |
268 | GNUNET_MQ_send (mq, env); | 283 | GNUNET_MQ_send (mq, env); |
269 | |||
270 | callback_room_sent (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, tunnel, message, hash); | ||
271 | } | 284 | } |
272 | 285 | ||
273 | void | 286 | int |
274 | send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, | 287 | send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message) |
275 | struct GNUNET_HashCode *hash) | ||
276 | { | 288 | { |
277 | struct GNUNET_MQ_Envelope *env = pack_room_message (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, | 289 | GNUNET_assert((tunnel) && (handle)); |
278 | message, hash, | 290 | |
279 | GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | 291 | if (!message) |
292 | return GNUNET_NO; | ||
293 | |||
294 | struct GNUNET_HashCode hash; | ||
295 | struct GNUNET_MQ_Envelope *env = pack_room_message ( | ||
296 | tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, | ||
297 | message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE | ||
298 | ); | ||
299 | |||
300 | destroy_message(message); | ||
301 | |||
302 | if (!env) | ||
303 | return GNUNET_NO; | ||
304 | |||
305 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n", | ||
306 | GNUNET_h2s(&hash)); | ||
280 | 307 | ||
281 | if (env) | 308 | send_tunnel_envelope (tunnel, env, &hash); |
282 | send_tunnel_envelope (tunnel, handle, env, copy_message (message), hash); | 309 | return GNUNET_YES; |
283 | } | 310 | } |
284 | 311 | ||
285 | void | 312 | void |
286 | forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, | 313 | forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, |
287 | const struct GNUNET_HashCode *hash) | 314 | const struct GNUNET_HashCode *hash) |
288 | { | 315 | { |
289 | struct GNUNET_MESSENGER_Message *clone = copy_message (message); | 316 | if (!message) |
290 | struct GNUNET_MQ_Envelope *env = pack_message (clone, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | 317 | return; |
318 | |||
319 | GNUNET_assert((tunnel) && (message) && (hash)); | ||
320 | |||
321 | struct GNUNET_MESSENGER_Message *copy = copy_message(message); | ||
322 | struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | ||
323 | |||
324 | destroy_message(copy); | ||
325 | |||
326 | if (!env) | ||
327 | return; | ||
328 | |||
329 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n", | ||
330 | GNUNET_h2s(hash)); | ||
291 | 331 | ||
292 | if (env) | 332 | send_tunnel_envelope (tunnel, env, hash); |
293 | send_tunnel_envelope (tunnel, NULL, env, clone, hash); | ||
294 | } | 333 | } |
295 | 334 | ||
296 | const struct GNUNET_HashCode* | 335 | const struct GNUNET_HashCode* |
297 | get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | 336 | get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) |
298 | { | 337 | { |
338 | GNUNET_assert(tunnel); | ||
339 | |||
299 | return tunnel->peer_message; | 340 | return tunnel->peer_message; |
300 | } | 341 | } |
342 | |||
343 | void | ||
344 | get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_PeerIdentity *peer) | ||
345 | { | ||
346 | GNUNET_assert(tunnel); | ||
347 | |||
348 | GNUNET_PEER_resolve(tunnel->peer, peer); | ||
349 | } | ||
350 | |||
351 | uint32_t | ||
352 | get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
353 | { | ||
354 | GNUNET_assert(tunnel); | ||
355 | |||
356 | return tunnel->messenger_version; | ||
357 | } | ||
358 | |||
359 | int | ||
360 | update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, uint32_t version) | ||
361 | { | ||
362 | GNUNET_assert(tunnel); | ||
363 | |||
364 | if (version != GNUNET_MESSENGER_VERSION) | ||
365 | return GNUNET_SYSERR; | ||
366 | |||
367 | if (version > tunnel->messenger_version) | ||
368 | tunnel->messenger_version = version; | ||
369 | |||
370 | return GNUNET_OK; | ||
371 | } | ||