aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api.c
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2020-11-12 17:32:32 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2020-11-12 17:32:32 +0100
commite11d1e59e4ae5f7d89c33df3ae9ca8f1ece990cf (patch)
tree80c08d417bb0c862adcbcde7f55aa7e3a4646d27 /src/messenger/messenger_api.c
parentfec34163a1f17729c190022a2bf747f48e34f07a (diff)
downloadgnunet-e11d1e59e4ae5f7d89c33df3ae9ca8f1ece990cf.tar.gz
gnunet-e11d1e59e4ae5f7d89c33df3ae9ca8f1ece990cf.zip
-revert "-merge branch 'jacki/messenger'"
This reverts commit fec34163a1f17729c190022a2bf747f48e34f07a, reversing changes made to 63fe195e40e55f13ab29e3ba578e97017fc4cc48.
Diffstat (limited to 'src/messenger/messenger_api.c')
-rw-r--r--src/messenger/messenger_api.c568
1 files changed, 0 insertions, 568 deletions
diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c
deleted file mode 100644
index 6401b18d7..000000000
--- a/src/messenger/messenger_api.c
+++ /dev/null
@@ -1,568 +0,0 @@
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 */
20/**
21 * @author Tobias Frisch
22 * @file src/messenger/messenger_api.c
23 * @brief messenger api: client implementation of GNUnet MESSENGER service
24 */
25
26#include "gnunet_messenger_service.h"
27
28#include "gnunet-service-messenger.h"
29
30#include "messenger_api_handle.h"
31#include "messenger_api_message.h"
32
33const char*
34GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind)
35{
36 switch (kind)
37 {
38 case GNUNET_MESSENGER_KIND_INFO:
39 return "INFO";
40 case GNUNET_MESSENGER_KIND_JOIN:
41 return "JOIN";
42 case GNUNET_MESSENGER_KIND_LEAVE:
43 return "LEAVE";
44 case GNUNET_MESSENGER_KIND_NAME:
45 return "NAME";
46 case GNUNET_MESSENGER_KIND_KEY:
47 return "KEY";
48 case GNUNET_MESSENGER_KIND_PEER:
49 return "PEER";
50 case GNUNET_MESSENGER_KIND_ID:
51 return "ID";
52 case GNUNET_MESSENGER_KIND_MISS:
53 return "MISS";
54 case GNUNET_MESSENGER_KIND_MERGE:
55 return "MERGE";
56 case GNUNET_MESSENGER_KIND_REQUEST:
57 return "REQUEST";
58 case GNUNET_MESSENGER_KIND_INVITE:
59 return "INVITE";
60 case GNUNET_MESSENGER_KIND_TEXT:
61 return "TEXT";
62 case GNUNET_MESSENGER_KIND_FILE:
63 return "FILE";
64 default:
65 return "UNKNOWN";
66 }
67}
68
69static int
70check_get_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg)
71{
72 GNUNET_MQ_check_zero_termination(msg);
73 return GNUNET_OK;
74}
75
76static void
77handle_get_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg)
78{
79 struct GNUNET_MESSENGER_Handle *handle = cls;
80
81 const char *name = ((const char*) msg) + sizeof(*msg);
82
83 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name);
84
85 set_handle_name (handle, strlen(name) > 0? name : NULL);
86}
87
88static void
89handle_get_key (void *cls, const struct GNUNET_MESSENGER_KeyMessage *msg)
90{
91 struct GNUNET_MESSENGER_Handle *handle = cls;
92
93 const struct GNUNET_IDENTITY_PublicKey *pubkey = &(msg->pubkey);
94
95 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", GNUNET_IDENTITY_public_key_to_string (pubkey));
96
97 set_handle_key (handle, pubkey);
98
99 if (handle->identity_callback)
100 handle->identity_callback (handle->identity_cls, handle);
101}
102
103static void
104handle_member_id (void *cls, const struct GNUNET_MESSENGER_MemberMessage *msg)
105{
106 struct GNUNET_MESSENGER_Handle *handle = cls;
107
108 const struct GNUNET_HashCode *key = &(msg->key);
109 const struct GNUNET_ShortHashCode *id = &(msg->id);
110
111 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set id of handle in room: %s\n", GNUNET_h2s (key));
112
113 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
114
115 if (room)
116 {
117 if (!room->contact_id)
118 room->contact_id = GNUNET_new(struct GNUNET_ShortHashCode);
119
120 GNUNET_memcpy(room->contact_id, id, sizeof(*id));
121 }
122}
123
124static void
125handle_room_open (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
126{
127 struct GNUNET_MESSENGER_Handle *handle = cls;
128
129 const struct GNUNET_HashCode *key = &(msg->key);
130
131 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key));
132
133 open_handle_room (handle, key);
134}
135
136static void
137handle_room_entry (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
138{
139 struct GNUNET_MESSENGER_Handle *handle = cls;
140
141 const struct GNUNET_PeerIdentity *door = &(msg->door);
142 const struct GNUNET_HashCode *key = &(msg->key);
143
144 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key));
145
146 entry_handle_room_at (handle, door, key);
147}
148
149static void
150handle_room_close (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
151{
152 struct GNUNET_MESSENGER_Handle *handle = cls;
153
154 const struct GNUNET_HashCode *key = &(msg->key);
155
156 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key));
157
158 close_handle_room (handle, key);
159}
160
161static int
162check_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
163{
164 const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header);
165
166 if (full_length < sizeof(msg->hash))
167 return GNUNET_NO;
168
169 const uint16_t length = full_length - sizeof(msg->hash);
170 const char *buffer = ((const char*) msg) + sizeof(*msg);
171
172 struct GNUNET_MESSENGER_Message message;
173
174 if (length < sizeof(message.header))
175 return GNUNET_NO;
176
177 if (GNUNET_YES != decode_message (&message, length, buffer))
178 return GNUNET_NO;
179
180 return GNUNET_OK;
181}
182
183static void
184handle_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
185{
186 struct GNUNET_MESSENGER_Handle *handle = cls;
187
188 const struct GNUNET_HashCode *key = &(msg->key);
189 const struct GNUNET_HashCode *hash = &(msg->hash);
190
191 const char *buffer = ((const char*) msg) + sizeof(*msg);
192
193 const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
194
195 struct GNUNET_MESSENGER_Message message;
196 decode_message (&message, length, buffer);
197
198 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind));
199
200 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
201
202 if (room)
203 {
204 handle_room_message (room, &message, hash);
205
206 if (handle->msg_callback)
207 handle->msg_callback (handle->msg_cls, room, &message, hash);
208 }
209 else
210 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MESSENGER ERROR: Room not found\n");
211}
212
213static void
214reconnect (struct GNUNET_MESSENGER_Handle *handle);
215
216static void
217send_open_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room)
218{
219 struct GNUNET_MESSENGER_RoomMessage *msg;
220 struct GNUNET_MQ_Envelope *env;
221
222 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN);
223 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key));
224 GNUNET_MQ_send (handle->mq, env);
225}
226
227static void
228send_entry_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room,
229 const struct GNUNET_PeerIdentity *door)
230{
231 struct GNUNET_MESSENGER_RoomMessage *msg;
232 struct GNUNET_MQ_Envelope *env;
233
234 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY);
235 GNUNET_memcpy(&(msg->door), door, sizeof(*door));
236 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key));
237 GNUNET_MQ_send (handle->mq, env);
238}
239
240static void
241send_close_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room)
242{
243 struct GNUNET_MESSENGER_RoomMessage *msg;
244 struct GNUNET_MQ_Envelope *env;
245
246 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE);
247 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key));
248 GNUNET_MQ_send (handle->mq, env);
249}
250
251static int
252iterate_reset_room (void *cls, const struct GNUNET_HashCode *key, void *value)
253{
254 struct GNUNET_MESSENGER_Handle *handle = cls;
255 struct GNUNET_MESSENGER_Room *room = value;
256
257 if (GNUNET_YES == room->opened)
258 send_open_room (handle, room);
259
260 struct GNUNET_MESSENGER_ListTunnel *entry = room->entries.head;
261
262 struct GNUNET_PeerIdentity door;
263
264 while (entry)
265 {
266 GNUNET_PEER_resolve (entry->peer, &door);
267
268 send_entry_room (handle, room, &door);
269
270 entry = entry->next;
271 }
272
273 return GNUNET_YES;
274}
275
276static void
277callback_reconnect (void *cls)
278{
279 struct GNUNET_MESSENGER_Handle *handle = cls;
280
281 handle->reconnect_task = NULL;
282 handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time)
283 ;
284
285 reconnect (handle);
286
287 GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_reset_room, handle);
288}
289
290static int
291iterate_close_room (void *cls, const struct GNUNET_HashCode *key, void *value)
292{
293 struct GNUNET_MESSENGER_Handle *handle = cls;
294 struct GNUNET_MESSENGER_Room *room = value;
295
296 send_close_room (handle, room);
297
298 return GNUNET_YES;
299}
300
301static void
302callback_mq_error (void *cls, enum GNUNET_MQ_Error error)
303{
304 struct GNUNET_MESSENGER_Handle *handle = cls;
305
306 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error);
307
308 GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, handle);
309
310 if (handle->mq)
311 {
312 GNUNET_MQ_destroy (handle->mq);
313 handle->mq = NULL;
314 }
315
316 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_time, &callback_reconnect, handle);
317}
318
319static void
320reconnect (struct GNUNET_MESSENGER_Handle *handle)
321{
322 const struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(
323 get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME, struct GNUNET_MESSENGER_NameMessage, handle),
324 GNUNET_MQ_hd_fixed_size(
325 get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY,
326 struct GNUNET_MESSENGER_KeyMessage, handle),
327 GNUNET_MQ_hd_fixed_size(
328 member_id,
329 GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID,
330 struct GNUNET_MESSENGER_MemberMessage, handle),
331 GNUNET_MQ_hd_fixed_size(room_open,
332 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
333 struct GNUNET_MESSENGER_RoomMessage,
334 handle),
335 GNUNET_MQ_hd_fixed_size(room_entry,
336 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
337 struct GNUNET_MESSENGER_RoomMessage,
338 handle),
339 GNUNET_MQ_hd_fixed_size(room_close,
340 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE,
341 struct GNUNET_MESSENGER_RoomMessage,
342 handle),
343 GNUNET_MQ_hd_var_size(
344 recv_message,
345 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE,
346 struct GNUNET_MESSENGER_RecvMessage, handle),
347 GNUNET_MQ_handler_end() };
348
349 handle->mq = GNUNET_CLIENT_connect (handle->cfg,
350 GNUNET_MESSENGER_SERVICE_NAME,
351 handlers, &callback_mq_error, handle);
352}
353
354struct GNUNET_MESSENGER_Handle*
355GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name,
356 GNUNET_MESSENGER_IdentityCallback identity_callback, void *identity_cls,
357 GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls)
358{
359 struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, identity_callback, identity_cls, msg_callback, msg_cls);
360
361 reconnect (handle);
362
363 if (handle->mq)
364 {
365 const uint16_t name_len = name ? strlen (name) : 0;
366
367 struct GNUNET_MESSENGER_CreateMessage *msg;
368 struct GNUNET_MQ_Envelope *env;
369
370 env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE);
371
372 char *extra = ((char*) msg) + sizeof(*msg);
373
374 if (name_len)
375 GNUNET_memcpy(extra, name, name_len);
376
377 extra[name_len] = '\0';
378
379 GNUNET_MQ_send (handle->mq, env);
380 return handle;
381 }
382 else
383 {
384 destroy_handle (handle);
385 return NULL;
386 }
387}
388
389int
390GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle)
391{
392 if ((!handle) || (!get_handle_name(handle)))
393 return GNUNET_SYSERR;
394
395 struct GNUNET_MESSENGER_UpdateMessage *msg;
396 struct GNUNET_MQ_Envelope *env;
397
398 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE);
399 GNUNET_MQ_send (handle->mq, env);
400 return GNUNET_OK;
401}
402
403void
404GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle)
405{
406 if (!handle)
407 return;
408
409 struct GNUNET_MESSENGER_DestroyMessage *msg;
410 struct GNUNET_MQ_Envelope *env;
411
412 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY);
413 GNUNET_MQ_send (handle->mq, env);
414
415 destroy_handle (handle);
416}
417
418const char*
419GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle)
420{
421 if (!handle)
422 return NULL;
423
424 return get_handle_name (handle);
425}
426
427int
428GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, const char *name)
429{
430 if (!handle)
431 return GNUNET_SYSERR;
432
433 const uint16_t name_len = name ? strlen (name) : 0;
434
435 struct GNUNET_MESSENGER_NameMessage *msg;
436 struct GNUNET_MQ_Envelope *env;
437
438 env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME);
439
440 char *extra = ((char*) msg) + sizeof(*msg);
441
442 if (name_len)
443 GNUNET_memcpy(extra, name, name_len);
444
445 extra[name_len] = '\0';
446
447 GNUNET_MQ_send (handle->mq, env);
448 return GNUNET_YES;
449}
450
451const struct GNUNET_IDENTITY_PublicKey*
452GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle)
453{
454 if (!handle)
455 return NULL;
456
457 return get_handle_key (handle);
458}
459
460struct GNUNET_MESSENGER_Room*
461GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key)
462{
463 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
464
465 if (!room)
466 {
467 room = create_room (handle, key);
468
469 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room,
470 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
471 {
472 destroy_room (room);
473 return NULL;
474 }
475 }
476
477 send_open_room (handle, room);
478 return room;
479}
480
481struct GNUNET_MESSENGER_Room*
482GNUNET_MESSENGER_entry_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door,
483 const struct GNUNET_HashCode *key)
484{
485 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
486
487 if (!room)
488 {
489 room = create_room (handle, key);
490
491 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room,
492 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
493 {
494 destroy_room (room);
495 return NULL;
496 }
497 }
498
499 send_entry_room (handle, room, door);
500 return room;
501}
502
503void
504GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room)
505{
506 send_close_room (room->handle, room);
507}
508
509struct GNUNET_MESSENGER_Contact*
510GNUNET_MESSENGER_get_member (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_ShortHashCode *id)
511{
512 return GNUNET_CONTAINER_multishortmap_get (room->members, id);
513}
514
515const char*
516GNUNET_MESSENGER_contact_get_name (const struct GNUNET_MESSENGER_Contact *contact)
517{
518 if (!contact)
519 return NULL;
520
521 return get_contact_name (contact);
522}
523
524const struct GNUNET_IDENTITY_PublicKey*
525GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact)
526{
527 if (!contact)
528 return NULL;
529
530 return get_contact_key (contact);
531}
532
533void
534GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message)
535{
536 const uint16_t length = get_message_size (message);
537
538 struct GNUNET_MESSENGER_SendMessage *msg;
539 struct GNUNET_MQ_Envelope *env;
540
541 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE);
542
543 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key));
544
545 char *buffer = ((char*) msg) + sizeof(*msg);
546 encode_message (message, length, buffer);
547
548 GNUNET_MQ_send (room->handle->mq, env);
549}
550
551const struct GNUNET_MESSENGER_Message*
552GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
553{
554 const struct GNUNET_MESSENGER_Message *message = get_room_message (room, hash);
555
556 if (!message)
557 {
558 struct GNUNET_MESSENGER_RecvMessage *msg;
559 struct GNUNET_MQ_Envelope *env;
560
561 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE);
562 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key));
563 GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash));
564 GNUNET_MQ_send (room->handle->mq, env);
565 }
566
567 return message;
568}