aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-03-12 14:38:12 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-03-12 14:38:12 +0100
commitba528dd455716f73fbfb3191401b8978e9900453 (patch)
tree4c8521087eab07be002f2706e565d438f3cca5f0
parentafd5d7cb5fdb8d2cf20f50d3942f553be78ca0ca (diff)
downloadlibgnunetchat-ba528dd455716f73fbfb3191401b8978e9900453.tar.gz
libgnunetchat-ba528dd455716f73fbfb3191401b8978e9900453.zip
Implemented lobby functionality and uri solving to add contacts
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--Makefile3
-rw-r--r--include/gnunet_chat_lib.h4
-rw-r--r--src/gnunet_chat_context.c21
-rw-r--r--src/gnunet_chat_context.h7
-rw-r--r--src/gnunet_chat_handle.c155
-rw-r--r--src/gnunet_chat_handle.h36
-rw-r--r--src/gnunet_chat_handle_intern.c75
-rw-r--r--src/gnunet_chat_lib.c125
-rw-r--r--src/gnunet_chat_lib_intern.c39
-rw-r--r--src/gnunet_chat_lobby.c130
-rw-r--r--src/gnunet_chat_lobby.h66
-rw-r--r--src/gnunet_chat_lobby_intern.c157
-rw-r--r--src/gnunet_chat_uri.c51
-rw-r--r--src/gnunet_chat_uri.h48
-rw-r--r--src/gnunet_chat_util.c37
-rw-r--r--src/gnunet_chat_util.h15
16 files changed, 857 insertions, 112 deletions
diff --git a/Makefile b/Makefile
index 82c739f..d8a8872 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,9 @@ SOURCES = gnunet_chat_lib.c\
14 gnunet_chat_group.c\ 14 gnunet_chat_group.c\
15 gnunet_chat_handle.c\ 15 gnunet_chat_handle.c\
16 gnunet_chat_invitation.c\ 16 gnunet_chat_invitation.c\
17 gnunet_chat_lobby.c\
17 gnunet_chat_message.c\ 18 gnunet_chat_message.c\
19 gnunet_chat_uri.c\
18 gnunet_chat_util.c 20 gnunet_chat_util.c
19 21
20HEADERS = gnunet_chat_lib.h 22HEADERS = gnunet_chat_lib.h
@@ -24,6 +26,7 @@ TESTS = test_gnunet_chat_handle.c
24LIBRARIES = gnunetarm\ 26LIBRARIES = gnunetarm\
25 gnunetfs\ 27 gnunetfs\
26 gnunetidentity\ 28 gnunetidentity\
29 gnunetgns\
27 gnunetmessenger\ 30 gnunetmessenger\
28 gnunetnamestore\ 31 gnunetnamestore\
29 gnunetregex\ 32 gnunetregex\
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
index b1810d5..e8a409f 100644
--- a/include/gnunet_chat_lib.h
+++ b/include/gnunet_chat_lib.h
@@ -39,6 +39,8 @@
39#include <gnunet/gnunet_time_lib.h> 39#include <gnunet/gnunet_time_lib.h>
40#include <gnunet/gnunet_util_lib.h> 40#include <gnunet/gnunet_util_lib.h>
41 41
42#define GNUNET_CHAT_URI_PREFIX "gnunet://chat/"
43
42/** 44/**
43 * Enum for the different kinds of messages. 45 * Enum for the different kinds of messages.
44 */ 46 */
@@ -172,7 +174,7 @@ typedef int
172 * Method called when a lobby is opened to share with others via a chat URI. 174 * Method called when a lobby is opened to share with others via a chat URI.
173 * 175 *
174 * @param[in,out] cls Closure from #GNUNET_CHAT_lobby_open 176 * @param[in,out] cls Closure from #GNUNET_CHAT_lobby_open
175 * @param[in] uri Chat URI of the lobby 177 * @param[in] uri Chat URI of the lobby or NULL on error
176 */ 178 */
177typedef void 179typedef void
178(*GNUNET_CHAT_LobbyCallback) (void *cls, 180(*GNUNET_CHAT_LobbyCallback) (void *cls,
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
index 7b6e36d..483d673 100644
--- a/src/gnunet_chat_context.c
+++ b/src/gnunet_chat_context.c
@@ -329,27 +329,8 @@ context_write_records (struct GNUNET_CHAT_Context *context)
329 count++; 329 count++;
330 } 330 }
331 331
332 const char *type_string = "chat";
333
334 switch (context->type)
335 {
336 case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
337 type_string = "contact";
338 break;
339 case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
340 type_string = "group";
341 break;
342 default:
343 break;
344 }
345
346 char *label; 332 char *label;
347 GNUNET_asprintf ( 333 util_get_context_label(context->type, hash, &label);
348 &label,
349 "%s_%s",
350 type_string,
351 GNUNET_h2s(hash)
352 );
353 334
354 printf("WRITE: %s -> %u (%s, %s)\n", label, count, nick, topic); 335 printf("WRITE: %s -> %u (%s, %s)\n", label, count, nick, topic);
355 336
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h
index f0272f0..37d9bc8 100644
--- a/src/gnunet_chat_context.h
+++ b/src/gnunet_chat_context.h
@@ -33,12 +33,7 @@
33#include <gnunet/gnunet_messenger_service.h> 33#include <gnunet/gnunet_messenger_service.h>
34#include <gnunet/gnunet_util_lib.h> 34#include <gnunet/gnunet_util_lib.h>
35 35
36enum GNUNET_CHAT_ContextType 36#include "gnunet_chat_util.h"
37{
38 GNUNET_CHAT_CONTEXT_TYPE_CONTACT = 1,
39 GNUNET_CHAT_CONTEXT_TYPE_GROUP = 2,
40 GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN = 0
41};
42 37
43struct GNUNET_CHAT_Handle; 38struct GNUNET_CHAT_Handle;
44 39
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
index 5205aa9..de42b83 100644
--- a/src/gnunet_chat_handle.c
+++ b/src/gnunet_chat_handle.c
@@ -60,6 +60,12 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
60 handle->creation_op = NULL; 60 handle->creation_op = NULL;
61 handle->monitor = NULL; 61 handle->monitor = NULL;
62 62
63 handle->lobbies_head = NULL;
64 handle->lobbies_tail = NULL;
65
66 handle->lobbies_head = NULL;
67 handle->lobbies_tail = NULL;
68
63 handle->files = NULL; 69 handle->files = NULL;
64 handle->contexts = NULL; 70 handle->contexts = NULL;
65 handle->contacts = NULL; 71 handle->contacts = NULL;
@@ -84,6 +90,7 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
84 ); 90 );
85 91
86 handle->fs = NULL; 92 handle->fs = NULL;
93 handle->gns = NULL;
87 handle->messenger = NULL; 94 handle->messenger = NULL;
88 95
89 handle->public_key = NULL; 96 handle->public_key = NULL;
@@ -218,6 +225,8 @@ handle_connect (struct GNUNET_CHAT_Handle *handle,
218 225
219 GNUNET_free(fs_client_name); 226 GNUNET_free(fs_client_name);
220 227
228 handle->gns = GNUNET_GNS_connect(handle->cfg);
229
221 handle->messenger = GNUNET_MESSENGER_connect( 230 handle->messenger = GNUNET_MESSENGER_connect(
222 handle->cfg, name, 231 handle->cfg, name,
223 on_handle_identity, handle, 232 on_handle_identity, handle,
@@ -250,18 +259,76 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle)
250 handle->contexts, it_destroy_handle_contexts, NULL 259 handle->contexts, it_destroy_handle_contexts, NULL
251 ); 260 );
252 261
262 struct GNUNET_CHAT_InternalMessages *internal;
263 while (handle->internal_head)
264 {
265 internal = handle->internal_head;
266
267 if ((internal->msg) && (internal->msg->context))
268 message_destroy(internal->msg);
269
270 GNUNET_CONTAINER_DLL_remove(
271 handle->internal_head,
272 handle->internal_tail,
273 internal
274 );
275
276 GNUNET_free(internal);
277 }
278
253 if (handle->messenger) 279 if (handle->messenger)
254 GNUNET_MESSENGER_disconnect(handle->messenger); 280 GNUNET_MESSENGER_disconnect(handle->messenger);
255 281
282 if (handle->gns)
283 GNUNET_GNS_disconnect(handle->gns);
284
256 if (handle->fs) 285 if (handle->fs)
257 GNUNET_FS_stop(handle->fs); 286 GNUNET_FS_stop(handle->fs);
258 287
288 handle->fs = NULL;
289 handle->gns = NULL;
290 handle->messenger = NULL;
291
259 GNUNET_CONTAINER_multihashmap_iterate( 292 GNUNET_CONTAINER_multihashmap_iterate(
260 handle->files, it_destroy_handle_files, NULL 293 handle->files, it_destroy_handle_files, NULL
261 ); 294 );
262 295
263 handle->fs = NULL; 296 struct GNUNET_CHAT_InternalLobbies *lobbies;
264 handle->messenger = NULL; 297 while (handle->lobbies_head)
298 {
299 lobbies = handle->lobbies_head;
300
301 if (lobbies->lobby)
302 lobby_destroy(lobbies->lobby);
303
304 GNUNET_CONTAINER_DLL_remove(
305 handle->lobbies_head,
306 handle->lobbies_tail,
307 lobbies
308 );
309
310 GNUNET_free(lobbies);
311 }
312
313 struct GNUNET_CHAT_UriLookups *lookups;
314 while (handle->lookups_head)
315 {
316 lookups = handle->lookups_head;
317
318 if (lookups->request)
319 GNUNET_GNS_lookup_cancel(lookups->request);
320
321 if (lookups->uri)
322 uri_destroy(lookups->uri);
323
324 GNUNET_CONTAINER_DLL_remove(
325 handle->lookups_head,
326 handle->lookups_tail,
327 lookups
328 );
329
330 GNUNET_free(lookups);
331 }
265 332
266 GNUNET_CONTAINER_multihashmap_destroy(handle->groups); 333 GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
267 GNUNET_CONTAINER_multishortmap_destroy(handle->contacts); 334 GNUNET_CONTAINER_multishortmap_destroy(handle->contacts);
@@ -493,3 +560,87 @@ handle_get_group_from_messenger (const struct GNUNET_CHAT_Handle *handle,
493 handle->groups, key 560 handle->groups, key
494 ); 561 );
495} 562}
563
564struct GNUNET_CHAT_Context*
565handle_process_records (struct GNUNET_CHAT_Handle *handle,
566 const char *label,
567 unsigned int count,
568 const struct GNUNET_GNSRECORD_Data *data)
569{
570 GNUNET_assert((handle) && (data));
571
572 if (count <= 0)
573 return NULL;
574
575 const struct GNUNET_MESSENGER_RoomEntryRecord *record = NULL;
576
577 for (unsigned int i = 0; i < count; i++)
578 {
579 if (GNUNET_YES == GNUNET_GNSRECORD_is_expired(data + i))
580 continue;
581
582 if ((GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY == data[i].record_type) &&
583 (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags)))
584 {
585 record = data[i].data;
586 break;
587 }
588 }
589
590 if (!record)
591 return NULL;
592
593 struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
594 handle->contexts,
595 &(record->key)
596 );
597
598 if (context)
599 {
600 context_read_records(context, label, count, data);
601
602 printf("PATCH: %s %u %d %s\n", label, count, (int) context->type, context->topic);
603
604 return NULL;
605 }
606
607 struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_enter_room(
608 handle->messenger,
609 &(record->door),
610 &(record->key)
611 );
612
613 if (!room)
614 return NULL;
615
616 context = context_create_from_room(handle, room);
617 context_read_records(context, label, count, data);
618
619 printf("READ: %s %u %d %s\n", label, count, (int) context->type, context->topic);
620
621 handle_send_room_name(handle, room);
622
623 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
624 handle->contexts, &(record->key), context,
625 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
626 {
627 context_destroy(context);
628 GNUNET_MESSENGER_close_room(room);
629 return NULL;
630 }
631
632 if (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)
633 return context;
634
635 struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context);
636
637 if (context->topic)
638 group_publish(group);
639
640 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
641 handle->groups, &(record->key), group,
642 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
643 group_destroy(group);
644
645 return context;
646}
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
index 0713bf1..28cfacc 100644
--- a/src/gnunet_chat_handle.h
+++ b/src/gnunet_chat_handle.h
@@ -31,6 +31,7 @@
31#include <gnunet/gnunet_container_lib.h> 31#include <gnunet/gnunet_container_lib.h>
32#include <gnunet/gnunet_arm_service.h> 32#include <gnunet/gnunet_arm_service.h>
33#include <gnunet/gnunet_fs_service.h> 33#include <gnunet/gnunet_fs_service.h>
34#include <gnunet/gnunet_gns_service.h>
34#include <gnunet/gnunet_identity_service.h> 35#include <gnunet/gnunet_identity_service.h>
35#include <gnunet/gnunet_messenger_service.h> 36#include <gnunet/gnunet_messenger_service.h>
36#include <gnunet/gnunet_namestore_service.h> 37#include <gnunet/gnunet_namestore_service.h>
@@ -39,7 +40,11 @@
39 40
40#include "gnunet_chat_lib.h" 41#include "gnunet_chat_lib.h"
41#include "gnunet_chat_account.h" 42#include "gnunet_chat_account.h"
43#include "gnunet_chat_lobby.h"
42#include "gnunet_chat_message.h" 44#include "gnunet_chat_message.h"
45#include "gnunet_chat_uri.h"
46
47struct GNUNET_CHAT_Handle;
43 48
44struct GNUNET_CHAT_InternalMessages 49struct GNUNET_CHAT_InternalMessages
45{ 50{
@@ -55,6 +60,24 @@ struct GNUNET_CHAT_InternalAccounts
55 struct GNUNET_CHAT_InternalAccounts *prev; 60 struct GNUNET_CHAT_InternalAccounts *prev;
56}; 61};
57 62
63struct GNUNET_CHAT_InternalLobbies
64{
65 struct GNUNET_CHAT_Lobby *lobby;
66 struct GNUNET_CHAT_InternalLobbies *next;
67 struct GNUNET_CHAT_InternalLobbies *prev;
68};
69
70struct GNUNET_CHAT_UriLookups
71{
72 struct GNUNET_CHAT_Handle *handle;
73
74 struct GNUNET_GNS_LookupRequest *request;
75 struct GNUNET_CHAT_Uri *uri;
76
77 struct GNUNET_CHAT_UriLookups *next;
78 struct GNUNET_CHAT_UriLookups *prev;
79};
80
58struct GNUNET_CHAT_Handle 81struct GNUNET_CHAT_Handle
59{ 82{
60 const struct GNUNET_CONFIGURATION_Handle* cfg; 83 const struct GNUNET_CONFIGURATION_Handle* cfg;
@@ -75,6 +98,12 @@ struct GNUNET_CHAT_Handle
75 struct GNUNET_IDENTITY_Operation *creation_op; 98 struct GNUNET_IDENTITY_Operation *creation_op;
76 struct GNUNET_NAMESTORE_ZoneMonitor *monitor; 99 struct GNUNET_NAMESTORE_ZoneMonitor *monitor;
77 100
101 struct GNUNET_CHAT_InternalLobbies *lobbies_head;
102 struct GNUNET_CHAT_InternalLobbies *lobbies_tail;
103
104 struct GNUNET_CHAT_UriLookups *lookups_head;
105 struct GNUNET_CHAT_UriLookups *lookups_tail;
106
78 struct GNUNET_CONTAINER_MultiHashMap *files; 107 struct GNUNET_CONTAINER_MultiHashMap *files;
79 struct GNUNET_CONTAINER_MultiHashMap *contexts; 108 struct GNUNET_CONTAINER_MultiHashMap *contexts;
80 struct GNUNET_CONTAINER_MultiShortmap *contacts; 109 struct GNUNET_CONTAINER_MultiShortmap *contacts;
@@ -82,6 +111,7 @@ struct GNUNET_CHAT_Handle
82 111
83 struct GNUNET_ARM_Handle *arm; 112 struct GNUNET_ARM_Handle *arm;
84 struct GNUNET_FS_Handle *fs; 113 struct GNUNET_FS_Handle *fs;
114 struct GNUNET_GNS_Handle *gns;
85 struct GNUNET_IDENTITY_Handle *identity; 115 struct GNUNET_IDENTITY_Handle *identity;
86 struct GNUNET_MESSENGER_Handle *messenger; 116 struct GNUNET_MESSENGER_Handle *messenger;
87 struct GNUNET_NAMESTORE_Handle *namestore; 117 struct GNUNET_NAMESTORE_Handle *namestore;
@@ -137,4 +167,10 @@ struct GNUNET_CHAT_Group*
137handle_get_group_from_messenger (const struct GNUNET_CHAT_Handle *handle, 167handle_get_group_from_messenger (const struct GNUNET_CHAT_Handle *handle,
138 const struct GNUNET_MESSENGER_Room *room); 168 const struct GNUNET_MESSENGER_Room *room);
139 169
170struct GNUNET_CHAT_Context*
171handle_process_records (struct GNUNET_CHAT_Handle *handle,
172 const char *label,
173 unsigned int count,
174 const struct GNUNET_GNSRECORD_Data *data);
175
140#endif /* GNUNET_CHAT_HANDLE_H_ */ 176#endif /* GNUNET_CHAT_HANDLE_H_ */
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
index 0662850..69b2793 100644
--- a/src/gnunet_chat_handle_intern.c
+++ b/src/gnunet_chat_handle_intern.c
@@ -374,79 +374,8 @@ on_monitor_namestore_record(void *cls,
374{ 374{
375 struct GNUNET_CHAT_Handle *chat = cls; 375 struct GNUNET_CHAT_Handle *chat = cls;
376 376
377 if (count <= 0) 377 handle_process_records(chat, label, count, data);
378 goto skip_records;
379 378
380 const struct GNUNET_MESSENGER_RoomEntryRecord *record = NULL;
381
382 for (unsigned int i = 0; i < count; i++)
383 {
384 if (GNUNET_YES == GNUNET_GNSRECORD_is_expired(data + i))
385 continue;
386
387 if ((GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY == data[i].record_type) &&
388 (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags)))
389 {
390 record = data[i].data;
391 break;
392 }
393 }
394
395 if (!record)
396 goto skip_records;
397
398 struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
399 chat->contexts,
400 &(record->key)
401 );
402
403 if (context)
404 {
405 context_read_records(context, label, count, data);
406
407 printf("PATCH: %s %u %d %s\n", label, count, (int) context->type, context->topic);
408
409 goto skip_records;
410 }
411
412 struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_enter_room(
413 chat->messenger,
414 &(record->door),
415 &(record->key)
416 );
417
418 if (!room)
419 goto skip_records;
420
421 context = context_create_from_room(chat, room);
422 context_read_records(context, label, count, data);
423
424 printf("READ: %s %u %d %s\n", label, count, (int) context->type, context->topic);
425
426 handle_send_room_name(chat, room);
427
428 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
429 chat->contexts, &(record->key), context,
430 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
431 {
432 context_destroy(context);
433 goto skip_records;
434 }
435
436 if (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)
437 goto skip_records;
438
439 struct GNUNET_CHAT_Group *group = group_create_from_context(chat, context);
440
441 if (context->topic)
442 group_publish(group);
443
444 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
445 chat->groups, &(record->key), group,
446 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
447 group_destroy(group);
448
449skip_records:
450 if (chat->monitor) 379 if (chat->monitor)
451 GNUNET_NAMESTORE_zone_monitor_next(chat->monitor, 1); 380 GNUNET_NAMESTORE_zone_monitor_next(chat->monitor, 1);
452} 381}
@@ -471,8 +400,6 @@ on_handle_identity(void *cls,
471 400
472 GNUNET_assert(handle->messenger); 401 GNUNET_assert(handle->messenger);
473 402
474 printf("HURRAY!\n");
475
476 handle_send_internal_message( 403 handle_send_internal_message(
477 handle, 404 handle,
478 NULL, 405 NULL,
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
index f9daa45..bac539d 100644
--- a/src/gnunet_chat_lib.c
+++ b/src/gnunet_chat_lib.c
@@ -32,7 +32,9 @@
32#include "gnunet_chat_group.h" 32#include "gnunet_chat_group.h"
33#include "gnunet_chat_handle.h" 33#include "gnunet_chat_handle.h"
34#include "gnunet_chat_invitation.h" 34#include "gnunet_chat_invitation.h"
35#include "gnunet_chat_lobby.h"
35#include "gnunet_chat_message.h" 36#include "gnunet_chat_message.h"
37
36#include "gnunet_chat_util.h" 38#include "gnunet_chat_util.h"
37 39
38#include "gnunet_chat_lib_intern.c" 40#include "gnunet_chat_lib_intern.c"
@@ -215,9 +217,44 @@ GNUNET_CHAT_uri_parse (const char *uri,
215 if (!uri) 217 if (!uri)
216 return NULL; 218 return NULL;
217 219
218 // TODO 220 const size_t prefix_len = strlen(GNUNET_CHAT_URI_PREFIX);
219 221
220 return NULL; 222 if (0 != strncmp(GNUNET_CHAT_URI_PREFIX, uri, prefix_len))
223 {
224 if (emsg)
225 *emsg = GNUNET_strdup (_ ("CHAT URI malformed (invalid prefix)"));
226
227 return NULL;
228 }
229
230 struct GNUNET_IDENTITY_PublicKey zone;
231
232 const char *data = uri + prefix_len;
233 char *end = strchr(data, '.');
234
235 if (!end)
236 {
237 if (emsg)
238 *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key missing)"));
239
240 return NULL;
241 }
242
243 char *zone_data = GNUNET_strndup(data, (size_t) (end - data));
244
245 if (GNUNET_OK != GNUNET_IDENTITY_public_key_from_string(zone_data, &zone))
246 {
247 GNUNET_free(zone_data);
248
249 if (emsg)
250 *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key invalid)"));
251
252 return NULL;
253 }
254
255 GNUNET_free(zone_data);
256
257 return uri_create(&zone, end + 1);
221} 258}
222 259
223 260
@@ -227,9 +264,18 @@ GNUNET_CHAT_uri_to_string (const struct GNUNET_CHAT_Uri *uri)
227 if (!uri) 264 if (!uri)
228 return NULL; 265 return NULL;
229 266
230 // TODO 267 char *key_string = GNUNET_IDENTITY_public_key_to_string(&(uri->zone));
231 268
232 return NULL; 269 char *string;
270 GNUNET_asprintf(
271 &string,
272 "gnunet://chat/%s.%s",
273 key_string,
274 uri->label
275 );
276
277 GNUNET_free(key_string);
278 return string;
233} 279}
234 280
235 281
@@ -239,7 +285,7 @@ GNUNET_CHAT_uri_destroy (struct GNUNET_CHAT_Uri *uri)
239 if (!uri) 285 if (!uri)
240 return; 286 return;
241 287
242 GNUNET_free(uri); 288 uri_destroy(uri);
243} 289}
244 290
245 291
@@ -249,16 +295,53 @@ GNUNET_CHAT_lobby_open (struct GNUNET_CHAT_Handle *handle,
249 GNUNET_CHAT_LobbyCallback callback, 295 GNUNET_CHAT_LobbyCallback callback,
250 void *cls) 296 void *cls)
251{ 297{
252 // TODO 298 if (!handle)
299 return NULL;
253 300
254 return NULL; 301 struct GNUNET_CHAT_InternalLobbies *lobbies = GNUNET_new(
302 struct GNUNET_CHAT_InternalLobbies
303 );
304
305 lobbies->lobby = lobby_create(handle);
306
307 GNUNET_CONTAINER_DLL_insert(
308 handle->lobbies_head,
309 handle->lobbies_tail,
310 lobbies
311 );
312
313 lobby_open(lobbies->lobby, delay, callback, cls);
314
315 return lobbies->lobby;
255} 316}
256 317
257 318
258void 319void
259GNUNET_CHAT_lobby_close (struct GNUNET_CHAT_Lobby *lobby) 320GNUNET_CHAT_lobby_close (struct GNUNET_CHAT_Lobby *lobby)
260{ 321{
261 // TODO 322 if (!lobby)
323 return;
324
325 struct GNUNET_CHAT_InternalLobbies *lobbies = lobby->handle->lobbies_head;
326
327 while (lobbies)
328 {
329 if (lobbies->lobby == lobby)
330 {
331 GNUNET_CONTAINER_DLL_remove(
332 lobby->handle->lobbies_head,
333 lobby->handle->lobbies_tail,
334 lobbies
335 );
336
337 GNUNET_free(lobbies);
338 break;
339 }
340
341 lobbies = lobbies->next;
342 }
343
344 lobby_destroy(lobby);
262} 345}
263 346
264 347
@@ -266,7 +349,31 @@ void
266GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle, 349GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle,
267 const struct GNUNET_CHAT_Uri *uri) 350 const struct GNUNET_CHAT_Uri *uri)
268{ 351{
269 // TODO 352 if ((!handle) || (!uri) || (!(handle->gns)))
353 return;
354
355 struct GNUNET_CHAT_UriLookups *lookups = GNUNET_new(
356 struct GNUNET_CHAT_UriLookups
357 );
358
359 lookups->handle = handle;
360 lookups->uri = uri_create(&(uri->zone), uri->label);
361
362 lookups->request = GNUNET_GNS_lookup(
363 handle->gns,
364 lookups->uri->label,
365 &(uri->zone),
366 GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY,
367 GNUNET_GNS_LO_DEFAULT,
368 cb_lobby_lookup,
369 lookups
370 );
371
372 GNUNET_CONTAINER_DLL_insert(
373 handle->lookups_head,
374 handle->lookups_tail,
375 lookups
376 );
270} 377}
271 378
272 379
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c
index 99384b4..ff8bbca 100644
--- a/src/gnunet_chat_lib_intern.c
+++ b/src/gnunet_chat_lib_intern.c
@@ -41,6 +41,45 @@ cb_account_creation (void *cls,
41 handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL); 41 handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL);
42} 42}
43 43
44void
45cb_lobby_lookup (void *cls,
46 uint32_t count,
47 const struct GNUNET_GNSRECORD_Data *data)
48{
49 GNUNET_assert(cls);
50
51 struct GNUNET_CHAT_UriLookups *lookups = (struct GNUNET_CHAT_UriLookups*) cls;
52
53 if ((!(lookups->handle)) || (!(lookups->uri)))
54 goto drop_lookup;
55
56 struct GNUNET_CHAT_Context *context = handle_process_records(
57 lookups->handle,
58 lookups->uri->label,
59 count,
60 data
61 );
62
63 if (context)
64 context_write_records(context);
65
66drop_lookup:
67 if (lookups->request)
68 GNUNET_GNS_lookup_cancel(lookups->request);
69
70 if (lookups->uri)
71 uri_destroy(lookups->uri);
72
73 if (lookups->handle)
74 GNUNET_CONTAINER_DLL_remove(
75 lookups->handle->lookups_head,
76 lookups->handle->lookups_tail,
77 lookups
78 );
79
80 GNUNET_free(lookups);
81}
82
44struct GNUNET_CHAT_HandleIterateContacts 83struct GNUNET_CHAT_HandleIterateContacts
45{ 84{
46 struct GNUNET_CHAT_Handle *handle; 85 struct GNUNET_CHAT_Handle *handle;
diff --git a/src/gnunet_chat_lobby.c b/src/gnunet_chat_lobby.c
new file mode 100644
index 0000000..e656ebb
--- /dev/null
+++ b/src/gnunet_chat_lobby.c
@@ -0,0 +1,130 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_lobby.c
23 */
24
25#include "gnunet_chat_lobby.h"
26
27#include "gnunet_chat_handle.h"
28#include "gnunet_chat_lobby_intern.c"
29
30struct GNUNET_CHAT_Lobby*
31lobby_create (struct GNUNET_CHAT_Handle *handle)
32{
33 GNUNET_assert(handle);
34
35 struct GNUNET_CHAT_Lobby *lobby = GNUNET_new(struct GNUNET_CHAT_Lobby);
36
37 lobby->handle = handle;
38 lobby->context = NULL;
39 lobby->uri = NULL;
40
41 lobby->op_create = NULL;
42 lobby->op_delete = NULL;
43
44 lobby->expiration = GNUNET_TIME_absolute_get_forever_();
45 lobby->callback = NULL;
46 lobby->cls = NULL;
47
48 return lobby;
49}
50
51void
52lobby_destroy (struct GNUNET_CHAT_Lobby *lobby)
53{
54 GNUNET_assert(lobby);
55
56 if (lobby->op_create)
57 GNUNET_IDENTITY_cancel(lobby->op_create);
58
59 if (lobby->op_delete)
60 GNUNET_IDENTITY_cancel(lobby->op_delete);
61
62 if (lobby->uri)
63 uri_destroy(lobby->uri);
64
65 if (lobby->context)
66 context_destroy(lobby->context);
67
68 GNUNET_free(lobby);
69}
70
71void
72lobby_open (struct GNUNET_CHAT_Lobby *lobby,
73 struct GNUNET_TIME_Relative delay,
74 GNUNET_CHAT_LobbyCallback callback,
75 void *cls)
76{
77 GNUNET_assert(lobby);
78
79 char *name;
80
81 lobby->expiration = GNUNET_TIME_relative_to_absolute(delay);
82 lobby->callback = callback;
83 lobby->cls = cls;
84
85 if (lobby->op_create)
86 {
87 GNUNET_IDENTITY_cancel(lobby->op_create);
88 goto open_zone;
89 }
90
91 struct GNUNET_HashCode key;
92 GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, &key, sizeof(key));
93
94 struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room(
95 lobby->handle->messenger,
96 &key
97 );
98
99 if (!room)
100 return;
101
102 lobby->context = context_create_from_room(lobby->handle, room);
103
104 handle_send_room_name(lobby->handle, room);
105
106 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
107 lobby->handle->contexts, &key, lobby->context,
108 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
109 {
110 context_destroy(lobby->context);
111 lobby->context = NULL;
112
113 GNUNET_MESSENGER_close_room(room);
114 return;
115 }
116
117open_zone:
118 util_lobby_name(&key, &name);
119
120 lobby->op_create = GNUNET_IDENTITY_create(
121 lobby->handle->identity,
122 name,
123 NULL,
124 GNUNET_IDENTITY_TYPE_EDDSA,
125 cont_lobby_identity_create,
126 lobby
127 );
128
129 GNUNET_free(name);
130}
diff --git a/src/gnunet_chat_lobby.h b/src/gnunet_chat_lobby.h
new file mode 100644
index 0000000..e913134
--- /dev/null
+++ b/src/gnunet_chat_lobby.h
@@ -0,0 +1,66 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_lobby.h
23 */
24
25#ifndef GNUNET_CHAT_LOBBY_H_
26#define GNUNET_CHAT_LOBBY_H_
27
28#include <gnunet/platform.h>
29#include <gnunet/gnunet_common.h>
30#include <gnunet/gnunet_identity_service.h>
31#include <gnunet/gnunet_util_lib.h>
32
33#include "gnunet_chat_lib.h"
34
35struct GNUNET_CHAT_Handle;
36struct GNUNET_CHAT_Context;
37struct GNUNET_CHAT_Uri;
38
39struct GNUNET_CHAT_Lobby
40{
41 struct GNUNET_CHAT_Handle *handle;
42
43 struct GNUNET_CHAT_Context *context;
44 struct GNUNET_CHAT_Uri *uri;
45
46 struct GNUNET_IDENTITY_Operation *op_create;
47 struct GNUNET_IDENTITY_Operation *op_delete;
48
49 struct GNUNET_TIME_Absolute expiration;
50 GNUNET_CHAT_LobbyCallback callback;
51 void *cls;
52};
53
54struct GNUNET_CHAT_Lobby*
55lobby_create (struct GNUNET_CHAT_Handle *handle);
56
57void
58lobby_destroy (struct GNUNET_CHAT_Lobby *lobby);
59
60void
61lobby_open (struct GNUNET_CHAT_Lobby *lobby,
62 struct GNUNET_TIME_Relative delay,
63 GNUNET_CHAT_LobbyCallback callback,
64 void *cls);
65
66#endif /* GNUNET_CHAT_LOBBY_H_ */
diff --git a/src/gnunet_chat_lobby_intern.c b/src/gnunet_chat_lobby_intern.c
new file mode 100644
index 0000000..2c10175
--- /dev/null
+++ b/src/gnunet_chat_lobby_intern.c
@@ -0,0 +1,157 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_lobby_intern.c
23 */
24
25#include "gnunet_chat_context.h"
26
27void
28cont_lobby_write_records (void *cls,
29 GNUNET_UNUSED int32_t success,
30 const char *emsg)
31{
32 struct GNUNET_CHAT_Lobby *lobby = cls;
33
34 if (!emsg)
35 goto call_cb;
36
37 handle_send_internal_message(
38 lobby->handle,
39 lobby->context,
40 GNUNET_CHAT_FLAG_WARNING,
41 emsg
42 );
43
44 if (lobby->uri)
45 uri_destroy(lobby->uri);
46
47 lobby->uri = NULL;
48
49call_cb:
50 if (lobby->callback)
51 lobby->callback(lobby->cls, lobby->uri);
52}
53
54void
55cont_lobby_identity_delete (void *cls,
56 const char *emsg)
57{
58 struct GNUNET_CHAT_Lobby *lobby = cls;
59
60 if (!emsg)
61 return;
62
63 handle_send_internal_message(
64 lobby->handle,
65 lobby->context,
66 GNUNET_CHAT_FLAG_WARNING,
67 emsg
68 );
69}
70
71void
72cont_lobby_identity_create (void *cls,
73 const struct GNUNET_IDENTITY_PrivateKey *zone,
74 const char *emsg)
75{
76 struct GNUNET_CHAT_Lobby *lobby = cls;
77
78 char *name;
79
80 if (emsg)
81 {
82 handle_send_internal_message(
83 lobby->handle,
84 NULL,
85 GNUNET_CHAT_FLAG_WARNING,
86 emsg
87 );
88
89 return;
90 }
91
92 struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room(
93 lobby->handle->messenger,
94 NULL
95 );
96
97 if (!room)
98 goto destroy_identity;
99
100 const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room);
101
102 lobby->context = context_create_from_room(lobby->handle, room);
103
104 handle_send_room_name(lobby->handle, room);
105
106 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
107 lobby->handle->contexts, key, lobby->context,
108 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
109 {
110 context_destroy(lobby->context);
111 lobby->context = NULL;
112 goto destroy_identity;
113 }
114
115 struct GNUNET_GNSRECORD_Data data [3];
116 data[0].record_type = GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY;
117 data[0].data = &room;
118 data[0].data_size = sizeof(room);
119 data[0].expiration_time = lobby->expiration.abs_value_us;
120 data[0].flags = GNUNET_GNSRECORD_RF_NONE;
121
122 if (lobby->uri)
123 uri_destroy(lobby->uri);
124
125 struct GNUNET_IDENTITY_PublicKey public_zone;
126 GNUNET_IDENTITY_key_get_public(zone, &public_zone);
127
128 char *label;
129 util_get_context_label(lobby->context->type, key, &label);
130
131 lobby->uri = uri_create(&public_zone, label);
132 GNUNET_free(label);
133
134 GNUNET_NAMESTORE_records_store(
135 lobby->handle->namestore,
136 zone,
137 lobby->uri->label,
138 1,
139 data,
140 cont_lobby_write_records,
141 lobby
142 );
143
144 context_write_records(lobby->context);
145
146destroy_identity:
147 util_lobby_name(key, &name);
148
149 lobby->op_delete = GNUNET_IDENTITY_delete(
150 lobby->handle->identity,
151 name,
152 cont_lobby_identity_delete,
153 lobby
154 );
155
156 GNUNET_free(name);
157}
diff --git a/src/gnunet_chat_uri.c b/src/gnunet_chat_uri.c
new file mode 100644
index 0000000..cc29756
--- /dev/null
+++ b/src/gnunet_chat_uri.c
@@ -0,0 +1,51 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_uri.c
23 */
24
25#include "gnunet_chat_uri.h"
26
27struct GNUNET_CHAT_Uri*
28uri_create (const struct GNUNET_IDENTITY_PublicKey *zone,
29 const char *label)
30{
31 GNUNET_assert((zone) && (label));
32
33 struct GNUNET_CHAT_Uri *uri = GNUNET_new(struct GNUNET_CHAT_Uri);
34
35 GNUNET_memcpy(&(uri->zone), zone, sizeof(uri->zone));
36
37 uri->label = GNUNET_strdup(label);
38
39 return uri;
40}
41
42void
43uri_destroy (struct GNUNET_CHAT_Uri *uri)
44{
45 GNUNET_assert(uri);
46
47 if (uri->label)
48 GNUNET_free(uri->label);
49
50 GNUNET_free(uri);
51}
diff --git a/src/gnunet_chat_uri.h b/src/gnunet_chat_uri.h
new file mode 100644
index 0000000..0074123
--- /dev/null
+++ b/src/gnunet_chat_uri.h
@@ -0,0 +1,48 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_uri.h
23 */
24
25#ifndef GNUNET_CHAT_URI_H_
26#define GNUNET_CHAT_URI_H_
27
28#include <gnunet/platform.h>
29#include <gnunet/gnunet_common.h>
30#include <gnunet/gnunet_identity_service.h>
31#include <gnunet/gnunet_util_lib.h>
32
33#include "gnunet_chat_util.h"
34
35struct GNUNET_CHAT_Uri
36{
37 struct GNUNET_IDENTITY_PublicKey zone;
38 char *label;
39};
40
41struct GNUNET_CHAT_Uri*
42uri_create (const struct GNUNET_IDENTITY_PublicKey *zone,
43 const char *label);
44
45void
46uri_destroy (struct GNUNET_CHAT_Uri *uri);
47
48#endif /* GNUNET_CHAT_URI_H_ */
diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c
index 5fde9a3..ae70918 100644
--- a/src/gnunet_chat_util.c
+++ b/src/gnunet_chat_util.c
@@ -286,3 +286,40 @@ util_get_filename (const char *directory,
286 GNUNET_free(dirname); 286 GNUNET_free(dirname);
287 return result; 287 return result;
288} 288}
289
290int
291util_get_context_label (enum GNUNET_CHAT_ContextType type,
292 const struct GNUNET_HashCode *hash,
293 char **label)
294{
295 const char *type_string = "chat";
296
297 switch (type)
298 {
299 case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
300 type_string = "contact";
301 break;
302 case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
303 type_string = "group";
304 break;
305 default:
306 break;
307 }
308
309 return GNUNET_asprintf (
310 label,
311 "%s_%s",
312 type_string,
313 GNUNET_h2s(hash)
314 );
315}
316
317int util_lobby_name (const struct GNUNET_HashCode *hash,
318 char **name)
319{
320 return GNUNET_asprintf (
321 name,
322 "chat_lobby_%s",
323 GNUNET_h2s(hash)
324 );
325}
diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h
index 74d1259..c94c32c 100644
--- a/src/gnunet_chat_util.h
+++ b/src/gnunet_chat_util.h
@@ -32,6 +32,13 @@
32#include <gnunet/gnunet_messenger_service.h> 32#include <gnunet/gnunet_messenger_service.h>
33#include <gnunet/gnunet_util_lib.h> 33#include <gnunet/gnunet_util_lib.h>
34 34
35enum GNUNET_CHAT_ContextType
36{
37 GNUNET_CHAT_CONTEXT_TYPE_CONTACT = 1,
38 GNUNET_CHAT_CONTEXT_TYPE_GROUP = 2,
39 GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN = 0
40};
41
35void 42void
36util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member, 43util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member,
37 struct GNUNET_ShortHashCode *shorthash); 44 struct GNUNET_ShortHashCode *shorthash);
@@ -63,4 +70,12 @@ util_get_filename (const char *directory,
63 const struct GNUNET_HashCode *hash, 70 const struct GNUNET_HashCode *hash,
64 char **filename); 71 char **filename);
65 72
73int
74util_get_context_label (enum GNUNET_CHAT_ContextType type,
75 const struct GNUNET_HashCode *hash,
76 char **label);
77
78int util_lobby_name (const struct GNUNET_HashCode *hash,
79 char **name);
80
66#endif /* GNUNET_CHAT_UTIL_H_ */ 81#endif /* GNUNET_CHAT_UTIL_H_ */