diff options
author | Gabor X Toth <*@tg-x.net> | 2015-12-17 14:12:44 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2015-12-17 14:12:44 +0000 |
commit | c159ab01bd16e9f3ad1776fa6fb26398cb7986d9 (patch) | |
tree | 61b0cad0b3e94f7e2dc7a8b48de7dc24784e229d /src/social | |
parent | 6cf89fa848bbcb9e1f941bad1ac0c4ec6066fdd7 (diff) | |
download | gnunet-c159ab01bd16e9f3ad1776fa6fb26398cb7986d9.tar.gz gnunet-c159ab01bd16e9f3ad1776fa6fb26398cb7986d9.zip |
social: API changes for application connections: store/load app subscriptions to places
Diffstat (limited to 'src/social')
-rw-r--r-- | src/social/Makefile.am | 9 | ||||
-rw-r--r-- | src/social/gnunet-service-social.c | 1361 | ||||
-rw-r--r-- | src/social/social.h | 181 | ||||
-rw-r--r-- | src/social/social_api.c | 1233 | ||||
-rw-r--r-- | src/social/test_social.c | 356 |
5 files changed, 2312 insertions, 828 deletions
diff --git a/src/social/Makefile.am b/src/social/Makefile.am index 2c8d5707d..ac80d0c8c 100644 --- a/src/social/Makefile.am +++ b/src/social/Makefile.am | |||
@@ -25,11 +25,6 @@ libgnunetsocial_la_SOURCES = \ | |||
25 | libgnunetsocial_la_LIBADD = \ | 25 | libgnunetsocial_la_LIBADD = \ |
26 | $(top_builddir)/src/util/libgnunetutil.la \ | 26 | $(top_builddir)/src/util/libgnunetutil.la \ |
27 | $(top_builddir)/src/env/libgnunetenv.la \ | 27 | $(top_builddir)/src/env/libgnunetenv.la \ |
28 | $(top_builddir)/src/psycstore/libgnunetpsycutil.la \ | ||
29 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
30 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
31 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
32 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
33 | $(GN_LIBINTL) $(XLIB) | 28 | $(GN_LIBINTL) $(XLIB) |
34 | libgnunetsocial_la_LDFLAGS = \ | 29 | libgnunetsocial_la_LDFLAGS = \ |
35 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | 30 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ |
@@ -47,6 +42,10 @@ gnunet_service_social_LDADD = \ | |||
47 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 42 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
48 | $(top_builddir)/src/psyc/libgnunetpsyc.la \ | 43 | $(top_builddir)/src/psyc/libgnunetpsyc.la \ |
49 | $(top_builddir)/src/psycstore/libgnunetpsycutil.la \ | 44 | $(top_builddir)/src/psycstore/libgnunetpsycutil.la \ |
45 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
46 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
47 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
48 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
50 | $(GN_LIBINTL) | 49 | $(GN_LIBINTL) |
51 | 50 | ||
52 | 51 | ||
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c index aace01fed..b7cf1f856 100644 --- a/src/social/gnunet-service-social.c +++ b/src/social/gnunet-service-social.c | |||
@@ -25,11 +25,16 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <inttypes.h> | 27 | #include <inttypes.h> |
28 | #include <strings.h> | ||
28 | 29 | ||
29 | #include "platform.h" | 30 | #include "platform.h" |
30 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_constants.h" | 32 | #include "gnunet_constants.h" |
32 | #include "gnunet_protocols.h" | 33 | #include "gnunet_protocols.h" |
34 | #include "gnunet_core_service.h" | ||
35 | #include "gnunet_identity_service.h" | ||
36 | #include "gnunet_namestore_service.h" | ||
37 | #include "gnunet_gns_service.h" | ||
33 | #include "gnunet_statistics_service.h" | 38 | #include "gnunet_statistics_service.h" |
34 | #include "gnunet_psyc_service.h" | 39 | #include "gnunet_psyc_service.h" |
35 | #include "gnunet_psyc_util_lib.h" | 40 | #include "gnunet_psyc_util_lib.h" |
@@ -42,10 +47,17 @@ | |||
42 | */ | 47 | */ |
43 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 48 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
44 | 49 | ||
50 | /* Handles to other services */ | ||
51 | static struct GNUNET_CORE_Handle *core; | ||
52 | static struct GNUNET_IDENTITY_Handle *id; | ||
53 | static struct GNUNET_GNS_Handle *gns; | ||
54 | static struct GNUNET_NAMESTORE_Handle *namestore; | ||
55 | static struct GNUNET_STATISTICS_Handle *stats; | ||
56 | |||
45 | /** | 57 | /** |
46 | * Handle to the statistics service. | 58 | * ID of this peer. |
47 | */ | 59 | */ |
48 | static struct GNUNET_STATISTICS_Handle *stats; | 60 | static struct GNUNET_PeerIdentity this_peer; |
49 | 61 | ||
50 | /** | 62 | /** |
51 | * Notification context, simplifies client broadcasts. | 63 | * Notification context, simplifies client broadcasts. |
@@ -66,7 +78,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *guests; | |||
66 | 78 | ||
67 | /** | 79 | /** |
68 | * Connected guests per place. | 80 | * Connected guests per place. |
69 | * H(place_pub_key) -> Guest's pub_key -> struct Guest | 81 | * H(place_pub_key) -> ego_pub_key -> struct Guest |
70 | */ | 82 | */ |
71 | static struct GNUNET_CONTAINER_MultiHashMap *place_guests; | 83 | static struct GNUNET_CONTAINER_MultiHashMap *place_guests; |
72 | 84 | ||
@@ -74,19 +86,44 @@ static struct GNUNET_CONTAINER_MultiHashMap *place_guests; | |||
74 | * Places entered as host or guest. | 86 | * Places entered as host or guest. |
75 | * H(place_pub_key) -> struct HostEnterRequest OR struct GuestEnterRequest | 87 | * H(place_pub_key) -> struct HostEnterRequest OR struct GuestEnterRequest |
76 | */ | 88 | */ |
77 | static struct GNUNET_CONTAINER_MultiHashMap *places_entered; | 89 | static struct GNUNET_CONTAINER_MultiHashMap *places; |
90 | |||
91 | /** | ||
92 | * Places entered per application. | ||
93 | * H(app_id) -> H(place_pub_key) -> NULL | ||
94 | */ | ||
95 | static struct GNUNET_CONTAINER_MultiHashMap *apps_places; | ||
96 | |||
97 | /** | ||
98 | * Connected applications. | ||
99 | * H(app_id) -> struct Application | ||
100 | */ | ||
101 | static struct GNUNET_CONTAINER_MultiHashMap *apps; | ||
102 | |||
103 | /** | ||
104 | * All egos. | ||
105 | * H(ego_pub_key) -> struct Ego | ||
106 | */ | ||
107 | static struct GNUNET_CONTAINER_MultiHashMap *egos; | ||
78 | 108 | ||
79 | /** | 109 | /** |
80 | * Place listener clients. | 110 | * Directory for storing social data. |
81 | * H(ego_pub_key) -> struct PlaceListener | 111 | * Default: ~/.local/share/gnunet/social |
82 | */ | 112 | */ |
83 | static struct GNUNET_CONTAINER_MultiHashMap *place_listeners; | 113 | static char *dir_social; |
84 | 114 | ||
85 | /** | 115 | /** |
86 | * Directory for storing places. | 116 | * Directory for storing place data. |
117 | * $dir_social/places | ||
87 | */ | 118 | */ |
88 | static char *dir_places; | 119 | static char *dir_places; |
89 | 120 | ||
121 | /** | ||
122 | * Directory for storing app data. | ||
123 | * $dir_social/apps | ||
124 | */ | ||
125 | static char *dir_apps; | ||
126 | |||
90 | 127 | ||
91 | /** | 128 | /** |
92 | * Message fragment transmission queue. | 129 | * Message fragment transmission queue. |
@@ -157,7 +194,12 @@ struct Place | |||
157 | struct GNUNET_PSYC_Channel *channel; | 194 | struct GNUNET_PSYC_Channel *channel; |
158 | 195 | ||
159 | /** | 196 | /** |
160 | * Public key of the channel. | 197 | * Private key of home in case of a host. |
198 | */ | ||
199 | struct GNUNET_CRYPTO_EddsaPublicKey key; | ||
200 | |||
201 | /** | ||
202 | * Public key of place. | ||
161 | */ | 203 | */ |
162 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | 204 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; |
163 | 205 | ||
@@ -167,6 +209,21 @@ struct Place | |||
167 | struct GNUNET_HashCode pub_key_hash; | 209 | struct GNUNET_HashCode pub_key_hash; |
168 | 210 | ||
169 | /** | 211 | /** |
212 | * Private key of ego. | ||
213 | */ | ||
214 | struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key; | ||
215 | |||
216 | /** | ||
217 | * Public key of ego. | ||
218 | */ | ||
219 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
220 | |||
221 | /** | ||
222 | * Hash of @a ego_pub_key. | ||
223 | */ | ||
224 | struct GNUNET_HashCode ego_pub_hash; | ||
225 | |||
226 | /** | ||
170 | * Last message ID received for the place. | 227 | * Last message ID received for the place. |
171 | * 0 if there is no such message. | 228 | * 0 if there is no such message. |
172 | */ | 229 | */ |
@@ -202,11 +259,6 @@ struct Host | |||
202 | struct Place plc; | 259 | struct Place plc; |
203 | 260 | ||
204 | /** | 261 | /** |
205 | * Private key of the channel. | ||
206 | */ | ||
207 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; | ||
208 | |||
209 | /** | ||
210 | * Handle for the multicast origin. | 262 | * Handle for the multicast origin. |
211 | */ | 263 | */ |
212 | struct GNUNET_PSYC_Master *master; | 264 | struct GNUNET_PSYC_Master *master; |
@@ -240,21 +292,6 @@ struct Guest | |||
240 | struct Place plc; | 292 | struct Place plc; |
241 | 293 | ||
242 | /** | 294 | /** |
243 | * Private key of the slave. | ||
244 | */ | ||
245 | struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; | ||
246 | |||
247 | /** | ||
248 | * Public key of the slave. | ||
249 | */ | ||
250 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | ||
251 | |||
252 | /** | ||
253 | * Hash of @a pub_key. | ||
254 | */ | ||
255 | struct GNUNET_HashCode pub_key_hash; | ||
256 | |||
257 | /** | ||
258 | * Handle for the PSYC slave. | 295 | * Handle for the PSYC slave. |
259 | */ | 296 | */ |
260 | struct GNUNET_PSYC_Slave *slave; | 297 | struct GNUNET_PSYC_Slave *slave; |
@@ -293,7 +330,7 @@ struct Guest | |||
293 | 330 | ||
294 | 331 | ||
295 | /** | 332 | /** |
296 | * Context for host/guest client. | 333 | * Context for a client. |
297 | */ | 334 | */ |
298 | struct Client | 335 | struct Client |
299 | { | 336 | { |
@@ -309,19 +346,25 @@ struct Client | |||
309 | struct MessageTransmitQueue *tmit_msg; | 346 | struct MessageTransmitQueue *tmit_msg; |
310 | 347 | ||
311 | /** | 348 | /** |
312 | * Ego key for listener clients; | 349 | * ID for application clients. |
313 | */ | 350 | */ |
314 | struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key; | 351 | char *app_id; |
315 | }; | 352 | }; |
316 | 353 | ||
317 | 354 | ||
318 | struct PlaceListener | 355 | struct Application |
319 | { | 356 | { |
320 | struct ClientListItem *clients_head; | 357 | struct ClientListItem *clients_head; |
321 | struct ClientListItem *clients_tail; | 358 | struct ClientListItem *clients_tail; |
322 | }; | 359 | }; |
323 | 360 | ||
324 | 361 | ||
362 | struct Ego { | ||
363 | struct GNUNET_CRYPTO_EcdsaPrivateKey key; | ||
364 | char *name; | ||
365 | }; | ||
366 | |||
367 | |||
325 | struct OperationClosure | 368 | struct OperationClosure |
326 | { | 369 | { |
327 | struct GNUNET_SERVER_Client *client; | 370 | struct GNUNET_SERVER_Client *client; |
@@ -335,6 +378,18 @@ static int | |||
335 | psyc_transmit_message (struct Place *plc); | 378 | psyc_transmit_message (struct Place *plc); |
336 | 379 | ||
337 | 380 | ||
381 | static void | ||
382 | cleanup_place (struct Place *plc); | ||
383 | |||
384 | |||
385 | int | ||
386 | place_entry_cleanup (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
387 | { | ||
388 | cleanup_place (value); | ||
389 | return GNUNET_YES; | ||
390 | } | ||
391 | |||
392 | |||
338 | /** | 393 | /** |
339 | * Task run during shutdown. | 394 | * Task run during shutdown. |
340 | * | 395 | * |
@@ -344,11 +399,34 @@ psyc_transmit_message (struct Place *plc); | |||
344 | static void | 399 | static void |
345 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 400 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
346 | { | 401 | { |
402 | GNUNET_CONTAINER_multihashmap_iterate (hosts, place_entry_cleanup, NULL); | ||
403 | GNUNET_CONTAINER_multihashmap_iterate (guests, place_entry_cleanup, NULL); | ||
404 | |||
347 | if (NULL != nc) | 405 | if (NULL != nc) |
348 | { | 406 | { |
349 | GNUNET_SERVER_notification_context_destroy (nc); | 407 | GNUNET_SERVER_notification_context_destroy (nc); |
350 | nc = NULL; | 408 | nc = NULL; |
351 | } | 409 | } |
410 | if (NULL != core) | ||
411 | { | ||
412 | GNUNET_CORE_disconnect (core); | ||
413 | core = NULL; | ||
414 | } | ||
415 | if (NULL != id) | ||
416 | { | ||
417 | GNUNET_IDENTITY_disconnect (id); | ||
418 | id = NULL; | ||
419 | } | ||
420 | if (NULL != namestore) | ||
421 | { | ||
422 | GNUNET_NAMESTORE_disconnect (namestore); | ||
423 | namestore = NULL; | ||
424 | } | ||
425 | if (NULL != gns) | ||
426 | { | ||
427 | GNUNET_GNS_disconnect (gns); | ||
428 | gns = NULL; | ||
429 | } | ||
352 | if (NULL != stats) | 430 | if (NULL != stats) |
353 | { | 431 | { |
354 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | 432 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); |
@@ -383,7 +461,7 @@ cleanup_guest (struct Guest *gst) | |||
383 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, | 461 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, |
384 | &plc->pub_key_hash); | 462 | &plc->pub_key_hash); |
385 | GNUNET_assert (NULL != plc_gst); // FIXME | 463 | GNUNET_assert (NULL != plc_gst); // FIXME |
386 | GNUNET_CONTAINER_multihashmap_remove (plc_gst, &gst->pub_key_hash, gst); | 464 | GNUNET_CONTAINER_multihashmap_remove (plc_gst, &plc->ego_pub_hash, gst); |
387 | 465 | ||
388 | if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst)) | 466 | if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst)) |
389 | { | 467 | { |
@@ -444,15 +522,20 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
444 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); | 522 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); |
445 | if (NULL == ctx) | 523 | if (NULL == ctx) |
446 | { | 524 | { |
447 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 525 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
448 | "%p User context is NULL in client_disconnect()\n", ctx); | 526 | "%p User context is NULL in client_disconnect()\n", ctx); |
449 | GNUNET_break (0); | ||
450 | return; | 527 | return; |
451 | } | 528 | } |
452 | 529 | ||
453 | struct Place *plc = ctx->plc; | 530 | struct Place *plc = ctx->plc; |
531 | |||
532 | if (NULL != ctx->app_id) | ||
533 | GNUNET_free (ctx->app_id); | ||
534 | |||
535 | GNUNET_free (ctx); | ||
536 | |||
454 | if (NULL == plc) | 537 | if (NULL == plc) |
455 | return; // place listener client, nothing to do | 538 | return; // application client, nothing to do |
456 | 539 | ||
457 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
458 | "%p Client (%s) disconnected from place %s\n", | 541 | "%p Client (%s) disconnected from place %s\n", |
@@ -470,40 +553,35 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
470 | } | 553 | } |
471 | cli = cli->next; | 554 | cli = cli->next; |
472 | } | 555 | } |
556 | } | ||
473 | 557 | ||
474 | if (NULL == plc->clients_head) | 558 | |
475 | { /* Last client disconnected. */ | 559 | /** |
476 | if (GNUNET_YES != plc->is_disconnected) | 560 | * Send message to a client. |
477 | { | 561 | */ |
478 | plc->is_disconnected = GNUNET_YES; | 562 | static inline void |
479 | if (NULL != plc->tmit_msgs_head) | 563 | client_send_msg (struct GNUNET_SERVER_Client *client, |
480 | { /* Send pending messages to PSYC before cleanup. */ | 564 | const struct GNUNET_MessageHeader *msg) |
481 | psyc_transmit_message (plc); | 565 | { |
482 | } | 566 | GNUNET_SERVER_notification_context_add (nc, client); |
483 | else | 567 | GNUNET_SERVER_notification_context_unicast (nc, client, msg, GNUNET_NO); |
484 | { | ||
485 | cleanup_place (plc); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | 568 | } |
490 | 569 | ||
491 | 570 | ||
492 | /** | 571 | /** |
493 | * Send message to all clients connected to the channel. | 572 | * Send message to all clients connected to a place. |
494 | */ | 573 | */ |
495 | static void | 574 | static void |
496 | client_send_msg (const struct Place *plc, | 575 | place_send_msg (const struct Place *plc, |
497 | const struct GNUNET_MessageHeader *msg) | 576 | const struct GNUNET_MessageHeader *msg) |
498 | { | 577 | { |
499 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
500 | "%p Sending message to clients.\n", plc); | 579 | "%p Sending message to clients of place.\n", plc); |
501 | 580 | ||
502 | struct ClientListItem *cli = plc->clients_head; | 581 | struct ClientListItem *cli = plc->clients_head; |
503 | while (NULL != cli) | 582 | while (NULL != cli) |
504 | { | 583 | { |
505 | GNUNET_SERVER_notification_context_add (nc, cli->client); | 584 | client_send_msg (cli->client, msg); |
506 | GNUNET_SERVER_notification_context_unicast (nc, cli->client, msg, GNUNET_NO); | ||
507 | cli = cli->next; | 585 | cli = cli->next; |
508 | } | 586 | } |
509 | } | 587 | } |
@@ -542,13 +620,31 @@ client_send_result (struct GNUNET_SERVER_Client *client, uint64_t op_id, | |||
542 | "%" PRId64 " (size: %u)\n", | 620 | "%" PRId64 " (size: %u)\n", |
543 | client, GNUNET_ntohll (op_id), result_code, data_size); | 621 | client, GNUNET_ntohll (op_id), result_code, data_size); |
544 | 622 | ||
545 | GNUNET_SERVER_notification_context_add (nc, client); | 623 | client_send_msg (client, &res->header); |
546 | GNUNET_SERVER_notification_context_unicast (nc, client, &res->header, | ||
547 | GNUNET_NO); | ||
548 | GNUNET_free (res); | 624 | GNUNET_free (res); |
549 | } | 625 | } |
550 | 626 | ||
551 | 627 | ||
628 | static void | ||
629 | client_send_host_enter_ack (struct GNUNET_SERVER_Client *client, | ||
630 | struct Host *hst, uint32_t result) | ||
631 | { | ||
632 | struct Place *plc = &hst->plc; | ||
633 | |||
634 | struct HostEnterAck hack; | ||
635 | hack.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); | ||
636 | hack.header.size = htons (sizeof (hack)); | ||
637 | hack.result_code = htonl (result); | ||
638 | hack.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
639 | hack.place_pub_key = plc->pub_key; | ||
640 | |||
641 | if (NULL != client) | ||
642 | client_send_msg (client, &hack.header); | ||
643 | else | ||
644 | place_send_msg (plc, &hack.header); | ||
645 | } | ||
646 | |||
647 | |||
552 | /** | 648 | /** |
553 | * Called after a PSYC master is started. | 649 | * Called after a PSYC master is started. |
554 | */ | 650 | */ |
@@ -560,13 +656,7 @@ psyc_master_started (void *cls, int result, uint64_t max_message_id) | |||
560 | plc->max_message_id = max_message_id; | 656 | plc->max_message_id = max_message_id; |
561 | plc->is_ready = GNUNET_YES; | 657 | plc->is_ready = GNUNET_YES; |
562 | 658 | ||
563 | struct GNUNET_PSYC_CountersResultMessage res; | 659 | client_send_host_enter_ack (NULL, hst, result); |
564 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); | ||
565 | res.header.size = htons (sizeof (res)); | ||
566 | res.result_code = htonl (result); | ||
567 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
568 | |||
569 | client_send_msg (plc, &res.header); | ||
570 | } | 660 | } |
571 | 661 | ||
572 | 662 | ||
@@ -585,7 +675,7 @@ psyc_recv_join_request (void *cls, | |||
585 | GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash); | 675 | GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash); |
586 | GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh, | 676 | GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh, |
587 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 677 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
588 | client_send_msg (&hst->plc, &req->header); | 678 | place_send_msg (&hst->plc, &req->header); |
589 | } | 679 | } |
590 | 680 | ||
591 | 681 | ||
@@ -606,7 +696,7 @@ psyc_slave_connected (void *cls, int result, uint64_t max_message_id) | |||
606 | res.result_code = htonl (result); | 696 | res.result_code = htonl (result); |
607 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | 697 | res.max_message_id = GNUNET_htonll (plc->max_message_id); |
608 | 698 | ||
609 | client_send_msg (plc, &res.header); | 699 | place_send_msg (plc, &res.header); |
610 | } | 700 | } |
611 | 701 | ||
612 | 702 | ||
@@ -620,7 +710,7 @@ psyc_recv_join_dcsn (void *cls, | |||
620 | const struct GNUNET_PSYC_Message *join_msg) | 710 | const struct GNUNET_PSYC_Message *join_msg) |
621 | { | 711 | { |
622 | struct Guest *gst = cls; | 712 | struct Guest *gst = cls; |
623 | client_send_msg (&gst->plc, &dcsn->header); | 713 | place_send_msg (&gst->plc, &dcsn->header); |
624 | } | 714 | } |
625 | 715 | ||
626 | 716 | ||
@@ -641,7 +731,7 @@ psyc_recv_message (void *cls, | |||
641 | plc, ntohs (msg->header.size), str); | 731 | plc, ntohs (msg->header.size), str); |
642 | GNUNET_free (str); | 732 | GNUNET_free (str); |
643 | 733 | ||
644 | client_send_msg (plc, &msg->header); | 734 | place_send_msg (plc, &msg->header); |
645 | 735 | ||
646 | /* FIXME: further processing */ | 736 | /* FIXME: further processing */ |
647 | } | 737 | } |
@@ -656,110 +746,219 @@ place_init (struct Place *plc) | |||
656 | 746 | ||
657 | } | 747 | } |
658 | 748 | ||
749 | /** | ||
750 | * Add a place to the @e places hash map. | ||
751 | * | ||
752 | * @param ereq | ||
753 | * Entry request. | ||
754 | * | ||
755 | * @return #GNUNET_OK if the place was added | ||
756 | * #GNUNET_NO if the place already exists in the hash map | ||
757 | * #GNUNET_SYSERR on error | ||
758 | */ | ||
759 | static int | ||
760 | place_add (const struct PlaceEnterRequest *ereq) | ||
761 | { | ||
762 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
763 | "Adding place to hashmap:\n"); | ||
764 | |||
765 | struct EgoPlacePublicKey ego_place_pub_key = { | ||
766 | .ego_pub_key = ereq->ego_pub_key, | ||
767 | .place_pub_key = ereq->place_pub_key, | ||
768 | }; | ||
769 | struct GNUNET_HashCode ego_place_pub_hash; | ||
770 | GNUNET_CRYPTO_hash (&ego_place_pub_key, sizeof (ego_place_pub_key), &ego_place_pub_hash); | ||
771 | |||
772 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
773 | " ego_place_pub_hash = %s\n", GNUNET_h2s (&ego_place_pub_hash)); | ||
774 | |||
775 | struct GNUNET_MessageHeader * | ||
776 | place_msg = GNUNET_CONTAINER_multihashmap_get (places, &ego_place_pub_hash); | ||
777 | if (NULL != place_msg) | ||
778 | return GNUNET_NO; | ||
779 | |||
780 | place_msg = GNUNET_copy_message (&ereq->header); | ||
781 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (places, &ego_place_pub_hash, place_msg, | ||
782 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
783 | { | ||
784 | GNUNET_break (0); | ||
785 | GNUNET_free (place_msg); | ||
786 | return GNUNET_SYSERR; | ||
787 | } | ||
788 | |||
789 | return GNUNET_OK; | ||
790 | } | ||
659 | 791 | ||
660 | /** | 792 | /** |
661 | * Add place to places_entered hash map. | 793 | * Add a place to the @e app_places hash map. |
662 | * | 794 | * |
663 | * @param ego_pub_hash | 795 | * @param app_id |
664 | * H(ego_pub_key) | 796 | * Application ID. |
665 | * @param place_pub_hash | ||
666 | * H(place_pub_key) | ||
667 | * @param msg | 797 | * @param msg |
668 | * Entry message. | 798 | * Entry message. |
669 | * | 799 | * |
670 | * @return Return value of GNUNET_CONTAINER_multihashmap_put () | 800 | * @return #GNUNET_OK if the place was added |
801 | * #GNUNET_NO if the place already exists in the hash map | ||
802 | * #GNUNET_SYSERR on error | ||
671 | */ | 803 | */ |
672 | static int | 804 | static int |
673 | place_add (const struct GNUNET_HashCode *ego_pub_hash, | 805 | app_place_add (const char *app_id, |
674 | const struct GNUNET_HashCode *place_pub_hash, | 806 | const struct PlaceEnterRequest *ereq) |
675 | const struct GNUNET_MessageHeader *msg) | ||
676 | { | 807 | { |
677 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 808 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
678 | "Adding place to hashmap:\n"); | 809 | "Adding app place to hashmap:\n"); |
679 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 810 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
680 | " ego_pub_hash = %s\n", GNUNET_h2s (ego_pub_hash)); | 811 | " app_id = %s\n", app_id); |
812 | |||
813 | struct GNUNET_HashCode app_id_hash; | ||
814 | GNUNET_CRYPTO_hash (app_id, strlen (app_id) + 1, &app_id_hash); | ||
815 | |||
816 | struct EgoPlacePublicKey ego_place_pub_key = { | ||
817 | .ego_pub_key = ereq->ego_pub_key, | ||
818 | .place_pub_key = ereq->place_pub_key, | ||
819 | }; | ||
820 | struct GNUNET_HashCode ego_place_pub_hash; | ||
821 | GNUNET_CRYPTO_hash (&ego_place_pub_key, sizeof (ego_place_pub_key), &ego_place_pub_hash); | ||
822 | |||
681 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 823 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
682 | " place_pub_hash = %s\n", GNUNET_h2s (place_pub_hash)); | 824 | " ego_place_pub_hash = %s\n", GNUNET_h2s (&ego_place_pub_hash)); |
683 | 825 | ||
684 | struct GNUNET_CONTAINER_MultiHashMap * | 826 | struct GNUNET_CONTAINER_MultiHashMap * |
685 | ego_places = GNUNET_CONTAINER_multihashmap_get (places_entered, ego_pub_hash); | 827 | app_places = GNUNET_CONTAINER_multihashmap_get (apps_places, &app_id_hash); |
686 | if (NULL == ego_places) | 828 | if (NULL == app_places) |
687 | { | 829 | { |
688 | ego_places = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 830 | app_places = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
689 | GNUNET_CONTAINER_multihashmap_put (places_entered, ego_pub_hash, ego_places, | 831 | GNUNET_CONTAINER_multihashmap_put (apps_places, &app_id_hash, app_places, |
690 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 832 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
691 | } | 833 | } |
692 | 834 | ||
693 | struct GNUNET_MessageHeader *msg_old, *msg_new; | 835 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (app_places, &ego_place_pub_hash)) |
694 | if (NULL != (msg_old = GNUNET_CONTAINER_multihashmap_get (ego_places, place_pub_hash))) | 836 | return GNUNET_NO; |
837 | |||
838 | if (GNUNET_SYSERR == place_add (ereq)) | ||
839 | return GNUNET_SYSERR; | ||
840 | |||
841 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (app_places, &ego_place_pub_hash, | ||
842 | NULL, 0)) | ||
695 | { | 843 | { |
696 | GNUNET_free (msg_old); | 844 | GNUNET_break (0); |
697 | GNUNET_CONTAINER_multihashmap_remove_all (ego_places, place_pub_hash); | 845 | return GNUNET_SYSERR; |
698 | } | 846 | } |
699 | 847 | ||
700 | uint16_t msg_size = ntohs (msg->size); | 848 | return GNUNET_OK; |
701 | msg_new = GNUNET_malloc (msg_size); | ||
702 | memcpy (msg_new, msg, msg_size); | ||
703 | int ret = GNUNET_CONTAINER_multihashmap_put (ego_places, place_pub_hash, msg_new, | ||
704 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
705 | if (GNUNET_OK != ret) | ||
706 | GNUNET_break (0); | ||
707 | return ret; | ||
708 | } | 849 | } |
709 | 850 | ||
710 | 851 | ||
711 | /** | 852 | /** |
712 | * Save place entry message to disk. | 853 | * Save place entry message to disk. |
713 | * | 854 | * |
714 | * @param ego_key | 855 | * @param app_id |
715 | * Private key of ego. | 856 | * Application ID. |
716 | * @param place_pub_hash | ||
717 | * Hash of public key of place. | ||
718 | * @param msg | 857 | * @param msg |
719 | * Entry message. | 858 | * Entry message. |
720 | */ | 859 | */ |
721 | static void | 860 | static int |
722 | place_save (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ego_key, | 861 | app_place_save (const char *app_id, |
723 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub, | 862 | const struct PlaceEnterRequest *ereq) |
724 | const struct GNUNET_MessageHeader *msg) | ||
725 | { | 863 | { |
864 | app_place_add (app_id, ereq); | ||
865 | |||
726 | if (NULL == dir_places) | 866 | if (NULL == dir_places) |
727 | return; | 867 | return GNUNET_SYSERR; |
728 | 868 | ||
869 | struct GNUNET_HashCode ego_pub_hash; | ||
729 | struct GNUNET_HashCode place_pub_hash; | 870 | struct GNUNET_HashCode place_pub_hash; |
730 | GNUNET_CRYPTO_hash (place_pub, sizeof (place_pub), &place_pub_hash); | 871 | GNUNET_CRYPTO_hash (&ereq->ego_pub_key, sizeof (ereq->ego_pub_key), |
872 | &ego_pub_hash); | ||
873 | GNUNET_CRYPTO_hash (&ereq->place_pub_key, sizeof (ereq->place_pub_key), | ||
874 | &place_pub_hash); | ||
875 | |||
876 | struct GNUNET_CRYPTO_HashAsciiEncoded ego_pub_hash_ascii; | ||
877 | struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; | ||
878 | memcpy (&ego_pub_hash_ascii.encoding, | ||
879 | GNUNET_h2s_full (&ego_pub_hash), sizeof (ego_pub_hash_ascii)); | ||
880 | memcpy (&place_pub_hash_ascii.encoding, | ||
881 | GNUNET_h2s_full (&place_pub_hash), sizeof (place_pub_hash_ascii)); | ||
882 | |||
883 | char *filename = NULL; | ||
884 | GNUNET_asprintf (&filename, "%s%c" "%s%c" "%s%c" "%s", | ||
885 | dir_social, DIR_SEPARATOR, | ||
886 | "places", DIR_SEPARATOR, | ||
887 | ego_pub_hash_ascii.encoding, DIR_SEPARATOR, | ||
888 | place_pub_hash_ascii.encoding); | ||
889 | int ret = GNUNET_DISK_directory_create_for_file (filename); | ||
890 | if (GNUNET_OK != ret | ||
891 | || 0 > GNUNET_DISK_fn_write (filename, ereq, ntohs (ereq->header.size), | ||
892 | GNUNET_DISK_PERM_USER_READ | ||
893 | | GNUNET_DISK_PERM_USER_WRITE)) | ||
894 | { | ||
895 | GNUNET_break (0); | ||
896 | ret = GNUNET_SYSERR; | ||
897 | } | ||
898 | GNUNET_free (filename); | ||
731 | 899 | ||
732 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub; | 900 | if (ret == GNUNET_OK) |
733 | struct GNUNET_HashCode ego_pub_hash; | 901 | { |
734 | GNUNET_CRYPTO_ecdsa_key_get_public (ego_key, &ego_pub); | 902 | GNUNET_asprintf (&filename, "%s%c" "%s%c" "%s%c" "%s%c" "%s", |
735 | GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash); | 903 | dir_social, DIR_SEPARATOR, |
736 | 904 | "apps", DIR_SEPARATOR, | |
737 | place_add (&ego_pub_hash, &place_pub_hash, msg); | 905 | app_id, DIR_SEPARATOR, |
738 | 906 | ego_pub_hash_ascii.encoding, DIR_SEPARATOR, | |
739 | char *ego_pub_hash_str = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1); | 907 | place_pub_hash_ascii.encoding); |
740 | char *place_pub_hash_str = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1); | 908 | ret = GNUNET_DISK_directory_create_for_file (filename); |
741 | memcpy (ego_pub_hash_str, GNUNET_h2s_full (&ego_pub_hash), sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); | 909 | if (GNUNET_OK != ret |
742 | memcpy (place_pub_hash_str, GNUNET_h2s_full (&place_pub_hash), sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); | 910 | || 0 > GNUNET_DISK_fn_write (filename, "", 0, |
743 | 911 | GNUNET_DISK_PERM_USER_READ | |
744 | char *filename = GNUNET_malloc (strlen (dir_places) + 1 | 912 | | GNUNET_DISK_PERM_USER_WRITE)) |
745 | + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1 | 913 | { |
746 | + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1); | 914 | GNUNET_break (0); |
747 | GNUNET_asprintf (&filename, | 915 | ret = GNUNET_SYSERR; |
748 | "%s%s%s%s%s", | 916 | } |
749 | dir_places, DIR_SEPARATOR_STR, | 917 | GNUNET_free (filename); |
750 | ego_pub_hash_str, DIR_SEPARATOR_STR, | 918 | } |
751 | place_pub_hash_str); | 919 | return ret; |
920 | } | ||
921 | |||
922 | |||
923 | int | ||
924 | app_place_remove (const char *app_id, | ||
925 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key) | ||
926 | { | ||
927 | struct GNUNET_HashCode place_pub_hash; | ||
928 | GNUNET_CRYPTO_hash (place_pub_key, sizeof (*place_pub_key), &place_pub_hash); | ||
929 | |||
930 | struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; | ||
931 | memcpy (&place_pub_hash_ascii.encoding, | ||
932 | GNUNET_h2s_full (&place_pub_hash), sizeof (place_pub_hash_ascii)); | ||
933 | |||
934 | char *app_place_filename = NULL; | ||
935 | GNUNET_asprintf (&app_place_filename, | ||
936 | "%s%c" "%s%/", | ||
937 | dir_social, DIR_SEPARATOR, | ||
938 | "apps", DIR_SEPARATOR, | ||
939 | app_id, DIR_SEPARATOR, | ||
940 | place_pub_hash_ascii.encoding); | ||
941 | |||
942 | struct GNUNET_HashCode app_id_hash; | ||
943 | GNUNET_CRYPTO_hash (app_id, strlen (app_id) + 1, &app_id_hash); | ||
944 | |||
945 | struct GNUNET_CONTAINER_MultiHashMap * | ||
946 | app_places = GNUNET_CONTAINER_multihashmap_get (apps_places, &app_id_hash); | ||
752 | 947 | ||
753 | GNUNET_DISK_directory_create_for_file (filename); | 948 | if (NULL != app_places) |
754 | if (GNUNET_DISK_fn_write (filename, msg, ntohs (msg->size), | 949 | GNUNET_CONTAINER_multihashmap_remove (app_places, &place_pub_hash, NULL); |
755 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE) < 0) | 950 | |
951 | int ret = unlink (app_place_filename); | ||
952 | GNUNET_free (app_place_filename); | ||
953 | if (0 != ret) | ||
756 | { | 954 | { |
757 | GNUNET_break (0); | 955 | GNUNET_break (0); |
956 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
957 | "Error removing app place: unlink returned %d\n", errno); | ||
958 | return GNUNET_SYSERR; | ||
758 | } | 959 | } |
759 | 960 | ||
760 | GNUNET_free (ego_pub_hash_str); | 961 | return GNUNET_OK; |
761 | GNUNET_free (place_pub_hash_str); | ||
762 | GNUNET_free (filename); | ||
763 | } | 962 | } |
764 | 963 | ||
765 | 964 | ||
@@ -772,35 +971,34 @@ place_save (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ego_key, | |||
772 | * Returned Host struct. | 971 | * Returned Host struct. |
773 | * | 972 | * |
774 | * @return #GNUNET_YES if the host entered the place just now, | 973 | * @return #GNUNET_YES if the host entered the place just now, |
775 | * #GNUNET_NO if the place is already entered. | 974 | * #GNUNET_NO if the place is already entered, |
975 | * #GNUNET_SYSERR if place_pub_key was set | ||
976 | * but its private key was not found | ||
776 | */ | 977 | */ |
777 | static int | 978 | static int |
778 | host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst) | 979 | host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst) |
779 | { | 980 | { |
780 | int ret = GNUNET_NO; | 981 | int ret = GNUNET_NO; |
781 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub; | ||
782 | struct GNUNET_HashCode place_pub_hash; | 982 | struct GNUNET_HashCode place_pub_hash; |
783 | 983 | GNUNET_CRYPTO_hash (&hreq->place_pub_key, sizeof (hreq->place_pub_key), | |
784 | GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub); | 984 | &place_pub_hash); |
785 | GNUNET_CRYPTO_hash (&place_pub, sizeof (place_pub), &place_pub_hash); | ||
786 | |||
787 | struct Host *hst = GNUNET_CONTAINER_multihashmap_get (hosts, &place_pub_hash); | 985 | struct Host *hst = GNUNET_CONTAINER_multihashmap_get (hosts, &place_pub_hash); |
986 | |||
788 | if (NULL == hst) | 987 | if (NULL == hst) |
789 | { | 988 | { |
790 | hst = GNUNET_new (struct Host); | 989 | hst = GNUNET_new (struct Host); |
791 | hst->policy = ntohl (hreq->policy); | 990 | hst->policy = hreq->policy; |
792 | hst->priv_key = hreq->place_key; | ||
793 | hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 991 | hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
794 | 992 | ||
795 | struct Place *plc = &hst->plc; | 993 | struct Place *plc = &hst->plc; |
994 | place_init (plc); | ||
796 | plc->is_host = GNUNET_YES; | 995 | plc->is_host = GNUNET_YES; |
797 | plc->pub_key = place_pub; | 996 | plc->pub_key = hreq->place_pub_key; |
798 | plc->pub_key_hash = place_pub_hash; | 997 | plc->pub_key_hash = place_pub_hash; |
799 | place_init (plc); | ||
800 | 998 | ||
801 | GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, | 999 | GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, |
802 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 1000 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
803 | hst->master = GNUNET_PSYC_master_start (cfg, &hst->priv_key, hst->policy, | 1001 | hst->master = GNUNET_PSYC_master_start (cfg, &hreq->place_key, hst->policy, |
804 | &psyc_master_started, | 1002 | &psyc_master_started, |
805 | &psyc_recv_join_request, | 1003 | &psyc_recv_join_request, |
806 | &psyc_recv_message, NULL, hst); | 1004 | &psyc_recv_message, NULL, hst); |
@@ -821,10 +1019,41 @@ static void | |||
821 | client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, | 1019 | client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, |
822 | const struct GNUNET_MessageHeader *msg) | 1020 | const struct GNUNET_MessageHeader *msg) |
823 | { | 1021 | { |
824 | const struct HostEnterRequest *hreq | 1022 | struct HostEnterRequest *hreq |
825 | = (const struct HostEnterRequest *) msg; | 1023 | = (struct HostEnterRequest *) GNUNET_copy_message (msg); |
826 | struct Place *plc; | 1024 | |
827 | struct Host *hst; | 1025 | uint8_t app_id_size = ntohs (hreq->header.size) - sizeof (*hreq); |
1026 | const char *app_id = NULL; | ||
1027 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &hreq[1], | ||
1028 | app_id_size, 1, &app_id); | ||
1029 | if (0 == offset || offset != app_id_size || app_id == NULL) | ||
1030 | { | ||
1031 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1032 | "offset = %u, app_id_size = %u, app_id = %s\n", | ||
1033 | offset, app_id_size, app_id); | ||
1034 | GNUNET_break (0); | ||
1035 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1036 | return; | ||
1037 | } | ||
1038 | |||
1039 | struct Host *hst = NULL; | ||
1040 | struct Place *plc = NULL; | ||
1041 | int ret = GNUNET_OK; | ||
1042 | |||
1043 | struct GNUNET_CRYPTO_EddsaPublicKey empty_pub_key; | ||
1044 | memset (&empty_pub_key, 0, sizeof (empty_pub_key)); | ||
1045 | |||
1046 | if (0 == memcmp (&hreq->place_pub_key, &empty_pub_key, sizeof (empty_pub_key))) | ||
1047 | { // no public key set: create new private key & save the place | ||
1048 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
1049 | place_key = GNUNET_CRYPTO_eddsa_key_create (); | ||
1050 | hreq->place_key = *place_key; | ||
1051 | GNUNET_CRYPTO_eddsa_key_get_public (place_key, &hreq->place_pub_key); | ||
1052 | GNUNET_CRYPTO_eddsa_key_clear (place_key); | ||
1053 | GNUNET_free (place_key); | ||
1054 | |||
1055 | app_place_save (app_id, (const struct PlaceEnterRequest *) hreq); | ||
1056 | } | ||
828 | 1057 | ||
829 | switch (host_enter (hreq, &hst)) | 1058 | switch (host_enter (hreq, &hst)) |
830 | { | 1059 | { |
@@ -835,40 +1064,32 @@ client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
835 | case GNUNET_NO: | 1064 | case GNUNET_NO: |
836 | { | 1065 | { |
837 | plc = &hst->plc; | 1066 | plc = &hst->plc; |
838 | 1067 | client_send_host_enter_ack (client, hst, GNUNET_OK); | |
839 | struct GNUNET_PSYC_CountersResultMessage res; | ||
840 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); | ||
841 | res.header.size = htons (sizeof (res)); | ||
842 | res.result_code = htonl (GNUNET_OK); | ||
843 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
844 | |||
845 | GNUNET_SERVER_notification_context_add (nc, client); | ||
846 | GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, | ||
847 | GNUNET_NO); | ||
848 | break; | 1068 | break; |
849 | } | 1069 | } |
850 | case GNUNET_SYSERR: | 1070 | case GNUNET_SYSERR: |
851 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1071 | ret = GNUNET_SYSERR; |
852 | return; | ||
853 | } | 1072 | } |
854 | 1073 | ||
855 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub; | 1074 | if (ret != GNUNET_SYSERR) |
856 | GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub); | 1075 | { |
857 | 1076 | ||
858 | place_save (&hreq->host_key, &place_pub, msg); | 1077 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1078 | "%p Client connected as host to place %s.\n", | ||
1079 | hst, GNUNET_h2s (&plc->pub_key_hash)); | ||
859 | 1080 | ||
860 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1081 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); |
861 | "%p Client connected as host to place %s.\n", | 1082 | cli->client = client; |
862 | hst, GNUNET_h2s (&plc->pub_key_hash)); | 1083 | GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); |
863 | 1084 | ||
864 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); | 1085 | struct Client *ctx = GNUNET_new (struct Client); |
865 | cli->client = client; | 1086 | ctx->plc = plc; |
866 | GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); | 1087 | GNUNET_SERVER_client_set_user_context (client, ctx); |
1088 | } | ||
867 | 1089 | ||
868 | struct Client *ctx = GNUNET_new (struct Client); | 1090 | GNUNET_CRYPTO_eddsa_key_clear (&hreq->place_key); |
869 | ctx->plc = plc; | 1091 | GNUNET_free (hreq); |
870 | GNUNET_SERVER_client_set_user_context (client, ctx); | 1092 | GNUNET_SERVER_receive_done (client, ret); |
871 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
872 | } | 1093 | } |
873 | 1094 | ||
874 | 1095 | ||
@@ -881,7 +1102,8 @@ client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
881 | * Returned Guest struct. | 1102 | * Returned Guest struct. |
882 | * | 1103 | * |
883 | * @return #GNUNET_YES if the guest entered the place just now, | 1104 | * @return #GNUNET_YES if the guest entered the place just now, |
884 | * #GNUNET_NO if the place is already entered. | 1105 | * #GNUNET_NO if the place is already entered, |
1106 | * #GNUNET_SYSERR on error. | ||
885 | */ | 1107 | */ |
886 | static int | 1108 | static int |
887 | guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) | 1109 | guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) |
@@ -889,44 +1111,68 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) | |||
889 | int ret = GNUNET_NO; | 1111 | int ret = GNUNET_NO; |
890 | uint16_t greq_size = ntohs (greq->header.size); | 1112 | uint16_t greq_size = ntohs (greq->header.size); |
891 | 1113 | ||
892 | struct GNUNET_CRYPTO_EcdsaPublicKey gst_pub_key; | 1114 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key = greq->ego_pub_key; |
893 | struct GNUNET_HashCode place_pub_hash, gst_pub_key_hash; | 1115 | struct GNUNET_HashCode ego_pub_hash; |
894 | GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &gst_pub_key); | 1116 | GNUNET_CRYPTO_hash (&ego_pub_key, sizeof (ego_pub_key), &ego_pub_hash); |
895 | GNUNET_CRYPTO_hash (&gst_pub_key, sizeof (gst_pub_key), &gst_pub_key_hash); | 1117 | struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash); |
896 | GNUNET_CRYPTO_hash (&greq->place_key, sizeof (greq->place_key), &place_pub_hash); | 1118 | |
1119 | if (NULL == ego) | ||
1120 | return GNUNET_SYSERR; | ||
1121 | |||
1122 | struct GNUNET_HashCode place_pub_hash; | ||
1123 | GNUNET_CRYPTO_hash (&greq->place_pub_key, sizeof (greq->place_pub_key), | ||
1124 | &place_pub_hash); | ||
897 | 1125 | ||
898 | struct GNUNET_CONTAINER_MultiHashMap * | 1126 | struct GNUNET_CONTAINER_MultiHashMap * |
899 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, &place_pub_hash); | 1127 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, &place_pub_hash); |
900 | struct Guest *gst = NULL; | 1128 | struct Guest *gst = NULL; |
901 | struct Place *plc; | ||
902 | 1129 | ||
903 | if (NULL != plc_gst) | 1130 | if (NULL != plc_gst) |
904 | gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &gst_pub_key_hash); | 1131 | gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &ego_pub_hash); |
905 | 1132 | ||
906 | if (NULL == gst || NULL == gst->slave) | 1133 | if (NULL == gst || NULL == gst->slave) |
907 | { | 1134 | { |
908 | gst = GNUNET_new (struct Guest); | 1135 | gst = GNUNET_new (struct Guest); |
909 | gst->priv_key = greq->guest_key; | ||
910 | gst->pub_key = gst_pub_key; | ||
911 | gst->pub_key_hash = gst_pub_key_hash; | ||
912 | gst->origin = greq->origin; | 1136 | gst->origin = greq->origin; |
913 | gst->relay_count = ntohl (greq->relay_count); | 1137 | gst->relay_count = ntohl (greq->relay_count); |
914 | 1138 | ||
1139 | uint16_t len; | ||
1140 | uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq); | ||
1141 | const char *app_id = (const char *) &greq[1]; | ||
1142 | const char *p = app_id; | ||
1143 | |||
1144 | len = strnlen (app_id, remaining); | ||
1145 | if (len == remaining) | ||
1146 | { | ||
1147 | GNUNET_break (0); | ||
1148 | return GNUNET_SYSERR; | ||
1149 | } | ||
1150 | p += len + 1; | ||
1151 | remaining -= len + 1; | ||
1152 | |||
915 | const struct GNUNET_PeerIdentity *relays = NULL; | 1153 | const struct GNUNET_PeerIdentity *relays = NULL; |
916 | uint16_t relay_size = gst->relay_count * sizeof (*relays); | 1154 | uint16_t relay_size = gst->relay_count * sizeof (*relays); |
1155 | if (remaining < relay_size) | ||
1156 | { | ||
1157 | GNUNET_break (0); | ||
1158 | return GNUNET_SYSERR; | ||
1159 | } | ||
917 | if (0 < relay_size) | 1160 | if (0 < relay_size) |
918 | relays = (const struct GNUNET_PeerIdentity *) &greq[1]; | 1161 | relays = (const struct GNUNET_PeerIdentity *) p; |
1162 | p += relay_size; | ||
1163 | remaining -= relay_size; | ||
1164 | |||
919 | struct GNUNET_PSYC_Message *join_msg = NULL; | 1165 | struct GNUNET_PSYC_Message *join_msg = NULL; |
920 | uint16_t join_msg_size = 0; | 1166 | uint16_t join_msg_size = 0; |
921 | 1167 | ||
922 | if (sizeof (*greq) + relay_size + sizeof (struct GNUNET_MessageHeader) | 1168 | if (sizeof (struct GNUNET_MessageHeader) <= remaining) |
923 | <= greq_size) | ||
924 | { | 1169 | { |
925 | join_msg = (struct GNUNET_PSYC_Message *) | 1170 | join_msg = (struct GNUNET_PSYC_Message *) p; |
926 | (((char *) &greq[1]) + relay_size); | ||
927 | join_msg_size = ntohs (join_msg->header.size); | 1171 | join_msg_size = ntohs (join_msg->header.size); |
1172 | p += join_msg_size; | ||
1173 | remaining -= join_msg_size; | ||
928 | } | 1174 | } |
929 | if (sizeof (*greq) + relay_size + join_msg_size != greq_size) | 1175 | if (0 != remaining) |
930 | { | 1176 | { |
931 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1177 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
932 | "%u + %u + %u != %u\n", | 1178 | "%u + %u + %u != %u\n", |
@@ -935,17 +1181,20 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) | |||
935 | GNUNET_free (gst); | 1181 | GNUNET_free (gst); |
936 | return GNUNET_SYSERR; | 1182 | return GNUNET_SYSERR; |
937 | } | 1183 | } |
938 | if (0 < gst->relay_count) | 1184 | if (0 < relay_size) |
939 | { | 1185 | { |
940 | gst->relays = GNUNET_malloc (relay_size); | 1186 | gst->relays = GNUNET_malloc (relay_size); |
941 | memcpy (gst->relays, &greq[1], relay_size); | 1187 | memcpy (gst->relays, relays, relay_size); |
942 | } | 1188 | } |
943 | 1189 | ||
944 | plc = &gst->plc; | 1190 | struct Place *plc = &gst->plc; |
1191 | place_init (plc); | ||
945 | plc->is_host = GNUNET_NO; | 1192 | plc->is_host = GNUNET_NO; |
946 | plc->pub_key = greq->place_key; | 1193 | plc->pub_key = greq->place_pub_key; |
947 | plc->pub_key_hash = place_pub_hash; | 1194 | plc->pub_key_hash = place_pub_hash; |
948 | place_init (plc); | 1195 | plc->ego_pub_key = ego_pub_key; |
1196 | plc->ego_pub_hash = ego_pub_hash; | ||
1197 | plc->ego_key = ego->key; | ||
949 | 1198 | ||
950 | if (NULL == plc_gst) | 1199 | if (NULL == plc_gst) |
951 | { | 1200 | { |
@@ -953,12 +1202,12 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) | |||
953 | (void) GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst, | 1202 | (void) GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst, |
954 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1203 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
955 | } | 1204 | } |
956 | (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &gst->pub_key_hash, gst, | 1205 | (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst, |
957 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1206 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
958 | (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst, | 1207 | (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst, |
959 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 1208 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
960 | gst->slave | 1209 | gst->slave |
961 | = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &gst->priv_key, | 1210 | = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &plc->ego_key, |
962 | &gst->origin, gst->relay_count, gst->relays, | 1211 | &gst->origin, gst->relay_count, gst->relays, |
963 | &psyc_recv_message, NULL, &psyc_slave_connected, | 1212 | &psyc_recv_message, NULL, &psyc_slave_connected, |
964 | &psyc_recv_join_dcsn, gst, join_msg); | 1213 | &psyc_recv_join_dcsn, gst, join_msg); |
@@ -981,6 +1230,18 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
981 | { | 1230 | { |
982 | const struct GuestEnterRequest * | 1231 | const struct GuestEnterRequest * |
983 | greq = (const struct GuestEnterRequest *) msg; | 1232 | greq = (const struct GuestEnterRequest *) msg; |
1233 | |||
1234 | uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq); | ||
1235 | const char *app_id = NULL; | ||
1236 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &greq[1], | ||
1237 | remaining, 1, &app_id); | ||
1238 | if (0 == offset) | ||
1239 | { | ||
1240 | GNUNET_break (0); | ||
1241 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1242 | return; | ||
1243 | } | ||
1244 | |||
984 | struct Guest *gst = NULL; | 1245 | struct Guest *gst = NULL; |
985 | struct Place *plc = NULL; | 1246 | struct Place *plc = NULL; |
986 | 1247 | ||
@@ -988,6 +1249,7 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
988 | { | 1249 | { |
989 | case GNUNET_YES: | 1250 | case GNUNET_YES: |
990 | plc = &gst->plc; | 1251 | plc = &gst->plc; |
1252 | app_place_save (app_id, (const struct PlaceEnterRequest *) greq); | ||
991 | break; | 1253 | break; |
992 | 1254 | ||
993 | case GNUNET_NO: | 1255 | case GNUNET_NO: |
@@ -1000,28 +1262,21 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
1000 | res.result_code = htonl (GNUNET_OK); | 1262 | res.result_code = htonl (GNUNET_OK); |
1001 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | 1263 | res.max_message_id = GNUNET_htonll (plc->max_message_id); |
1002 | 1264 | ||
1003 | GNUNET_SERVER_notification_context_add (nc, client); | 1265 | client_send_msg (client, &res.header); |
1004 | GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, | ||
1005 | GNUNET_NO); | ||
1006 | if (NULL != gst->join_dcsn) | 1266 | if (NULL != gst->join_dcsn) |
1007 | { | 1267 | client_send_msg (client, &gst->join_dcsn->header); |
1008 | GNUNET_SERVER_notification_context_add (nc, client); | 1268 | |
1009 | GNUNET_SERVER_notification_context_unicast (nc, client, | ||
1010 | &gst->join_dcsn->header, | ||
1011 | GNUNET_NO); | ||
1012 | } | ||
1013 | break; | 1269 | break; |
1014 | } | 1270 | } |
1015 | case GNUNET_SYSERR: | 1271 | case GNUNET_SYSERR: |
1272 | GNUNET_break (0); | ||
1016 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1273 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1017 | return; | 1274 | return; |
1018 | } | 1275 | } |
1019 | 1276 | ||
1020 | place_save (&greq->guest_key, &greq->place_key, msg); | ||
1021 | |||
1022 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1277 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1023 | "%p Client connected as guest to place %s.\n", | 1278 | "%p Client connected as guest to place %s.\n", |
1024 | gst, GNUNET_h2s (&gst->plc.pub_key_hash)); | 1279 | gst, GNUNET_h2s (&plc->pub_key_hash)); |
1025 | 1280 | ||
1026 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); | 1281 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); |
1027 | cli->client = client; | 1282 | cli->client = client; |
@@ -1034,16 +1289,159 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | |||
1034 | } | 1289 | } |
1035 | 1290 | ||
1036 | 1291 | ||
1292 | struct GuestEnterByNameClosure | ||
1293 | { | ||
1294 | struct GNUNET_SERVER_Client *client; | ||
1295 | char *app_id; | ||
1296 | char *password; | ||
1297 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
1298 | struct GNUNET_MessageHeader *join_msg; | ||
1299 | }; | ||
1300 | |||
1301 | |||
1302 | /** | ||
1303 | * Result of a GNS name lookup for entering a place. | ||
1304 | * | ||
1305 | * @see GNUNET_SOCIAL_guest_enter_by_name | ||
1306 | */ | ||
1307 | static void | ||
1308 | gns_result_guest_enter (void *cls, uint32_t rd_count, | ||
1309 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1310 | { | ||
1311 | struct GuestEnterByNameClosure *gcls = cls; | ||
1312 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1313 | "%p GNS result: %u records.\n", gcls->client, rd_count); | ||
1314 | |||
1315 | const struct GNUNET_GNSRECORD_PlaceData * | ||
1316 | rec = (const struct GNUNET_GNSRECORD_PlaceData *) rd->data; | ||
1317 | |||
1318 | if (0 == rd_count || rd->data_size < sizeof (*rec)) | ||
1319 | { | ||
1320 | GNUNET_break (0); | ||
1321 | GNUNET_SERVER_receive_done (gcls->client, GNUNET_SYSERR); | ||
1322 | return; | ||
1323 | } | ||
1324 | |||
1325 | uint16_t relay_count = ntohl (rec->relay_count); | ||
1326 | struct GNUNET_PeerIdentity *relays = NULL; | ||
1327 | |||
1328 | if (0 < relay_count) | ||
1329 | { | ||
1330 | if (rd->data_size == sizeof (*rec) + relay_count * sizeof (struct GNUNET_PeerIdentity)) | ||
1331 | { | ||
1332 | relays = (struct GNUNET_PeerIdentity *) &rec[1]; | ||
1333 | } | ||
1334 | else | ||
1335 | { | ||
1336 | relay_count = 0; | ||
1337 | GNUNET_break_op (0); | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1341 | uint16_t app_id_size = strlen (gcls->app_id) + 1; | ||
1342 | uint16_t relay_size = relay_count * sizeof (*relays); | ||
1343 | uint16_t join_msg_size = 0; | ||
1344 | if (NULL != gcls->join_msg) | ||
1345 | join_msg_size = ntohs (gcls->join_msg->size); | ||
1346 | uint16_t greq_size = sizeof (struct GuestEnterRequest) | ||
1347 | + app_id_size + relay_size + join_msg_size; | ||
1348 | struct GuestEnterRequest *greq = GNUNET_malloc (greq_size); | ||
1349 | greq->header.size = htons (greq_size); | ||
1350 | greq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER); | ||
1351 | greq->ego_pub_key = gcls->ego_pub_key; | ||
1352 | greq->place_pub_key = rec->place_pub_key; | ||
1353 | greq->origin = rec->origin; | ||
1354 | greq->relay_count = rec->relay_count; | ||
1355 | |||
1356 | void *p = &greq[1]; | ||
1357 | memcpy (p, gcls->app_id, app_id_size); | ||
1358 | p += app_id_size; | ||
1359 | memcpy (p, relays, relay_size); | ||
1360 | p += relay_size; | ||
1361 | memcpy (p, gcls->join_msg, join_msg_size); | ||
1362 | |||
1363 | client_recv_guest_enter (NULL, gcls->client, &greq->header); | ||
1364 | |||
1365 | GNUNET_free (gcls->app_id); | ||
1366 | if (NULL != gcls->password) | ||
1367 | GNUNET_free (gcls->password); | ||
1368 | if (NULL != gcls->join_msg) | ||
1369 | GNUNET_free (gcls->join_msg); | ||
1370 | GNUNET_free (gcls); | ||
1371 | GNUNET_free (greq); | ||
1372 | } | ||
1373 | |||
1374 | |||
1375 | /** | ||
1376 | * Handle a connecting client entering a place as guest using a GNS address. | ||
1377 | * | ||
1378 | * Look up GNS address and generate a GuestEnterRequest from that. | ||
1379 | */ | ||
1380 | static void | ||
1381 | client_recv_guest_enter_by_name (void *cls, struct GNUNET_SERVER_Client *client, | ||
1382 | const struct GNUNET_MessageHeader *msg) | ||
1383 | { | ||
1384 | const struct GuestEnterByNameRequest * | ||
1385 | greq = (const struct GuestEnterByNameRequest *) msg; | ||
1386 | |||
1387 | struct GuestEnterByNameClosure *gcls = GNUNET_malloc (sizeof (*gcls)); | ||
1388 | gcls->client = client; | ||
1389 | gcls->ego_pub_key = greq->ego_pub_key; | ||
1390 | |||
1391 | const char *p = (const char *) &greq[1]; | ||
1392 | const char *app_id = NULL, *password = NULL, *gns_name = NULL; | ||
1393 | uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq); | ||
1394 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize (p, remaining, 3, | ||
1395 | &app_id, | ||
1396 | &gns_name, | ||
1397 | &password); | ||
1398 | p += offset; | ||
1399 | remaining -= offset; | ||
1400 | |||
1401 | if (0 != offset && sizeof (*gcls->join_msg) <= remaining) | ||
1402 | { | ||
1403 | gcls->join_msg = GNUNET_copy_message ((struct GNUNET_MessageHeader *) p); | ||
1404 | remaining -= ntohs (gcls->join_msg->size); | ||
1405 | } | ||
1406 | |||
1407 | if (0 == offset || 0 != remaining) | ||
1408 | { | ||
1409 | if (NULL != gcls->join_msg) | ||
1410 | GNUNET_free (gcls->join_msg); | ||
1411 | GNUNET_break (0); | ||
1412 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1413 | return; | ||
1414 | } | ||
1415 | |||
1416 | uint16_t app_id_size = strlen (app_id) + 1; | ||
1417 | gcls->app_id = GNUNET_malloc (app_id_size); | ||
1418 | memcpy (gcls->app_id, app_id, app_id_size); | ||
1419 | |||
1420 | uint16_t password_size = strlen (password); | ||
1421 | if (0 < password_size++) | ||
1422 | { | ||
1423 | gcls->password = GNUNET_malloc (password_size); | ||
1424 | memcpy (gcls->password, password, password_size); | ||
1425 | } | ||
1426 | |||
1427 | GNUNET_GNS_lookup (gns, gns_name, &greq->ego_pub_key, | ||
1428 | GNUNET_GNSRECORD_TYPE_PLACE, GNUNET_GNS_LO_DEFAULT, | ||
1429 | NULL, gns_result_guest_enter, gcls); | ||
1430 | } | ||
1431 | |||
1432 | |||
1037 | void | 1433 | void |
1038 | place_notify (struct GNUNET_MessageHeader *msg, | 1434 | app_notify_place (struct GNUNET_MessageHeader *msg, |
1039 | struct GNUNET_SERVER_Client *client) | 1435 | struct GNUNET_SERVER_Client *client) |
1040 | { | 1436 | { |
1041 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1437 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1042 | "%p Sending place notification of type %u to client.\n", | 1438 | "%p Sending place notification of type %u to client.\n", |
1043 | client, ntohs (msg->type)); | 1439 | client, ntohs (msg->type)); |
1044 | 1440 | ||
1045 | uint16_t msg_size = ntohs (msg->size); | 1441 | uint16_t msg_size = ntohs (msg->size); |
1046 | struct GNUNET_CRYPTO_EcdsaPublicKey place_pub; | 1442 | struct AppPlaceMessage amsg; |
1443 | amsg.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE); | ||
1444 | amsg.header.size = htons (sizeof (amsg)); | ||
1047 | 1445 | ||
1048 | switch (ntohs (msg->type)) | 1446 | switch (ntohs (msg->type)) |
1049 | { | 1447 | { |
@@ -1051,77 +1449,181 @@ place_notify (struct GNUNET_MessageHeader *msg, | |||
1051 | if (msg_size < sizeof (struct HostEnterRequest)) | 1449 | if (msg_size < sizeof (struct HostEnterRequest)) |
1052 | return; | 1450 | return; |
1053 | struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg; | 1451 | struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg; |
1054 | GNUNET_CRYPTO_ecdsa_key_get_public (&hreq->host_key, &place_pub); | 1452 | amsg.is_host = GNUNET_YES; |
1453 | amsg.ego_pub_key = hreq->ego_pub_key; | ||
1454 | amsg.place_pub_key = hreq->place_pub_key; | ||
1055 | break; | 1455 | break; |
1056 | 1456 | ||
1057 | case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER: | 1457 | case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER: |
1058 | if (msg_size < sizeof (struct GuestEnterRequest)) | 1458 | if (msg_size < sizeof (struct GuestEnterRequest)) |
1059 | return; | 1459 | return; |
1060 | struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg; | 1460 | struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg; |
1061 | GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &place_pub); | 1461 | amsg.is_host = GNUNET_NO; |
1462 | amsg.ego_pub_key = greq->ego_pub_key; | ||
1463 | amsg.place_pub_key = greq->place_pub_key; | ||
1062 | break; | 1464 | break; |
1063 | 1465 | ||
1064 | default: | 1466 | default: |
1065 | return; | 1467 | return; |
1066 | } | 1468 | } |
1067 | 1469 | ||
1068 | GNUNET_SERVER_notification_context_add (nc, client); | 1470 | client_send_msg (client, &amsg.header); |
1069 | GNUNET_SERVER_notification_context_unicast (nc, client, msg, | 1471 | } |
1070 | GNUNET_NO); | 1472 | |
1473 | |||
1474 | void | ||
1475 | app_notify_ego (struct Ego *ego, struct GNUNET_SERVER_Client *client) | ||
1476 | { | ||
1477 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1478 | "%p Sending ego notification to client: %s\n", | ||
1479 | client, ego->name); | ||
1480 | |||
1481 | size_t name_size = strlen (ego->name) + 1; | ||
1482 | struct AppEgoMessage *emsg = GNUNET_malloc (sizeof (*emsg) + name_size); | ||
1483 | emsg->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO); | ||
1484 | emsg->header.size = htons (sizeof (*emsg) + name_size); | ||
1485 | |||
1486 | GNUNET_CRYPTO_ecdsa_key_get_public (&ego->key, &emsg->ego_pub_key); | ||
1487 | memcpy (&emsg[1], ego->name, name_size); | ||
1488 | |||
1489 | client_send_msg (client, &emsg->header); | ||
1490 | GNUNET_free (emsg); | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | int | ||
1495 | app_place_entry (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
1496 | { | ||
1497 | struct GNUNET_MessageHeader * | ||
1498 | msg = GNUNET_CONTAINER_multihashmap_get (places, key); | ||
1499 | if (NULL != msg) | ||
1500 | app_notify_place (msg, cls); | ||
1501 | return GNUNET_YES; | ||
1071 | } | 1502 | } |
1072 | 1503 | ||
1073 | 1504 | ||
1074 | int | 1505 | int |
1075 | map_entry_place (void *cls, const struct GNUNET_HashCode *key, void *value) | 1506 | ego_entry (void *cls, const struct GNUNET_HashCode *key, void *value) |
1076 | { | 1507 | { |
1077 | place_notify (value, cls); | 1508 | app_notify_ego (value, cls); |
1078 | return GNUNET_YES; | 1509 | return GNUNET_YES; |
1079 | } | 1510 | } |
1080 | 1511 | ||
1081 | 1512 | ||
1082 | /** | 1513 | /** |
1083 | * Handle a connecting client listening for entered places. | 1514 | * Handle application connection. |
1084 | */ | 1515 | */ |
1085 | static void | 1516 | static void |
1086 | client_recv_place_listen (void *cls, struct GNUNET_SERVER_Client *client, | 1517 | client_recv_app_connect (void *cls, struct GNUNET_SERVER_Client *client, |
1087 | const struct GNUNET_MessageHeader *msg) | 1518 | const struct GNUNET_MessageHeader *msg) |
1088 | { | 1519 | { |
1089 | const struct PlaceListenRequest *req | 1520 | const struct AppConnectRequest *creq |
1090 | = (const struct PlaceListenRequest *) msg; | 1521 | = (const struct AppConnectRequest *) msg; |
1522 | |||
1523 | uint8_t app_id_size = ntohs (creq->header.size) - sizeof (*creq); | ||
1524 | const char *app_id = NULL; | ||
1525 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &creq[1], | ||
1526 | app_id_size, 1, &app_id); | ||
1527 | if (0 == offset || offset != app_id_size) | ||
1528 | { | ||
1529 | GNUNET_break (0); | ||
1530 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1531 | return; | ||
1532 | } | ||
1091 | 1533 | ||
1092 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub; | 1534 | struct GNUNET_HashCode app_id_hash; |
1093 | struct GNUNET_HashCode ego_pub_hash; | 1535 | GNUNET_CRYPTO_hash (app_id, app_id_size, &app_id_hash); |
1094 | 1536 | ||
1095 | GNUNET_CRYPTO_ecdsa_key_get_public (&req->ego_key, &ego_pub); | 1537 | GNUNET_CONTAINER_multihashmap_iterate (egos, ego_entry, client); |
1096 | GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash); | ||
1097 | 1538 | ||
1098 | struct GNUNET_CONTAINER_MultiHashMap * | 1539 | struct GNUNET_CONTAINER_MultiHashMap * |
1099 | ego_places = GNUNET_CONTAINER_multihashmap_get (places_entered, &ego_pub_hash); | 1540 | app_places = GNUNET_CONTAINER_multihashmap_get (apps_places, &app_id_hash); |
1100 | if (NULL != ego_places) | 1541 | if (NULL != app_places) |
1101 | GNUNET_CONTAINER_multihashmap_iterate (ego_places, map_entry_place, client); | 1542 | GNUNET_CONTAINER_multihashmap_iterate (app_places, app_place_entry, client); |
1102 | |||
1103 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1104 | "%p Client connected to listen for entered places of ego %s.\n", | ||
1105 | NULL, GNUNET_h2s (&ego_pub_hash)); | ||
1106 | 1543 | ||
1107 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); | 1544 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); |
1108 | cli->client = client; | 1545 | cli->client = client; |
1109 | struct PlaceListener *pl = GNUNET_CONTAINER_multihashmap_get (place_listeners, | 1546 | struct Application *app = GNUNET_CONTAINER_multihashmap_get (apps, |
1110 | &ego_pub_hash); | 1547 | &app_id_hash); |
1111 | if (NULL == pl) { | 1548 | if (NULL == app) { |
1112 | pl = GNUNET_malloc (sizeof (*pl)); | 1549 | app = GNUNET_malloc (sizeof (*app)); |
1113 | (void) GNUNET_CONTAINER_multihashmap_put (place_listeners, &ego_pub_hash, pl, | 1550 | (void) GNUNET_CONTAINER_multihashmap_put (apps, &app_id_hash, app, |
1114 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1551 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
1115 | } | 1552 | } |
1116 | GNUNET_CONTAINER_DLL_insert (pl->clients_head, pl->clients_tail, cli); | 1553 | GNUNET_CONTAINER_DLL_insert (app->clients_head, app->clients_tail, cli); |
1554 | |||
1555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1556 | "%p Application %s connected.\n", app, app_id); | ||
1117 | 1557 | ||
1118 | struct Client *ctx = GNUNET_new (struct Client); | 1558 | struct Client *ctx = GNUNET_new (struct Client); |
1119 | ctx->ego_key = req->ego_key; | 1559 | ctx->app_id = GNUNET_malloc (app_id_size); |
1560 | memcpy (ctx->app_id, app_id, app_id_size); | ||
1561 | |||
1120 | GNUNET_SERVER_client_set_user_context (client, ctx); | 1562 | GNUNET_SERVER_client_set_user_context (client, ctx); |
1121 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1563 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1122 | } | 1564 | } |
1123 | 1565 | ||
1124 | 1566 | ||
1567 | /** | ||
1568 | * Handle application detach request. | ||
1569 | */ | ||
1570 | static void | ||
1571 | client_recv_app_detach (void *cls, struct GNUNET_SERVER_Client *client, | ||
1572 | const struct GNUNET_MessageHeader *msg) | ||
1573 | { | ||
1574 | struct Client * | ||
1575 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); | ||
1576 | GNUNET_assert (NULL != ctx); | ||
1577 | |||
1578 | const struct AppDetachRequest *req | ||
1579 | = (const struct AppDetachRequest *) msg; | ||
1580 | |||
1581 | int ret = app_place_remove (ctx->app_id, &req->place_pub_key); | ||
1582 | client_send_result (client, req->op_id, ret, NULL, 0); | ||
1583 | |||
1584 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1585 | } | ||
1586 | |||
1587 | |||
1588 | /** | ||
1589 | * Handle application detach request. | ||
1590 | */ | ||
1591 | static void | ||
1592 | client_recv_place_leave (void *cls, struct GNUNET_SERVER_Client *client, | ||
1593 | const struct GNUNET_MessageHeader *msg) | ||
1594 | { | ||
1595 | struct Client * | ||
1596 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); | ||
1597 | GNUNET_assert (NULL != ctx); | ||
1598 | struct Place *plc = ctx->plc; | ||
1599 | |||
1600 | /* Disconnect all clients connected to the place */ | ||
1601 | /* FIXME: disconnect from the network, but keep local connection for history access */ | ||
1602 | struct ClientListItem *cli = plc->clients_head, *next; | ||
1603 | while (NULL != cli) | ||
1604 | { | ||
1605 | GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli); | ||
1606 | GNUNET_SERVER_client_disconnect (cli->client); | ||
1607 | next = cli->next; | ||
1608 | GNUNET_free (cli); | ||
1609 | cli = next; | ||
1610 | } | ||
1611 | |||
1612 | if (GNUNET_YES != plc->is_disconnected) | ||
1613 | { | ||
1614 | plc->is_disconnected = GNUNET_YES; | ||
1615 | if (NULL != plc->tmit_msgs_head) | ||
1616 | { /* Send pending messages to PSYC before cleanup. */ | ||
1617 | psyc_transmit_message (plc); | ||
1618 | } | ||
1619 | else | ||
1620 | { | ||
1621 | cleanup_place (plc); | ||
1622 | } | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | |||
1125 | struct JoinDecisionClosure | 1627 | struct JoinDecisionClosure |
1126 | { | 1628 | { |
1127 | int32_t is_admitted; | 1629 | int32_t is_admitted; |
@@ -1198,9 +1700,7 @@ send_message_ack (struct Place *plc, struct GNUNET_SERVER_Client *client) | |||
1198 | struct GNUNET_MessageHeader res; | 1700 | struct GNUNET_MessageHeader res; |
1199 | res.size = htons (sizeof (res)); | 1701 | res.size = htons (sizeof (res)); |
1200 | res.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK); | 1702 | res.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK); |
1201 | 1703 | client_send_msg (client, &res); | |
1202 | GNUNET_SERVER_notification_context_add (nc, client); | ||
1203 | GNUNET_SERVER_notification_context_unicast (nc, client, &res, GNUNET_NO); | ||
1204 | } | 1704 | } |
1205 | 1705 | ||
1206 | 1706 | ||
@@ -1872,7 +2372,7 @@ psyc_recv_history_message (void *cls, uint64_t message_id, uint32_t flags, | |||
1872 | memcpy (&res[1], msg, size); | 2372 | memcpy (&res[1], msg, size); |
1873 | 2373 | ||
1874 | /** @todo FIXME: send only to requesting client */ | 2374 | /** @todo FIXME: send only to requesting client */ |
1875 | client_send_msg (plc, &res->header); | 2375 | place_send_msg (plc, &res->header); |
1876 | } | 2376 | } |
1877 | 2377 | ||
1878 | 2378 | ||
@@ -1977,7 +2477,7 @@ psyc_recv_state_var (void *cls, | |||
1977 | memcpy (&res[1], mod, size); | 2477 | memcpy (&res[1], mod, size); |
1978 | 2478 | ||
1979 | /** @todo FIXME: send only to requesting client */ | 2479 | /** @todo FIXME: send only to requesting client */ |
1980 | client_send_msg (plc, &res->header); | 2480 | place_send_msg (plc, &res->header); |
1981 | } | 2481 | } |
1982 | 2482 | ||
1983 | 2483 | ||
@@ -2059,6 +2559,130 @@ client_recv_state_get (void *cls, struct GNUNET_SERVER_Client *client, | |||
2059 | } | 2559 | } |
2060 | 2560 | ||
2061 | 2561 | ||
2562 | static void | ||
2563 | namestore_recv_records_store_result (void *cls, int32_t result, | ||
2564 | const char *err_msg) | ||
2565 | { | ||
2566 | struct OperationClosure *ocls = cls; | ||
2567 | client_send_result (ocls->client, ocls->op_id, result, err_msg, | ||
2568 | (NULL != err_msg) ? strlen (err_msg) : 0); | ||
2569 | GNUNET_free (ocls); | ||
2570 | } | ||
2571 | |||
2572 | |||
2573 | /** | ||
2574 | * Handle request to add PLACE record to GNS zone. | ||
2575 | */ | ||
2576 | static void | ||
2577 | client_recv_zone_add_place (void *cls, struct GNUNET_SERVER_Client *client, | ||
2578 | const struct GNUNET_MessageHeader *msg) | ||
2579 | { | ||
2580 | const struct ZoneAddPlaceRequest *preq | ||
2581 | = (const struct ZoneAddPlaceRequest *) msg; | ||
2582 | |||
2583 | uint16_t remaining = ntohs (preq->header.size) - sizeof (*preq); | ||
2584 | const char *p = (const char *) &preq[1]; | ||
2585 | const char *name = NULL, *password = NULL; | ||
2586 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize (p, remaining, 2, | ||
2587 | &name, &password); | ||
2588 | remaining -= offset; | ||
2589 | p += offset; | ||
2590 | const struct GNUNET_PeerIdentity * | ||
2591 | relays = (const struct GNUNET_PeerIdentity *) p; | ||
2592 | uint16_t relay_size = ntohl (preq->relay_count) * sizeof (*relays); | ||
2593 | |||
2594 | if (0 == offset || remaining != relay_size) | ||
2595 | { | ||
2596 | GNUNET_break (0); | ||
2597 | client_send_result (client, preq->op_id, GNUNET_SYSERR, NULL, 0); | ||
2598 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2599 | return; | ||
2600 | } | ||
2601 | |||
2602 | struct GNUNET_GNSRECORD_Data rd = { }; | ||
2603 | rd.record_type = GNUNET_GNSRECORD_TYPE_PLACE; | ||
2604 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
2605 | rd.expiration_time = GNUNET_ntohll (preq->expiration_time); | ||
2606 | |||
2607 | struct GNUNET_GNSRECORD_PlaceData * | ||
2608 | rec = GNUNET_malloc (sizeof (*rec) + relay_size); | ||
2609 | rec->place_pub_key = preq->place_pub_key; | ||
2610 | rec->origin = this_peer; | ||
2611 | rec->relay_count = preq->relay_count; | ||
2612 | memcpy (&rec[1], relays, relay_size); | ||
2613 | |||
2614 | rd.data = rec; | ||
2615 | rd.data_size = sizeof (*rec) + relay_size; | ||
2616 | |||
2617 | struct GNUNET_HashCode ego_pub_hash; | ||
2618 | GNUNET_CRYPTO_hash (&preq->ego_pub_key, sizeof (preq->ego_pub_key), &ego_pub_hash); | ||
2619 | struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash); | ||
2620 | if (NULL == ego) | ||
2621 | { | ||
2622 | client_send_result (client, preq->op_id, GNUNET_SYSERR, NULL, 0); | ||
2623 | } | ||
2624 | else | ||
2625 | { | ||
2626 | struct OperationClosure *ocls = GNUNET_malloc (sizeof (*ocls)); | ||
2627 | ocls->client = client; | ||
2628 | ocls->op_id = preq->op_id; | ||
2629 | GNUNET_NAMESTORE_records_store (namestore, &ego->key, | ||
2630 | name, 1, &rd, | ||
2631 | namestore_recv_records_store_result, ocls); | ||
2632 | } | ||
2633 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2634 | } | ||
2635 | |||
2636 | |||
2637 | /** | ||
2638 | * Handle request to add PLACE record to GNS zone. | ||
2639 | */ | ||
2640 | static void | ||
2641 | client_recv_zone_add_nym (void *cls, struct GNUNET_SERVER_Client *client, | ||
2642 | const struct GNUNET_MessageHeader *msg) | ||
2643 | { | ||
2644 | const struct ZoneAddNymRequest *nreq | ||
2645 | = (const struct ZoneAddNymRequest *) msg; | ||
2646 | |||
2647 | uint16_t name_size = ntohs (nreq->header.size) - sizeof (*nreq); | ||
2648 | const char *name = NULL; | ||
2649 | uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &nreq[1], | ||
2650 | name_size, 1, &name); | ||
2651 | if (0 == offset || offset != name_size) | ||
2652 | { | ||
2653 | GNUNET_break (0); | ||
2654 | client_send_result (client, nreq->op_id, GNUNET_SYSERR, NULL, 0); | ||
2655 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2656 | return; | ||
2657 | } | ||
2658 | |||
2659 | struct GNUNET_GNSRECORD_Data rd = { }; | ||
2660 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | ||
2661 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
2662 | rd.expiration_time = GNUNET_ntohll (nreq->expiration_time); | ||
2663 | rd.data = &nreq->nym_pub_key; | ||
2664 | rd.data_size = sizeof (nreq->nym_pub_key); | ||
2665 | |||
2666 | struct GNUNET_HashCode ego_pub_hash; | ||
2667 | GNUNET_CRYPTO_hash (&nreq->ego_pub_key, sizeof (nreq->ego_pub_key), &ego_pub_hash); | ||
2668 | struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash); | ||
2669 | if (NULL == ego) | ||
2670 | { | ||
2671 | client_send_result (client, nreq->op_id, GNUNET_SYSERR, NULL, 0); | ||
2672 | } | ||
2673 | else | ||
2674 | { | ||
2675 | struct OperationClosure *ocls = GNUNET_malloc (sizeof (*ocls)); | ||
2676 | ocls->client = client; | ||
2677 | ocls->op_id = nreq->op_id; | ||
2678 | GNUNET_NAMESTORE_records_store (namestore, &ego->key, | ||
2679 | name, 1, &rd, | ||
2680 | namestore_recv_records_store_result, ocls); | ||
2681 | } | ||
2682 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2683 | } | ||
2684 | |||
2685 | |||
2062 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 2686 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
2063 | { &client_recv_host_enter, NULL, | 2687 | { &client_recv_host_enter, NULL, |
2064 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, 0 }, | 2688 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, 0 }, |
@@ -2066,6 +2690,9 @@ static const struct GNUNET_SERVER_MessageHandler handlers[] = { | |||
2066 | { &client_recv_guest_enter, NULL, | 2690 | { &client_recv_guest_enter, NULL, |
2067 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, 0 }, | 2691 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, 0 }, |
2068 | 2692 | ||
2693 | { &client_recv_guest_enter_by_name, NULL, | ||
2694 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME, 0 }, | ||
2695 | |||
2069 | { &client_recv_join_decision, NULL, | 2696 | { &client_recv_join_decision, NULL, |
2070 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, | 2697 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, |
2071 | 2698 | ||
@@ -2081,50 +2708,79 @@ static const struct GNUNET_SERVER_MessageHandler handlers[] = { | |||
2081 | { &client_recv_state_get, NULL, | 2708 | { &client_recv_state_get, NULL, |
2082 | GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }, | 2709 | GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }, |
2083 | 2710 | ||
2084 | { &client_recv_place_listen, NULL, | 2711 | { &client_recv_zone_add_place, NULL, |
2085 | GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN, 0 }, | 2712 | GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE, 0 }, |
2713 | |||
2714 | { &client_recv_zone_add_nym, NULL, | ||
2715 | GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM, 0 }, | ||
2716 | |||
2717 | { &client_recv_app_connect, NULL, | ||
2718 | GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT, 0 }, | ||
2719 | |||
2720 | { &client_recv_app_detach, NULL, | ||
2721 | GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH, 0 }, | ||
2722 | |||
2723 | { &client_recv_place_leave, NULL, | ||
2724 | GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE, 0 }, | ||
2086 | 2725 | ||
2087 | { NULL, NULL, 0, 0 } | 2726 | { NULL, NULL, 0, 0 } |
2088 | }; | 2727 | }; |
2089 | 2728 | ||
2090 | 2729 | ||
2730 | const char * | ||
2731 | path_basename (const char *path) | ||
2732 | { | ||
2733 | const char *basename = strrchr (path, DIR_SEPARATOR); | ||
2734 | if (NULL != basename) | ||
2735 | basename++; | ||
2736 | |||
2737 | if (NULL == basename || '\0' == basename) | ||
2738 | return NULL; | ||
2739 | |||
2740 | return basename; | ||
2741 | } | ||
2742 | |||
2743 | |||
2744 | struct PlaceLoadClosure | ||
2745 | { | ||
2746 | const char *app_id; | ||
2747 | const char *ego_pub_hash_str; | ||
2748 | }; | ||
2749 | |||
2750 | |||
2751 | /** Load a place file */ | ||
2091 | int | 2752 | int |
2092 | file_place_load (void *cls, const char *filename) | 2753 | file_place_load (void *cls, const char *filename) |
2093 | { | 2754 | { |
2094 | uint64_t fsize = 0; | 2755 | char *app_id = cls; |
2756 | uint64_t file_size = 0; | ||
2095 | if (GNUNET_OK != | 2757 | if (GNUNET_OK != |
2096 | GNUNET_DISK_file_size (filename, &fsize, GNUNET_YES, GNUNET_YES) | 2758 | GNUNET_DISK_file_size (filename, &file_size, GNUNET_YES, GNUNET_YES) |
2097 | || fsize < sizeof (struct HostEnterRequest)) | 2759 | || file_size < sizeof (struct HostEnterRequest)) |
2098 | return GNUNET_OK; | 2760 | return GNUNET_OK; |
2099 | 2761 | ||
2100 | struct GNUNET_MessageHeader *msg = GNUNET_malloc (fsize); | 2762 | struct PlaceEnterRequest *ereq = GNUNET_malloc (file_size); |
2101 | ssize_t rsize = GNUNET_DISK_fn_read (filename, msg, fsize); | 2763 | ssize_t read_size = GNUNET_DISK_fn_read (filename, ereq, file_size); |
2102 | if (rsize < 0 || (size_t) rsize < sizeof (*msg)) | 2764 | if (read_size < 0 || read_size < sizeof (*ereq)) |
2103 | return GNUNET_OK; | 2765 | return GNUNET_OK; |
2104 | 2766 | ||
2105 | uint16_t msg_size = ntohs (msg->size); | 2767 | uint16_t ereq_size = ntohs (ereq->header.size); |
2106 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub; | 2768 | if (read_size != ereq_size) |
2107 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub; | 2769 | return GNUNET_OK; |
2108 | 2770 | ||
2109 | switch (ntohs (msg->type)) | 2771 | switch (ntohs (ereq->header.type)) |
2110 | { | 2772 | { |
2111 | case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER: | 2773 | case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER: |
2112 | if (msg_size < sizeof (struct HostEnterRequest)) | 2774 | if (ereq_size < sizeof (struct HostEnterRequest)) |
2113 | return GNUNET_OK; | 2775 | return GNUNET_OK; |
2114 | struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg; | 2776 | struct HostEnterRequest *hreq = (struct HostEnterRequest *) ereq; |
2115 | GNUNET_CRYPTO_ecdsa_key_get_public (&hreq->host_key, &ego_pub); | ||
2116 | GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub); | ||
2117 | |||
2118 | host_enter (hreq, NULL); | 2777 | host_enter (hreq, NULL); |
2119 | break; | 2778 | break; |
2120 | 2779 | ||
2121 | case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER: | 2780 | case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER: |
2122 | if (msg_size < sizeof (struct GuestEnterRequest)) | 2781 | if (ereq_size < sizeof (struct GuestEnterRequest)) |
2123 | return GNUNET_OK; | 2782 | return GNUNET_OK; |
2124 | struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg; | 2783 | struct GuestEnterRequest *greq = (struct GuestEnterRequest *) ereq; |
2125 | GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &ego_pub); | ||
2126 | place_pub = greq->place_key; | ||
2127 | |||
2128 | guest_enter (greq, NULL); | 2784 | guest_enter (greq, NULL); |
2129 | break; | 2785 | break; |
2130 | 2786 | ||
@@ -2132,40 +2788,135 @@ file_place_load (void *cls, const char *filename) | |||
2132 | return GNUNET_OK; | 2788 | return GNUNET_OK; |
2133 | } | 2789 | } |
2134 | 2790 | ||
2135 | struct GNUNET_HashCode ego_pub_hash, place_pub_hash; | 2791 | app_place_add (app_id, ereq); |
2136 | GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash); | 2792 | return GNUNET_OK; |
2137 | GNUNET_CRYPTO_hash (&place_pub, sizeof (place_pub), &place_pub_hash); | 2793 | } |
2794 | |||
2795 | |||
2796 | /** Load an ego place file */ | ||
2797 | int | ||
2798 | file_ego_place_load (void *cls, const char *place_filename) | ||
2799 | { | ||
2800 | struct PlaceLoadClosure *plcls = cls; | ||
2138 | 2801 | ||
2139 | place_add (&ego_pub_hash, &place_pub_hash, msg); | 2802 | const char *place_pub_hash_str = path_basename (place_filename); |
2803 | if (NULL == place_pub_hash_str) | ||
2804 | { | ||
2805 | GNUNET_break (0); | ||
2806 | return GNUNET_OK; | ||
2807 | } | ||
2808 | |||
2809 | char *filename = NULL; | ||
2810 | GNUNET_asprintf (&filename, "%s%c" "%s%c" "%s%c" "%s", | ||
2811 | dir_social, DIR_SEPARATOR, | ||
2812 | "places", DIR_SEPARATOR, | ||
2813 | plcls->ego_pub_hash_str, DIR_SEPARATOR, | ||
2814 | place_pub_hash_str); | ||
2815 | |||
2816 | struct PlaceEnterRequest ereq[GNUNET_SERVER_MAX_MESSAGE_SIZE]; | ||
2817 | |||
2818 | int read_size = GNUNET_DISK_fn_read (filename, &ereq, | ||
2819 | GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
2820 | GNUNET_free (filename); | ||
2821 | |||
2822 | if (read_size < (ssize_t) sizeof (ereq)) | ||
2823 | return GNUNET_OK; | ||
2824 | |||
2825 | app_place_add (plcls->app_id, ereq); | ||
2140 | return GNUNET_OK; | 2826 | return GNUNET_OK; |
2141 | } | 2827 | } |
2142 | 2828 | ||
2143 | 2829 | ||
2830 | /** | ||
2831 | * Read @e place_pub_hash_str entries in @a dir_ego | ||
2832 | * | ||
2833 | * @param dir_ego | ||
2834 | * Data directory of an application ego. | ||
2835 | * e.g. ~/.local/share/gnunet/social/apps/$app_id/$ego_pub_hash_str/ | ||
2836 | */ | ||
2837 | int | ||
2838 | scan_app_ego_dir (void *cls, const char *dir_ego) | ||
2839 | { | ||
2840 | struct PlaceLoadClosure *plcls = cls; | ||
2841 | plcls->ego_pub_hash_str = path_basename (dir_ego); | ||
2842 | |||
2843 | if (NULL != plcls->ego_pub_hash_str) | ||
2844 | GNUNET_DISK_directory_scan (dir_ego, file_ego_place_load, plcls); | ||
2845 | |||
2846 | return GNUNET_OK; | ||
2847 | } | ||
2848 | |||
2849 | /** | ||
2850 | * Read @e ego_pub_hash_str entries in @a dir_app | ||
2851 | * | ||
2852 | * @param dir_app | ||
2853 | * Data directory of an application. | ||
2854 | * e.g. ~/.local/share/gnunet/social/apps/$app_id/ | ||
2855 | */ | ||
2144 | int | 2856 | int |
2145 | load_places_of_ego (void *cls, const char *dir_ego) | 2857 | scan_app_dir (void *cls, const char *dir_app) |
2146 | { | 2858 | { |
2147 | if (GNUNET_YES != GNUNET_DISK_directory_test (dir_ego, GNUNET_YES)) | 2859 | if (GNUNET_YES != GNUNET_DISK_directory_test (dir_app, GNUNET_YES)) |
2148 | return GNUNET_OK; | 2860 | return GNUNET_OK; |
2149 | 2861 | ||
2150 | GNUNET_DISK_directory_scan (dir_ego, file_place_load, NULL); | 2862 | struct PlaceLoadClosure plcls; |
2863 | plcls.app_id = path_basename (dir_app); | ||
2864 | |||
2865 | if (NULL != plcls.app_id) | ||
2866 | GNUNET_DISK_directory_scan (dir_app, scan_app_ego_dir, &plcls); | ||
2867 | |||
2151 | return GNUNET_OK; | 2868 | return GNUNET_OK; |
2152 | } | 2869 | } |
2153 | 2870 | ||
2154 | 2871 | ||
2155 | void | 2872 | static void |
2156 | load_places () | 2873 | identity_recv_ego (void *cls, struct GNUNET_IDENTITY_Ego *id_ego, |
2874 | void **ctx, const char *name) | ||
2157 | { | 2875 | { |
2158 | if (GNUNET_OK != | 2876 | if (NULL == id_ego) // end of initial list of egos |
2159 | GNUNET_CONFIGURATION_get_value_filename (cfg, "social", "PLACES_DIR", | ||
2160 | &dir_places)) | ||
2161 | { | ||
2162 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "social", "PLACES_DIR"); | ||
2163 | GNUNET_break (0); | ||
2164 | return; | 2877 | return; |
2878 | |||
2879 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
2880 | GNUNET_IDENTITY_ego_get_public_key (id_ego, &ego_pub_key); | ||
2881 | |||
2882 | struct GNUNET_HashCode ego_pub_hash; | ||
2883 | GNUNET_CRYPTO_hash (&ego_pub_key, sizeof (ego_pub_key), &ego_pub_hash); | ||
2884 | |||
2885 | struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash); | ||
2886 | if (NULL != ego) | ||
2887 | { | ||
2888 | GNUNET_free (ego->name); | ||
2889 | if (NULL == name) // deleted | ||
2890 | { | ||
2891 | GNUNET_CONTAINER_multihashmap_remove (egos, &ego_pub_hash, ego); | ||
2892 | GNUNET_free (ego); | ||
2893 | ego = NULL; | ||
2894 | } | ||
2895 | } | ||
2896 | else | ||
2897 | { | ||
2898 | ego = GNUNET_malloc (sizeof (*ego)); | ||
2165 | } | 2899 | } |
2900 | if (NULL != ego) | ||
2901 | { | ||
2902 | ego->key = *(GNUNET_IDENTITY_ego_get_private_key (id_ego)); | ||
2903 | size_t name_size = strlen (name) + 1; | ||
2904 | ego->name = GNUNET_malloc (name_size); | ||
2905 | memcpy (ego->name, name, name_size); | ||
2166 | 2906 | ||
2167 | places_entered = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); | 2907 | GNUNET_CONTAINER_multihashmap_put (egos, &ego_pub_hash, ego, |
2168 | GNUNET_DISK_directory_scan (dir_places, load_places_of_ego, NULL); | 2908 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
2909 | } | ||
2910 | } | ||
2911 | |||
2912 | |||
2913 | /** | ||
2914 | * Connected to core service. | ||
2915 | */ | ||
2916 | static void | ||
2917 | core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity) | ||
2918 | { | ||
2919 | this_peer = *my_identity; | ||
2169 | } | 2920 | } |
2170 | 2921 | ||
2171 | 2922 | ||
@@ -2181,12 +2932,38 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
2181 | const struct GNUNET_CONFIGURATION_Handle *c) | 2932 | const struct GNUNET_CONFIGURATION_Handle *c) |
2182 | { | 2933 | { |
2183 | cfg = c; | 2934 | cfg = c; |
2184 | stats = GNUNET_STATISTICS_create ("social", cfg); | 2935 | |
2185 | hosts = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | 2936 | hosts = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); |
2186 | guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | 2937 | guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); |
2187 | place_guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 2938 | place_guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
2188 | place_listeners = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 2939 | |
2189 | load_places (); | 2940 | egos = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
2941 | apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
2942 | places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); | ||
2943 | apps_places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); | ||
2944 | |||
2945 | core = GNUNET_CORE_connect (cfg, NULL, core_connected, NULL, NULL, | ||
2946 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); | ||
2947 | id = GNUNET_IDENTITY_connect (cfg, &identity_recv_ego, NULL); | ||
2948 | gns = GNUNET_GNS_connect (cfg); | ||
2949 | namestore = GNUNET_NAMESTORE_connect (cfg); | ||
2950 | stats = GNUNET_STATISTICS_create ("social", cfg); | ||
2951 | |||
2952 | if (GNUNET_OK != | ||
2953 | GNUNET_CONFIGURATION_get_value_filename (cfg, "social", "SOCIAL_DATA_DIR", | ||
2954 | &dir_social)) | ||
2955 | { | ||
2956 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
2957 | "social", "SOCIAL_DATA_DIR"); | ||
2958 | GNUNET_break (0); | ||
2959 | return; | ||
2960 | } | ||
2961 | GNUNET_asprintf (&dir_places, "%s%c%s", | ||
2962 | dir_social, DIR_SEPARATOR, "places"); | ||
2963 | GNUNET_asprintf (&dir_apps, "%s%c%s", | ||
2964 | dir_social, DIR_SEPARATOR, "apps"); | ||
2965 | |||
2966 | GNUNET_DISK_directory_scan (dir_apps, scan_app_dir, NULL); | ||
2190 | 2967 | ||
2191 | nc = GNUNET_SERVER_notification_context_create (server, 1); | 2968 | nc = GNUNET_SERVER_notification_context_create (server, 1); |
2192 | GNUNET_SERVER_add_handlers (server, handlers); | 2969 | GNUNET_SERVER_add_handlers (server, handlers); |
diff --git a/src/social/social.h b/src/social/social.h index 6dfd55612..651338c51 100644 --- a/src/social/social.h +++ b/src/social/social.h | |||
@@ -49,6 +49,37 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
49 | /**** library -> service ****/ | 49 | /**** library -> service ****/ |
50 | 50 | ||
51 | 51 | ||
52 | struct AppConnectRequest | ||
53 | { | ||
54 | /** | ||
55 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT | ||
56 | */ | ||
57 | struct GNUNET_MessageHeader header; | ||
58 | |||
59 | /* Followed by char *app_id */ | ||
60 | }; | ||
61 | |||
62 | |||
63 | struct AppDetachRequest | ||
64 | { | ||
65 | /** | ||
66 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH | ||
67 | */ | ||
68 | struct GNUNET_MessageHeader header; | ||
69 | |||
70 | /** | ||
71 | * Public key of place. | ||
72 | */ | ||
73 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
74 | |||
75 | /** | ||
76 | * Operation ID. | ||
77 | */ | ||
78 | uint64_t op_id GNUNET_PACKED; | ||
79 | |||
80 | }; | ||
81 | |||
82 | |||
52 | struct HostEnterRequest | 83 | struct HostEnterRequest |
53 | { | 84 | { |
54 | /** | 85 | /** |
@@ -58,46 +89,179 @@ struct HostEnterRequest | |||
58 | 89 | ||
59 | uint32_t policy GNUNET_PACKED; | 90 | uint32_t policy GNUNET_PACKED; |
60 | 91 | ||
61 | struct GNUNET_CRYPTO_EcdsaPrivateKey host_key; | 92 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; |
93 | |||
94 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
62 | 95 | ||
63 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key; | 96 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key; |
97 | |||
98 | /* Followed by char *app_id */ | ||
64 | }; | 99 | }; |
65 | 100 | ||
66 | 101 | ||
67 | struct GuestEnterRequest | 102 | struct GuestEnterRequest |
68 | { | 103 | { |
69 | /** | 104 | /** |
70 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ADDR | 105 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER |
71 | */ | 106 | */ |
72 | struct GNUNET_MessageHeader header; | 107 | struct GNUNET_MessageHeader header; |
73 | 108 | ||
74 | uint32_t relay_count GNUNET_PACKED; | 109 | uint32_t relay_count GNUNET_PACKED; |
75 | 110 | ||
76 | struct GNUNET_CRYPTO_EcdsaPrivateKey guest_key; | 111 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; |
77 | 112 | ||
78 | struct GNUNET_CRYPTO_EddsaPublicKey place_key; | 113 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; |
79 | 114 | ||
80 | struct GNUNET_PeerIdentity origin; | 115 | struct GNUNET_PeerIdentity origin; |
81 | 116 | ||
117 | /* Followed by char *app_id */ | ||
82 | /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ | 118 | /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ |
119 | /* Followed by struct GNUNET_MessageHeader *join_msg */ | ||
120 | }; | ||
121 | |||
83 | 122 | ||
84 | /* Followed by struct GNUNET_MessageHeader join_msg */ | 123 | /** Compatible parts of HostEnterRequest and GuestEnterRequest */ |
124 | struct PlaceEnterRequest | ||
125 | { | ||
126 | struct GNUNET_MessageHeader header; | ||
127 | |||
128 | uint32_t reserved GNUNET_PACKED; | ||
129 | |||
130 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
131 | |||
132 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
85 | }; | 133 | }; |
86 | 134 | ||
87 | 135 | ||
88 | struct PlaceListenRequest | 136 | struct EgoPlacePublicKey |
137 | { | ||
138 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
139 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
140 | }; | ||
141 | |||
142 | |||
143 | struct GuestEnterByNameRequest | ||
89 | { | 144 | { |
90 | /** | 145 | /** |
91 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN | 146 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME |
92 | */ | 147 | */ |
93 | struct GNUNET_MessageHeader header; | 148 | struct GNUNET_MessageHeader header; |
94 | 149 | ||
95 | struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key; | 150 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; |
151 | |||
152 | /* Followed by char *app_id */ | ||
153 | /* Followed by char *gns_name */ | ||
154 | /* Followed by char *password */ | ||
155 | /* Followed by struct GNUNET_MessageHeader *join_msg */ | ||
96 | }; | 156 | }; |
97 | 157 | ||
98 | 158 | ||
159 | struct ZoneAddPlaceRequest | ||
160 | { | ||
161 | struct GNUNET_MessageHeader header; | ||
162 | |||
163 | uint32_t relay_count GNUNET_PACKED; | ||
164 | |||
165 | /** | ||
166 | * Operation ID. | ||
167 | */ | ||
168 | uint64_t op_id; | ||
169 | |||
170 | /** | ||
171 | * Expiration time: absolute value in us. | ||
172 | */ | ||
173 | uint64_t expiration_time; | ||
174 | |||
175 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
176 | |||
177 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
178 | |||
179 | struct GNUNET_PeerIdentity origin; | ||
180 | |||
181 | /* Followed by const char *name */ | ||
182 | /* Followed by const char *password */ | ||
183 | /* Followed by struct GNUNET_PeerIdentity *relays[relay_count] */ | ||
184 | }; | ||
185 | |||
186 | |||
187 | struct ZoneAddNymRequest | ||
188 | { | ||
189 | struct GNUNET_MessageHeader header; | ||
190 | |||
191 | /** | ||
192 | * Operation ID. | ||
193 | */ | ||
194 | uint64_t op_id; | ||
195 | |||
196 | /** | ||
197 | * Expiration time: absolute value in us. | ||
198 | */ | ||
199 | uint64_t expiration_time; | ||
200 | |||
201 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
202 | |||
203 | struct GNUNET_CRYPTO_EcdsaPublicKey nym_pub_key; | ||
204 | |||
205 | /* Followed by const char *name */ | ||
206 | }; | ||
207 | |||
99 | /**** service -> library ****/ | 208 | /**** service -> library ****/ |
100 | 209 | ||
210 | |||
211 | struct AppEgoMessage | ||
212 | { | ||
213 | /** | ||
214 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO | ||
215 | */ | ||
216 | struct GNUNET_MessageHeader header; | ||
217 | |||
218 | /** | ||
219 | * Public key of ego. | ||
220 | */ | ||
221 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
222 | |||
223 | /* Followed by char *name */ | ||
224 | }; | ||
225 | |||
226 | |||
227 | struct AppPlaceMessage | ||
228 | { | ||
229 | /** | ||
230 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE | ||
231 | */ | ||
232 | struct GNUNET_MessageHeader header; | ||
233 | |||
234 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
235 | |||
236 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
237 | |||
238 | uint8_t is_host; | ||
239 | }; | ||
240 | |||
241 | |||
242 | struct HostEnterAck { | ||
243 | /** | ||
244 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK | ||
245 | */ | ||
246 | struct GNUNET_MessageHeader header; | ||
247 | |||
248 | /** | ||
249 | * Status code for the operation. | ||
250 | */ | ||
251 | uint32_t result_code GNUNET_PACKED; | ||
252 | |||
253 | /** | ||
254 | * Last message ID sent to the channel. | ||
255 | */ | ||
256 | uint64_t max_message_id GNUNET_PACKED; | ||
257 | |||
258 | /** | ||
259 | * Public key of the place. | ||
260 | */ | ||
261 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
262 | }; | ||
263 | |||
264 | |||
101 | #if REMOVE | 265 | #if REMOVE |
102 | struct NymEnterRequest | 266 | struct NymEnterRequest |
103 | { | 267 | { |
@@ -105,6 +269,7 @@ struct NymEnterRequest | |||
105 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_NYM_ENTER | 269 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_NYM_ENTER |
106 | */ | 270 | */ |
107 | struct GNUNET_MessageHeader header; | 271 | struct GNUNET_MessageHeader header; |
272 | |||
108 | /** | 273 | /** |
109 | * Public key of the joining slave. | 274 | * Public key of the joining slave. |
110 | */ | 275 | */ |
diff --git a/src/social/social_api.c b/src/social/social_api.c index 9a2f99ae8..6c85ba294 100644 --- a/src/social/social_api.c +++ b/src/social/social_api.c | |||
@@ -30,10 +30,6 @@ | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | #include "gnunet_env_lib.h" | 32 | #include "gnunet_env_lib.h" |
33 | #include "gnunet_core_service.h" | ||
34 | #include "gnunet_identity_service.h" | ||
35 | #include "gnunet_namestore_service.h" | ||
36 | #include "gnunet_gns_service.h" | ||
37 | #include "gnunet_psyc_service.h" | 33 | #include "gnunet_psyc_service.h" |
38 | #include "gnunet_psyc_util_lib.h" | 34 | #include "gnunet_psyc_util_lib.h" |
39 | #include "gnunet_social_service.h" | 35 | #include "gnunet_social_service.h" |
@@ -41,11 +37,15 @@ | |||
41 | 37 | ||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "social-api",__VA_ARGS__) | 38 | #define LOG(kind,...) GNUNET_log_from (kind, "social-api",__VA_ARGS__) |
43 | 39 | ||
44 | 40 | /** | |
45 | static struct GNUNET_CORE_Handle *core; | 41 | * Handle for an ego. |
46 | static struct GNUNET_GNS_Handle *gns; | 42 | */ |
47 | static struct GNUNET_NAMESTORE_Handle *namestore; | 43 | struct GNUNET_SOCIAL_Ego |
48 | static struct GNUNET_PeerIdentity this_peer; | 44 | { |
45 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | ||
46 | struct GNUNET_HashCode pub_key_hash; | ||
47 | char *name; | ||
48 | }; | ||
49 | 49 | ||
50 | 50 | ||
51 | /** | 51 | /** |
@@ -59,6 +59,76 @@ struct GNUNET_SOCIAL_Nym | |||
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Handle for an application. | ||
63 | */ | ||
64 | struct GNUNET_SOCIAL_App | ||
65 | { | ||
66 | /** | ||
67 | * Configuration to use. | ||
68 | */ | ||
69 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
70 | |||
71 | /** | ||
72 | * Client connection to the service. | ||
73 | */ | ||
74 | struct GNUNET_CLIENT_MANAGER_Connection *client; | ||
75 | |||
76 | /** | ||
77 | * Message to send on reconnect. | ||
78 | */ | ||
79 | struct GNUNET_MessageHeader *connect_msg; | ||
80 | |||
81 | /** | ||
82 | * Function called after disconnected from the service. | ||
83 | */ | ||
84 | GNUNET_ContinuationCallback disconnect_cb; | ||
85 | |||
86 | /** | ||
87 | * Closure for @a disconnect_cb. | ||
88 | */ | ||
89 | void *disconnect_cls; | ||
90 | |||
91 | /** | ||
92 | * Application ID. | ||
93 | */ | ||
94 | char *id; | ||
95 | |||
96 | /** | ||
97 | * Hash map of all egos. | ||
98 | * pub_key_hash -> struct GNUNET_SOCIAL_Ego * | ||
99 | */ | ||
100 | struct GNUNET_CONTAINER_MultiHashMap *egos; | ||
101 | |||
102 | GNUNET_SOCIAL_AppEgoCallback ego_cb; | ||
103 | GNUNET_SOCIAL_AppHostPlaceCallback host_cb; | ||
104 | GNUNET_SOCIAL_AppGuestPlaceCallback guest_cb; | ||
105 | void *cb_cls; | ||
106 | |||
107 | /** | ||
108 | * Is this place in the process of disconnecting from the service? | ||
109 | * #GNUNET_YES or #GNUNET_NO | ||
110 | */ | ||
111 | uint8_t is_disconnecting; | ||
112 | }; | ||
113 | |||
114 | |||
115 | struct GNUNET_SOCIAL_HostConnection | ||
116 | { | ||
117 | struct GNUNET_SOCIAL_App *app; | ||
118 | |||
119 | struct AppPlaceMessage plc_msg; | ||
120 | }; | ||
121 | |||
122 | |||
123 | struct GNUNET_SOCIAL_GuestConnection | ||
124 | { | ||
125 | struct GNUNET_SOCIAL_App *app; | ||
126 | |||
127 | struct AppPlaceMessage plc_msg; | ||
128 | }; | ||
129 | |||
130 | |||
131 | /** | ||
62 | * Handle for a place where social interactions happen. | 132 | * Handle for a place where social interactions happen. |
63 | */ | 133 | */ |
64 | struct GNUNET_SOCIAL_Place | 134 | struct GNUNET_SOCIAL_Place |
@@ -109,9 +179,9 @@ struct GNUNET_SOCIAL_Place | |||
109 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | 179 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; |
110 | 180 | ||
111 | /** | 181 | /** |
112 | * Private key of the ego. | 182 | * Public key of the ego. |
113 | */ | 183 | */ |
114 | struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key; | 184 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; |
115 | 185 | ||
116 | /** | 186 | /** |
117 | * Does this place belong to a host (#GNUNET_YES) or guest (#GNUNET_NO)? | 187 | * Does this place belong to a host (#GNUNET_YES) or guest (#GNUNET_NO)? |
@@ -133,8 +203,6 @@ struct GNUNET_SOCIAL_Host | |||
133 | { | 203 | { |
134 | struct GNUNET_SOCIAL_Place plc; | 204 | struct GNUNET_SOCIAL_Place plc; |
135 | 205 | ||
136 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key; | ||
137 | |||
138 | /** | 206 | /** |
139 | * Receipt handle. | 207 | * Receipt handle. |
140 | */ | 208 | */ |
@@ -190,19 +258,6 @@ struct GNUNET_SOCIAL_Guest | |||
190 | 258 | ||
191 | 259 | ||
192 | /** | 260 | /** |
193 | * Handle for place notifications. | ||
194 | */ | ||
195 | struct GNUNET_SOCIAL_PlaceListenHandle | ||
196 | { | ||
197 | struct GNUNET_SOCIAL_Place plc; | ||
198 | |||
199 | GNUNET_SOCIAL_PlaceNotifyHostCallback notify_host; | ||
200 | GNUNET_SOCIAL_PlaceNotifyGuestCallback notify_guest; | ||
201 | void *notify_cls; | ||
202 | }; | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Hash map of all nyms. | 261 | * Hash map of all nyms. |
207 | * pub_key_hash -> struct GNUNET_SOCIAL_Nym * | 262 | * pub_key_hash -> struct GNUNET_SOCIAL_Nym * |
208 | */ | 263 | */ |
@@ -417,6 +472,22 @@ struct GNUNET_SOCIAL_LookHandle | |||
417 | }; | 472 | }; |
418 | 473 | ||
419 | 474 | ||
475 | struct ZoneAddPlaceHandle | ||
476 | { | ||
477 | struct ZoneAddPlaceRequest *req; | ||
478 | GNUNET_ResultCallback result_cb; | ||
479 | void *result_cls; | ||
480 | }; | ||
481 | |||
482 | |||
483 | struct ZoneAddNymHandle | ||
484 | { | ||
485 | struct ZoneAddNymRequest *req; | ||
486 | GNUNET_ResultCallback result_cb; | ||
487 | void *result_cls; | ||
488 | }; | ||
489 | |||
490 | |||
420 | /*** NYM ***/ | 491 | /*** NYM ***/ |
421 | 492 | ||
422 | static struct GNUNET_SOCIAL_Nym * | 493 | static struct GNUNET_SOCIAL_Nym * |
@@ -1012,6 +1083,31 @@ GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer) | |||
1012 | GNUNET_free (slicer); | 1083 | GNUNET_free (slicer); |
1013 | } | 1084 | } |
1014 | 1085 | ||
1086 | /*** CLIENT ***/ | ||
1087 | |||
1088 | |||
1089 | static void | ||
1090 | app_send_connect_msg (struct GNUNET_SOCIAL_App *app) | ||
1091 | { | ||
1092 | uint16_t cmsg_size = ntohs (app->connect_msg->size); | ||
1093 | struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size); | ||
1094 | memcpy (cmsg, app->connect_msg, cmsg_size); | ||
1095 | GNUNET_CLIENT_MANAGER_transmit_now (app->client, cmsg); | ||
1096 | } | ||
1097 | |||
1098 | |||
1099 | static void | ||
1100 | app_recv_disconnect (void *cls, | ||
1101 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
1102 | const struct GNUNET_MessageHeader *msg) | ||
1103 | { | ||
1104 | struct GNUNET_SOCIAL_App * | ||
1105 | app = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*app)); | ||
1106 | |||
1107 | GNUNET_CLIENT_MANAGER_reconnect (client); | ||
1108 | app_send_connect_msg (app); | ||
1109 | } | ||
1110 | |||
1015 | 1111 | ||
1016 | /*** PLACE ***/ | 1112 | /*** PLACE ***/ |
1017 | 1113 | ||
@@ -1066,6 +1162,32 @@ place_recv_result (void *cls, | |||
1066 | 1162 | ||
1067 | 1163 | ||
1068 | static void | 1164 | static void |
1165 | app_recv_result (void *cls, | ||
1166 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
1167 | const struct GNUNET_MessageHeader *msg) | ||
1168 | { | ||
1169 | struct GNUNET_SOCIAL_App * | ||
1170 | app = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*app)); | ||
1171 | |||
1172 | const struct GNUNET_OperationResultMessage * | ||
1173 | res = (const struct GNUNET_OperationResultMessage *) msg; | ||
1174 | |||
1175 | uint16_t size = ntohs (msg->size); | ||
1176 | if (size < sizeof (*res)) | ||
1177 | { /* Error, message too small. */ | ||
1178 | GNUNET_break (0); | ||
1179 | return; | ||
1180 | } | ||
1181 | |||
1182 | uint16_t data_size = size - sizeof (*res); | ||
1183 | const char *data = (0 < data_size) ? (const char *) &res[1] : NULL; | ||
1184 | GNUNET_CLIENT_MANAGER_op_result (app->client, GNUNET_ntohll (res->op_id), | ||
1185 | GNUNET_ntohll (res->result_code), | ||
1186 | data, data_size); | ||
1187 | } | ||
1188 | |||
1189 | |||
1190 | static void | ||
1069 | op_recv_history_result (void *cls, int64_t result, | 1191 | op_recv_history_result (void *cls, int64_t result, |
1070 | const void *err_msg, uint16_t err_msg_size) | 1192 | const void *err_msg, uint16_t err_msg_size) |
1071 | { | 1193 | { |
@@ -1261,11 +1383,13 @@ host_recv_enter_ack (void *cls, | |||
1261 | hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | 1383 | hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, |
1262 | sizeof (struct GNUNET_SOCIAL_Place)); | 1384 | sizeof (struct GNUNET_SOCIAL_Place)); |
1263 | 1385 | ||
1264 | struct GNUNET_PSYC_CountersResultMessage * | 1386 | struct HostEnterAck *hack = (struct HostEnterAck *) msg; |
1265 | cres = (struct GNUNET_PSYC_CountersResultMessage *) msg; | 1387 | hst->plc.pub_key = hack->place_pub_key; |
1266 | int32_t result = ntohl (cres->result_code); | 1388 | |
1389 | int32_t result = ntohl (hack->result_code); | ||
1267 | if (NULL != hst->enter_cb) | 1390 | if (NULL != hst->enter_cb) |
1268 | hst->enter_cb (hst->cb_cls, result, GNUNET_ntohll (cres->max_message_id)); | 1391 | hst->enter_cb (hst->cb_cls, result, &hack->place_pub_key, |
1392 | GNUNET_ntohll (hack->max_message_id)); | ||
1269 | } | 1393 | } |
1270 | 1394 | ||
1271 | 1395 | ||
@@ -1364,52 +1488,85 @@ guest_recv_join_decision (void *cls, | |||
1364 | 1488 | ||
1365 | 1489 | ||
1366 | static void | 1490 | static void |
1367 | notify_recv_place_host (void *cls, | 1491 | app_recv_ego (void *cls, |
1368 | struct GNUNET_CLIENT_MANAGER_Connection *client, | 1492 | struct GNUNET_CLIENT_MANAGER_Connection *client, |
1369 | const struct GNUNET_MessageHeader *msg) | 1493 | const struct GNUNET_MessageHeader *msg) |
1370 | { | 1494 | { |
1371 | struct GNUNET_SOCIAL_PlaceListenHandle * | 1495 | struct GNUNET_SOCIAL_App * |
1372 | pl = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*pl)); | 1496 | app = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*app)); |
1373 | if (NULL == pl->notify_host) | ||
1374 | return; | ||
1375 | 1497 | ||
1376 | struct HostEnterRequest * | 1498 | struct AppEgoMessage * |
1377 | hreq = (struct HostEnterRequest *) msg; | 1499 | emsg = (struct AppEgoMessage *) msg; |
1378 | 1500 | ||
1379 | pl->notify_host (pl->notify_cls, &hreq->place_key, ntohl (hreq->policy)); | 1501 | uint16_t name_size = ntohs (emsg->header.size) - sizeof (*emsg); |
1502 | |||
1503 | struct GNUNET_HashCode ego_pub_hash; | ||
1504 | GNUNET_CRYPTO_hash (&emsg->ego_pub_key, sizeof (emsg->ego_pub_key), | ||
1505 | &ego_pub_hash); | ||
1506 | |||
1507 | struct GNUNET_SOCIAL_Ego * | ||
1508 | ego = GNUNET_CONTAINER_multihashmap_get (app->egos, &ego_pub_hash); | ||
1509 | if (NULL == ego) | ||
1510 | { | ||
1511 | ego = GNUNET_malloc (sizeof (*ego)); | ||
1512 | ego->pub_key = emsg->ego_pub_key; | ||
1513 | ego->name = GNUNET_malloc (name_size); | ||
1514 | memcpy (ego->name, &emsg[1], name_size); | ||
1515 | } | ||
1516 | else | ||
1517 | { | ||
1518 | ego->name = GNUNET_realloc (ego->name, name_size); | ||
1519 | memcpy (ego->name, &emsg[1], name_size); | ||
1520 | } | ||
1521 | |||
1522 | GNUNET_CONTAINER_multihashmap_put (app->egos, &ego_pub_hash, ego, | ||
1523 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
1524 | |||
1525 | if (NULL != app->ego_cb) | ||
1526 | app->ego_cb (app->cb_cls, ego, &ego->pub_key, ego->name); | ||
1380 | } | 1527 | } |
1381 | 1528 | ||
1382 | 1529 | ||
1383 | static void | 1530 | static void |
1384 | notify_recv_place_guest (void *cls, | 1531 | app_recv_place (void *cls, |
1385 | struct GNUNET_CLIENT_MANAGER_Connection *client, | 1532 | struct GNUNET_CLIENT_MANAGER_Connection *client, |
1386 | const struct GNUNET_MessageHeader *msg) | 1533 | const struct GNUNET_MessageHeader *msg) |
1387 | { | 1534 | { |
1388 | struct GNUNET_SOCIAL_PlaceListenHandle * | 1535 | struct GNUNET_SOCIAL_App * |
1389 | pl = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*pl)); | 1536 | app = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*app)); |
1390 | if (NULL == pl->notify_guest) | ||
1391 | return; | ||
1392 | 1537 | ||
1393 | struct GuestEnterRequest * | 1538 | struct AppPlaceMessage * |
1394 | greq = (struct GuestEnterRequest *) msg; | 1539 | pmsg = (struct AppPlaceMessage *) msg; |
1395 | uint16_t greq_size = ntohs (greq->header.size); | ||
1396 | 1540 | ||
1397 | const struct GNUNET_PeerIdentity *relays = NULL; | 1541 | if ((GNUNET_YES == pmsg->is_host && NULL == app->host_cb) |
1398 | uint16_t relay_count = ntohs (greq->relay_count); | 1542 | || (GNUNET_NO == pmsg->is_host && NULL == app->guest_cb)) |
1399 | uint16_t relay_size = relay_count * sizeof (*relays); | 1543 | return; |
1400 | if (0 < relay_size) | ||
1401 | relays = (const struct GNUNET_PeerIdentity *) &greq[1]; | ||
1402 | struct GNUNET_PSYC_Message *join_msg = NULL; | ||
1403 | 1544 | ||
1404 | if (sizeof (*greq) + relay_size + sizeof (struct GNUNET_MessageHeader) | 1545 | struct GNUNET_HashCode ego_pub_hash; |
1405 | <= greq_size) | 1546 | GNUNET_CRYPTO_hash (&pmsg->ego_pub_key, sizeof (pmsg->ego_pub_key), |
1547 | &ego_pub_hash); | ||
1548 | struct GNUNET_SOCIAL_Ego * | ||
1549 | ego = GNUNET_CONTAINER_multihashmap_get (app->egos, &ego_pub_hash); | ||
1550 | if (NULL == ego) | ||
1406 | { | 1551 | { |
1407 | join_msg = (struct GNUNET_PSYC_Message *) | 1552 | GNUNET_break (0); |
1408 | (((char *) &greq[1]) + relay_size); | 1553 | return; |
1409 | } | 1554 | } |
1410 | 1555 | ||
1411 | pl->notify_guest (pl->notify_cls, &greq->place_key, &greq->origin, | 1556 | if (GNUNET_YES == pmsg->is_host) |
1412 | relay_count, relays, join_msg); | 1557 | { |
1558 | struct GNUNET_SOCIAL_HostConnection *hconn = GNUNET_malloc (sizeof (*hconn)); | ||
1559 | hconn->app = app; | ||
1560 | hconn->plc_msg = *pmsg; | ||
1561 | app->host_cb (app->cb_cls, hconn, ego, &pmsg->place_pub_key); | ||
1562 | } | ||
1563 | else | ||
1564 | { | ||
1565 | struct GNUNET_SOCIAL_GuestConnection *gconn = GNUNET_malloc (sizeof (*gconn)); | ||
1566 | gconn->app = app; | ||
1567 | gconn->plc_msg = *pmsg; | ||
1568 | app->guest_cb (app->cb_cls, gconn, ego, &pmsg->place_pub_key); | ||
1569 | } | ||
1413 | } | 1570 | } |
1414 | 1571 | ||
1415 | 1572 | ||
@@ -1417,7 +1574,7 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] = | |||
1417 | { | 1574 | { |
1418 | { host_recv_enter_ack, NULL, | 1575 | { host_recv_enter_ack, NULL, |
1419 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK, | 1576 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK, |
1420 | sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO }, | 1577 | sizeof (struct HostEnterAck), GNUNET_NO }, |
1421 | 1578 | ||
1422 | { host_recv_enter_request, NULL, | 1579 | { host_recv_enter_request, NULL, |
1423 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, | 1580 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, |
@@ -1490,15 +1647,21 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler guest_handlers[] = | |||
1490 | 1647 | ||
1491 | 1648 | ||
1492 | 1649 | ||
1493 | static struct GNUNET_CLIENT_MANAGER_MessageHandler notify_handlers[] = | 1650 | static struct GNUNET_CLIENT_MANAGER_MessageHandler app_handlers[] = |
1494 | { | 1651 | { |
1495 | { notify_recv_place_host, NULL, | 1652 | { app_recv_ego, NULL, |
1496 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, | 1653 | GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO, |
1497 | sizeof (struct HostEnterRequest), GNUNET_NO }, | 1654 | sizeof (struct AppEgoMessage), GNUNET_YES }, |
1655 | |||
1656 | { app_recv_place, NULL, | ||
1657 | GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE, | ||
1658 | sizeof (struct AppPlaceMessage), GNUNET_NO }, | ||
1498 | 1659 | ||
1499 | { notify_recv_place_guest, NULL, | 1660 | { app_recv_result, NULL, |
1500 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, | 1661 | GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE, |
1501 | sizeof (struct GuestEnterRequest), GNUNET_YES }, | 1662 | sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, |
1663 | |||
1664 | { app_recv_disconnect, NULL, 0, 0, GNUNET_NO }, | ||
1502 | 1665 | ||
1503 | { NULL, NULL, 0, 0, GNUNET_NO } | 1666 | { NULL, NULL, 0, 0, GNUNET_NO } |
1504 | }; | 1667 | }; |
@@ -1515,22 +1678,6 @@ place_cleanup (struct GNUNET_SOCIAL_Place *plc) | |||
1515 | GNUNET_free (plc->connect_msg); | 1678 | GNUNET_free (plc->connect_msg); |
1516 | if (NULL != plc->disconnect_cb) | 1679 | if (NULL != plc->disconnect_cb) |
1517 | plc->disconnect_cb (plc->disconnect_cls); | 1680 | plc->disconnect_cb (plc->disconnect_cls); |
1518 | |||
1519 | if (NULL != core) | ||
1520 | { | ||
1521 | GNUNET_CORE_disconnect (core); | ||
1522 | core = NULL; | ||
1523 | } | ||
1524 | if (NULL != namestore) | ||
1525 | { | ||
1526 | GNUNET_NAMESTORE_disconnect (namestore); | ||
1527 | namestore = NULL; | ||
1528 | } | ||
1529 | if (NULL != gns) | ||
1530 | { | ||
1531 | GNUNET_GNS_disconnect (gns); | ||
1532 | gns = NULL; | ||
1533 | } | ||
1534 | } | 1681 | } |
1535 | 1682 | ||
1536 | 1683 | ||
@@ -1539,8 +1686,16 @@ host_cleanup (void *cls) | |||
1539 | { | 1686 | { |
1540 | struct GNUNET_SOCIAL_Host *hst = cls; | 1687 | struct GNUNET_SOCIAL_Host *hst = cls; |
1541 | place_cleanup (&hst->plc); | 1688 | place_cleanup (&hst->plc); |
1542 | GNUNET_PSYC_receive_destroy (hst->recv); | 1689 | if (NULL != hst->recv) |
1543 | GNUNET_SOCIAL_slicer_destroy (hst->slicer); | 1690 | { |
1691 | GNUNET_PSYC_receive_destroy (hst->recv); | ||
1692 | hst->recv = NULL; | ||
1693 | } | ||
1694 | if (NULL != hst->slicer) | ||
1695 | { | ||
1696 | GNUNET_SOCIAL_slicer_destroy (hst->slicer); | ||
1697 | hst->slicer = NULL; | ||
1698 | } | ||
1544 | GNUNET_free (hst); | 1699 | GNUNET_free (hst); |
1545 | } | 1700 | } |
1546 | 1701 | ||
@@ -1568,11 +1723,13 @@ guest_cleanup (void *cls) | |||
1568 | * Identity of the host. | 1723 | * Identity of the host. |
1569 | * @param place_key | 1724 | * @param place_key |
1570 | * Private-public key pair of the place. | 1725 | * Private-public key pair of the place. |
1571 | * NULL for ephemeral places. | 1726 | * NULL to generate a key. |
1572 | * @param policy | 1727 | * @param policy |
1573 | * Policy specifying entry and history restrictions for the place. | 1728 | * Policy specifying entry and history restrictions for the place. |
1574 | * @param slicer | 1729 | * @param slicer |
1575 | * Slicer to handle incoming messages. | 1730 | * Slicer to handle incoming messages. |
1731 | * @param enter_cb | ||
1732 | * Function called when the place is entered and ready to use. | ||
1576 | * @param answer_door_cb | 1733 | * @param answer_door_cb |
1577 | * Function to handle new nyms that want to enter. | 1734 | * Function to handle new nyms that want to enter. |
1578 | * @param farewell_cb | 1735 | * @param farewell_cb |
@@ -1583,9 +1740,8 @@ guest_cleanup (void *cls) | |||
1583 | * @return Handle for the host. | 1740 | * @return Handle for the host. |
1584 | */ | 1741 | */ |
1585 | struct GNUNET_SOCIAL_Host * | 1742 | struct GNUNET_SOCIAL_Host * |
1586 | GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1743 | GNUNET_SOCIAL_host_enter (const struct GNUNET_SOCIAL_App *app, |
1587 | const struct GNUNET_IDENTITY_Ego *ego, | 1744 | const struct GNUNET_SOCIAL_Ego *ego, |
1588 | const struct GNUNET_CRYPTO_EddsaPrivateKey *place_key, | ||
1589 | enum GNUNET_PSYC_Policy policy, | 1745 | enum GNUNET_PSYC_Policy policy, |
1590 | struct GNUNET_SOCIAL_Slicer *slicer, | 1746 | struct GNUNET_SOCIAL_Slicer *slicer, |
1591 | GNUNET_SOCIAL_HostEnterCallback enter_cb, | 1747 | GNUNET_SOCIAL_HostEnterCallback enter_cb, |
@@ -1595,35 +1751,17 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1595 | { | 1751 | { |
1596 | struct GNUNET_SOCIAL_Host *hst = GNUNET_malloc (sizeof (*hst)); | 1752 | struct GNUNET_SOCIAL_Host *hst = GNUNET_malloc (sizeof (*hst)); |
1597 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | 1753 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; |
1598 | struct HostEnterRequest *req = GNUNET_malloc (sizeof (*req)); | ||
1599 | |||
1600 | if (NULL != place_key) | ||
1601 | { | ||
1602 | hst->place_key = *place_key; | ||
1603 | } | ||
1604 | else | ||
1605 | { | ||
1606 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
1607 | ephemeral_key = GNUNET_CRYPTO_eddsa_key_create (); | ||
1608 | hst->place_key = *ephemeral_key; | ||
1609 | GNUNET_CRYPTO_eddsa_key_get_public (&hst->place_key, &plc->pub_key); | ||
1610 | GNUNET_CRYPTO_eddsa_key_clear (ephemeral_key); | ||
1611 | GNUNET_free (ephemeral_key); | ||
1612 | } | ||
1613 | 1754 | ||
1614 | plc->cfg = cfg; | 1755 | plc->cfg = app->cfg; |
1615 | plc->is_host = GNUNET_YES; | 1756 | plc->is_host = GNUNET_YES; |
1616 | plc->slicer = slicer; | 1757 | plc->slicer = slicer; |
1617 | 1758 | ||
1618 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1619 | GNUNET_CRYPTO_eddsa_key_get_public (place_key, &plc->pub_key); | ||
1620 | |||
1621 | hst->enter_cb = enter_cb; | 1759 | hst->enter_cb = enter_cb; |
1622 | hst->answer_door_cb = answer_door_cb; | 1760 | hst->answer_door_cb = answer_door_cb; |
1623 | hst->farewell_cb = farewell_cb; | 1761 | hst->farewell_cb = farewell_cb; |
1624 | hst->cb_cls = cls; | 1762 | hst->cb_cls = cls; |
1625 | 1763 | ||
1626 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", host_handlers); | 1764 | plc->client = GNUNET_CLIENT_MANAGER_connect (plc->cfg, "social", host_handlers); |
1627 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); | 1765 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); |
1628 | 1766 | ||
1629 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | 1767 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); |
@@ -1636,13 +1774,15 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1636 | NULL, host_recv_notice_place_leave_eom, hst); | 1774 | NULL, host_recv_notice_place_leave_eom, hst); |
1637 | hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer); | 1775 | hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer); |
1638 | 1776 | ||
1639 | req->header.size = htons (sizeof (*req)); | 1777 | uint16_t app_id_size = strlen (app->id) + 1; |
1640 | req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER); | 1778 | struct HostEnterRequest *hreq = GNUNET_malloc (sizeof (*hreq) + app_id_size); |
1641 | req->policy = policy; | 1779 | hreq->header.size = htons (sizeof (*hreq) + app_id_size); |
1642 | req->place_key = hst->place_key; | 1780 | hreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER); |
1643 | req->host_key = plc->ego_key; | 1781 | hreq->policy = policy; |
1782 | hreq->ego_pub_key = ego->pub_key; | ||
1783 | memcpy (&hreq[1], app->id, app_id_size); | ||
1644 | 1784 | ||
1645 | plc->connect_msg = (struct GNUNET_MessageHeader *) req; | 1785 | plc->connect_msg = &hreq->header; |
1646 | place_send_connect_msg (plc); | 1786 | place_send_connect_msg (plc); |
1647 | 1787 | ||
1648 | return hst; | 1788 | return hst; |
@@ -1650,22 +1790,15 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1650 | 1790 | ||
1651 | 1791 | ||
1652 | /** | 1792 | /** |
1653 | * Enter a place as host. | 1793 | * Reconnect to an already entered place as host. |
1654 | * | 1794 | * |
1655 | * A place is created upon first entering, and it is active until permanently | 1795 | * @param hconn |
1656 | * left using GNUNET_SOCIAL_host_leave(). | 1796 | * Host connection handle. |
1657 | * | 1797 | * @see GNUNET_SOCIAL_app_connect() & GNUNET_SOCIAL_AppHostPlaceCallback() |
1658 | * @param cfg | ||
1659 | * Configuration to contact the social service. | ||
1660 | * @param ego | ||
1661 | * Identity of the host. | ||
1662 | * @param gns_name | ||
1663 | * GNS name in the zone of the @a ego that contains the | ||
1664 | * public key of the place in a PLACE record. | ||
1665 | * @param policy | ||
1666 | * Policy specifying entry and history restrictions for the place. | ||
1667 | * @param slicer | 1798 | * @param slicer |
1668 | * Slicer to handle incoming messages. | 1799 | * Slicer to handle incoming messages. |
1800 | * @param enter_cb | ||
1801 | * Function called when the place is entered and ready to use. | ||
1669 | * @param answer_door_cb | 1802 | * @param answer_door_cb |
1670 | * Function to handle new nyms that want to enter. | 1803 | * Function to handle new nyms that want to enter. |
1671 | * @param farewell_cb | 1804 | * @param farewell_cb |
@@ -1676,26 +1809,54 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1676 | * @return Handle for the host. | 1809 | * @return Handle for the host. |
1677 | */ | 1810 | */ |
1678 | struct GNUNET_SOCIAL_Host * | 1811 | struct GNUNET_SOCIAL_Host * |
1679 | GNUNET_SOCIAL_host_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1812 | GNUNET_SOCIAL_host_enter_reconnect (struct GNUNET_SOCIAL_HostConnection *hconn, |
1680 | struct GNUNET_IDENTITY_Ego *ego, | 1813 | struct GNUNET_SOCIAL_Slicer *slicer, |
1681 | const char *gns_name, | 1814 | GNUNET_SOCIAL_HostEnterCallback enter_cb, |
1682 | enum GNUNET_PSYC_Policy policy, | 1815 | GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb, |
1683 | struct GNUNET_SOCIAL_Slicer *slicer, | 1816 | GNUNET_SOCIAL_FarewellCallback farewell_cb, |
1684 | GNUNET_SOCIAL_HostEnterCallback enter_cb, | 1817 | void *cls) |
1685 | GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb, | 1818 | { |
1686 | GNUNET_SOCIAL_FarewellCallback farewell_cb, | 1819 | struct GNUNET_SOCIAL_Host *hst = GNUNET_malloc (sizeof (*hst)); |
1687 | void *cls) | 1820 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; |
1688 | { | 1821 | |
1689 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key = {}; | 1822 | size_t app_id_size = strlen (hconn->app->id) + 1; |
1690 | 1823 | struct HostEnterRequest *hreq = GNUNET_malloc (sizeof (*hreq) + app_id_size); | |
1691 | /* FIXME: | 1824 | |
1692 | * 1. get public key by looking up PLACE entry under gns_name | 1825 | hst->enter_cb = enter_cb; |
1693 | * in the zone of the ego. | 1826 | hst->answer_door_cb = answer_door_cb; |
1694 | * 2. get private key from $GNUNET_DATA_HOME/social/places/PUB_KEY_HASH | 1827 | hst->farewell_cb = farewell_cb; |
1695 | */ | 1828 | hst->cb_cls = cls; |
1829 | |||
1830 | plc->cfg = hconn->app->cfg; | ||
1831 | plc->is_host = GNUNET_YES; | ||
1832 | plc->slicer = slicer; | ||
1833 | plc->pub_key = hconn->plc_msg.place_pub_key; | ||
1834 | plc->ego_pub_key = hconn->plc_msg.ego_pub_key; | ||
1835 | |||
1836 | plc->client = GNUNET_CLIENT_MANAGER_connect (plc->cfg, "social", host_handlers); | ||
1837 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); | ||
1838 | |||
1839 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
1840 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); | ||
1841 | |||
1842 | hst->slicer = GNUNET_SOCIAL_slicer_create (); | ||
1843 | GNUNET_SOCIAL_slicer_method_add (hst->slicer, "_notice_place_leave", | ||
1844 | host_recv_notice_place_leave_method, | ||
1845 | host_recv_notice_place_leave_modifier, | ||
1846 | NULL, host_recv_notice_place_leave_eom, hst); | ||
1847 | hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer); | ||
1848 | |||
1849 | hreq->header.size = htons (sizeof (*hreq) + app_id_size); | ||
1850 | hreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER); | ||
1851 | hreq->place_pub_key = hconn->plc_msg.place_pub_key; | ||
1852 | hreq->ego_pub_key = hconn->plc_msg.ego_pub_key; | ||
1853 | memcpy (&hreq[1], hconn->app->id, app_id_size); | ||
1696 | 1854 | ||
1697 | return GNUNET_SOCIAL_host_enter (cfg, ego, &place_key, policy, slicer, | 1855 | plc->connect_msg = &hreq->header; |
1698 | enter_cb, answer_door_cb, farewell_cb, cls); | 1856 | place_send_connect_msg (plc); |
1857 | |||
1858 | GNUNET_free (hconn); | ||
1859 | return hst; | ||
1699 | } | 1860 | } |
1700 | 1861 | ||
1701 | 1862 | ||
@@ -1759,12 +1920,16 @@ GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst, | |||
1759 | * Host of the place. | 1920 | * Host of the place. |
1760 | * @param nym | 1921 | * @param nym |
1761 | * Handle for the entity to be ejected. | 1922 | * Handle for the entity to be ejected. |
1923 | * @param env | ||
1924 | * Environment for the message or NULL. | ||
1762 | */ | 1925 | */ |
1763 | void | 1926 | void |
1764 | GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *hst, | 1927 | GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *hst, |
1765 | const struct GNUNET_SOCIAL_Nym *nym) | 1928 | const struct GNUNET_SOCIAL_Nym *nym, |
1929 | struct GNUNET_ENV_Environment *env) | ||
1766 | { | 1930 | { |
1767 | struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); | 1931 | if (NULL == env) |
1932 | env = GNUNET_ENV_environment_create (); | ||
1768 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET, | 1933 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET, |
1769 | "_nym", &nym->pub_key, sizeof (nym->pub_key)); | 1934 | "_nym", &nym->pub_key, sizeof (nym->pub_key)); |
1770 | GNUNET_SOCIAL_host_announce (hst, "_notice_place_leave", env, NULL, NULL, | 1935 | GNUNET_SOCIAL_host_announce (hst, "_notice_place_leave", env, NULL, NULL, |
@@ -1773,121 +1938,79 @@ GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *hst, | |||
1773 | 1938 | ||
1774 | 1939 | ||
1775 | /** | 1940 | /** |
1776 | * Get the public key of a @a nym. | 1941 | * Get the public key of @a ego. |
1777 | * | 1942 | * |
1778 | * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). | 1943 | * @param ego |
1779 | * | 1944 | * Ego. |
1780 | * @param nym | ||
1781 | * Pseudonym to map to a cryptographic identifier. | ||
1782 | * | 1945 | * |
1783 | * @return Public key of nym. | 1946 | * @return Public key of ego. |
1784 | */ | 1947 | */ |
1785 | const struct GNUNET_CRYPTO_EcdsaPublicKey * | 1948 | const struct GNUNET_CRYPTO_EcdsaPublicKey * |
1786 | GNUNET_SOCIAL_nym_get_key (const struct GNUNET_SOCIAL_Nym *nym) | 1949 | GNUNET_SOCIAL_ego_get_pub_key (const struct GNUNET_SOCIAL_Ego *ego) |
1787 | { | 1950 | { |
1788 | return &nym->pub_key; | 1951 | return &ego->pub_key; |
1789 | } | 1952 | } |
1790 | 1953 | ||
1791 | 1954 | ||
1792 | /** | 1955 | /** |
1793 | * Get the hash of the public key of a @a nym. | 1956 | * Get the hash of the public key of @a ego. |
1794 | * | 1957 | * |
1795 | * @param nym | 1958 | * @param ego |
1796 | * Pseudonym to map to a cryptographic identifier. | 1959 | * Ego. |
1797 | * | 1960 | * |
1798 | * @return Hash of the public key of nym. | 1961 | * @return Hash of the public key of @a ego. |
1799 | */ | 1962 | */ |
1800 | const struct GNUNET_HashCode * | 1963 | const struct GNUNET_HashCode * |
1801 | GNUNET_SOCIAL_nym_get_key_hash (const struct GNUNET_SOCIAL_Nym *nym) | 1964 | GNUNET_SOCIAL_ego_get_pub_key_hash (const struct GNUNET_SOCIAL_Ego *ego) |
1802 | { | 1965 | { |
1803 | return &nym->pub_key_hash; | 1966 | return &ego->pub_key_hash; |
1804 | } | 1967 | } |
1805 | 1968 | ||
1806 | 1969 | ||
1807 | /** | 1970 | /** |
1808 | * Obtain the private-public key pair of the hosted place. | 1971 | * Get the name of @a ego. |
1809 | * | ||
1810 | * The public part is suitable for storing in GNS within a PLACE record, | ||
1811 | * along with peer IDs to join at. | ||
1812 | * | 1972 | * |
1813 | * @param host | 1973 | * @param ego |
1814 | * Host of the place. | 1974 | * Ego. |
1815 | * | 1975 | * |
1816 | * @return Private-public key pair of the hosted place. | 1976 | * @return Public key of @a ego. |
1817 | */ | 1977 | */ |
1818 | const struct GNUNET_CRYPTO_EddsaPrivateKey * | 1978 | const char * |
1819 | GNUNET_SOCIAL_host_get_place_key (struct GNUNET_SOCIAL_Host *hst) | 1979 | GNUNET_SOCIAL_ego_get_name (const struct GNUNET_SOCIAL_Ego *ego) |
1820 | { | 1980 | { |
1821 | return &hst->place_key; | 1981 | return ego->name; |
1822 | } | 1982 | } |
1823 | 1983 | ||
1824 | 1984 | ||
1825 | /** | 1985 | /** |
1826 | * Connected to core service. | 1986 | * Get the public key of @a nym. |
1987 | * | ||
1988 | * Suitable, for example, to be used with GNUNET_SOCIAL_zone_add_nym(). | ||
1989 | * | ||
1990 | * @param nym | ||
1991 | * Pseudonym. | ||
1992 | * | ||
1993 | * @return Public key of @a nym. | ||
1827 | */ | 1994 | */ |
1828 | static void | 1995 | const struct GNUNET_CRYPTO_EcdsaPublicKey * |
1829 | core_connected_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity) | 1996 | GNUNET_SOCIAL_nym_get_pub_key (const struct GNUNET_SOCIAL_Nym *nym) |
1830 | { | 1997 | { |
1831 | this_peer = *my_identity; | 1998 | return &nym->pub_key; |
1832 | // FIXME | ||
1833 | } | 1999 | } |
1834 | 2000 | ||
1835 | 2001 | ||
1836 | /** | 2002 | /** |
1837 | * Advertise the place in the GNS zone of the @e ego of the @a host. | 2003 | * Get the hash of the public key of @a nym. |
1838 | * | 2004 | * |
1839 | * @param hst | 2005 | * @param nym |
1840 | * Host of the place. | 2006 | * Pseudonym. |
1841 | * @param name | 2007 | * |
1842 | * The name for the PLACE record to put in the zone. | 2008 | * @return Hash of the public key of @a nym. |
1843 | * @param peer_count | ||
1844 | * Number of elements in the @a peers array. | ||
1845 | * @param peers | ||
1846 | * List of peers to put in the PLACE record to advertise | ||
1847 | * as entry points to the place in addition to the origin. | ||
1848 | * @param expiration_time | ||
1849 | * Expiration time of the record, use 0 to remove the record. | ||
1850 | * @param password | ||
1851 | * Password used to encrypt the record or NULL to keep it cleartext. | ||
1852 | * @param result_cb | ||
1853 | * Function called with the result of the operation. | ||
1854 | * @param result_cls | ||
1855 | * Closure for @a result_cb | ||
1856 | */ | 2009 | */ |
1857 | void | 2010 | const struct GNUNET_HashCode * |
1858 | GNUNET_SOCIAL_host_advertise (struct GNUNET_SOCIAL_Host *hst, | 2011 | GNUNET_SOCIAL_nym_get_pub_key_hash (const struct GNUNET_SOCIAL_Nym *nym) |
1859 | const char *name, | ||
1860 | uint32_t peer_count, | ||
1861 | const struct GNUNET_PeerIdentity *peers, | ||
1862 | struct GNUNET_TIME_Absolute expiration_time, | ||
1863 | const char *password, | ||
1864 | GNUNET_NAMESTORE_ContinuationWithStatus result_cb, | ||
1865 | void *result_cls) | ||
1866 | { | 2012 | { |
1867 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | 2013 | return &nym->pub_key_hash; |
1868 | if (NULL == namestore) | ||
1869 | namestore = GNUNET_NAMESTORE_connect (plc->cfg); | ||
1870 | if (NULL == core) | ||
1871 | core = GNUNET_CORE_connect (plc->cfg, NULL, core_connected_cb, NULL, NULL, | ||
1872 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); | ||
1873 | |||
1874 | struct GNUNET_GNSRECORD_Data rd = { }; | ||
1875 | rd.record_type = GNUNET_GNSRECORD_TYPE_PLACE; | ||
1876 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1877 | rd.expiration_time = expiration_time.abs_value_us; | ||
1878 | |||
1879 | struct GNUNET_GNSRECORD_PlaceData * | ||
1880 | rec = GNUNET_malloc (sizeof (*rec) + peer_count * sizeof (*peers)); | ||
1881 | rec->place_key = plc->pub_key; | ||
1882 | rec->origin = this_peer; | ||
1883 | rec->relay_count = htonl (peer_count); | ||
1884 | memcpy (&rec[1], peers, peer_count * sizeof (*peers)); | ||
1885 | |||
1886 | rd.data = rec; | ||
1887 | rd.data_size = sizeof (*rec) + peer_count * sizeof (*peers); | ||
1888 | |||
1889 | GNUNET_NAMESTORE_records_store (namestore, &hst->plc.ego_key, | ||
1890 | name, 1, &rd, result_cb, result_cls); | ||
1891 | } | 2014 | } |
1892 | 2015 | ||
1893 | 2016 | ||
@@ -1966,65 +2089,117 @@ GNUNET_SOCIAL_host_get_place (struct GNUNET_SOCIAL_Host *hst) | |||
1966 | } | 2089 | } |
1967 | 2090 | ||
1968 | 2091 | ||
2092 | |||
2093 | void | ||
2094 | place_leave (struct GNUNET_SOCIAL_Place *plc) | ||
2095 | { | ||
2096 | struct GNUNET_MessageHeader msg; | ||
2097 | msg.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE); | ||
2098 | msg.size = htons (sizeof (msg)); | ||
2099 | GNUNET_CLIENT_MANAGER_transmit (plc->client, &msg); | ||
2100 | } | ||
2101 | |||
2102 | |||
2103 | void | ||
2104 | place_disconnect (struct GNUNET_SOCIAL_Place *plc, | ||
2105 | GNUNET_ContinuationCallback disconnect_cb, | ||
2106 | void *disconnect_cls) | ||
2107 | { | ||
2108 | plc->is_disconnecting = GNUNET_YES; | ||
2109 | plc->disconnect_cb = disconnect_cb; | ||
2110 | plc->disconnect_cls = disconnect_cls; | ||
2111 | |||
2112 | GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, | ||
2113 | GNUNET_YES == plc->is_host | ||
2114 | ? host_cleanup : guest_cleanup, | ||
2115 | plc); | ||
2116 | } | ||
2117 | |||
2118 | |||
1969 | /** | 2119 | /** |
1970 | * Stop hosting a place. | 2120 | * Disconnect from a home. |
1971 | * | 2121 | * |
1972 | * Invalidates host handle. | 2122 | * Invalidates host handle. |
1973 | * | 2123 | * |
1974 | * @param host Host leaving the place. | 2124 | * @param hst |
1975 | * @param keep_active Keep the place active after last host disconnected. | 2125 | * The host to disconnect. |
1976 | */ | 2126 | */ |
1977 | void | 2127 | void |
1978 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst, | 2128 | GNUNET_SOCIAL_host_disconnect (struct GNUNET_SOCIAL_Host *hst, |
1979 | int keep_active, | 2129 | GNUNET_ContinuationCallback disconnect_cb, |
1980 | GNUNET_ContinuationCallback leave_cb, | 2130 | void *cls) |
1981 | void *leave_cls) | ||
1982 | { | 2131 | { |
1983 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | 2132 | place_disconnect (&hst->plc, disconnect_cb, cls); |
2133 | } | ||
1984 | 2134 | ||
1985 | /* FIXME: send msg to service */ | ||
1986 | 2135 | ||
1987 | plc->is_disconnecting = GNUNET_YES; | 2136 | /** |
1988 | plc->disconnect_cb = leave_cb; | 2137 | * Stop hosting the home. |
1989 | plc->disconnect_cls = leave_cls; | 2138 | * |
1990 | 2139 | * Sends a _notice_place_closed announcement to the home. | |
1991 | GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, | 2140 | * Invalidates host handle. |
1992 | &host_cleanup, hst); | 2141 | * |
2142 | * @param hst | ||
2143 | * The host leaving. | ||
2144 | * @param env | ||
2145 | * Environment for the message or NULL. | ||
2146 | * _nym is set to @e nym regardless whether an @e env is provided. | ||
2147 | * @param disconnect_cb | ||
2148 | * Function called after the host left the place | ||
2149 | * and disconnected from the social service. | ||
2150 | * @param cls | ||
2151 | * Closure for @a disconnect_cb. | ||
2152 | */ | ||
2153 | void | ||
2154 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst, | ||
2155 | const struct GNUNET_ENV_Environment *env, | ||
2156 | GNUNET_ContinuationCallback disconnect_cb, | ||
2157 | void *cls) | ||
2158 | { | ||
2159 | GNUNET_SOCIAL_host_announce (hst, "_notice_place_closed", env, NULL, NULL, | ||
2160 | GNUNET_SOCIAL_ANNOUNCE_NONE); | ||
2161 | place_leave (&hst->plc); | ||
2162 | GNUNET_SOCIAL_host_disconnect (hst, disconnect_cb, cls); | ||
1993 | } | 2163 | } |
1994 | 2164 | ||
1995 | 2165 | ||
1996 | /*** GUEST ***/ | 2166 | /*** GUEST ***/ |
1997 | 2167 | ||
1998 | static struct GuestEnterRequest * | 2168 | static struct GuestEnterRequest * |
1999 | guest_enter_request_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key, | 2169 | guest_enter_request_create (const char *app_id, |
2000 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, | 2170 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key, |
2171 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key, | ||
2001 | const struct GNUNET_PeerIdentity *origin, | 2172 | const struct GNUNET_PeerIdentity *origin, |
2002 | size_t relay_count, | 2173 | size_t relay_count, |
2003 | const struct GNUNET_PeerIdentity *relays, | 2174 | const struct GNUNET_PeerIdentity *relays, |
2004 | const struct GNUNET_PSYC_Message *join_msg) | 2175 | const struct GNUNET_PSYC_Message *join_msg) |
2005 | { | 2176 | { |
2177 | uint16_t app_id_size = strlen (app_id) + 1; | ||
2006 | uint16_t join_msg_size = ntohs (join_msg->header.size); | 2178 | uint16_t join_msg_size = ntohs (join_msg->header.size); |
2007 | uint16_t relay_size = relay_count * sizeof (*relays); | 2179 | uint16_t relay_size = relay_count * sizeof (*relays); |
2008 | 2180 | ||
2009 | struct GuestEnterRequest * | 2181 | struct GuestEnterRequest * |
2010 | req = GNUNET_malloc (sizeof (*req) + relay_size + join_msg_size); | 2182 | greq = GNUNET_malloc (sizeof (*greq) + app_id_size + relay_size + join_msg_size); |
2183 | |||
2184 | greq->header.size = htons (sizeof (*greq) + app_id_size + relay_size + join_msg_size); | ||
2185 | greq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER); | ||
2186 | greq->place_pub_key = *place_pub_key; | ||
2187 | greq->ego_pub_key = *ego_pub_key; | ||
2188 | greq->origin = *origin; | ||
2189 | greq->relay_count = htonl (relay_count); | ||
2011 | 2190 | ||
2012 | req->header.size = htons (sizeof (*req) + relay_size + join_msg_size); | 2191 | char *p = (char *) &greq[1]; |
2013 | req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER); | 2192 | memcpy (p, app_id, app_id_size); |
2014 | req->place_key = *place_key; | 2193 | p += app_id_size; |
2015 | req->guest_key = *guest_key; | ||
2016 | req->origin = *origin; | ||
2017 | req->relay_count = htonl (relay_count); | ||
2018 | 2194 | ||
2019 | uint16_t p = sizeof (*req); | ||
2020 | if (0 < relay_size) | 2195 | if (0 < relay_size) |
2021 | { | 2196 | { |
2022 | memcpy ((char *) req + p, relays, relay_size); | 2197 | memcpy (p, relays, relay_size); |
2023 | p += relay_size; | 2198 | p += relay_size; |
2024 | } | 2199 | } |
2025 | 2200 | ||
2026 | memcpy ((char *) req + p, join_msg, join_msg_size); | 2201 | memcpy (p, join_msg, join_msg_size); |
2027 | return req; | 2202 | return greq; |
2028 | } | 2203 | } |
2029 | 2204 | ||
2030 | /** | 2205 | /** |
@@ -2045,13 +2220,13 @@ guest_enter_request_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_ke | |||
2045 | * @return NULL on errors, otherwise handle for the guest. | 2220 | * @return NULL on errors, otherwise handle for the guest. |
2046 | */ | 2221 | */ |
2047 | struct GNUNET_SOCIAL_Guest * | 2222 | struct GNUNET_SOCIAL_Guest * |
2048 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 2223 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_SOCIAL_App *app, |
2049 | const struct GNUNET_IDENTITY_Ego *ego, | 2224 | const struct GNUNET_SOCIAL_Ego *ego, |
2050 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, | 2225 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key, |
2051 | const struct GNUNET_PeerIdentity *origin, | 2226 | const struct GNUNET_PeerIdentity *origin, |
2052 | uint32_t relay_count, | 2227 | uint32_t relay_count, |
2053 | const struct GNUNET_PeerIdentity *relays, | 2228 | const struct GNUNET_PeerIdentity *relays, |
2054 | const struct GNUNET_PSYC_Message *join_msg, | 2229 | const struct GNUNET_PSYC_Message *entry_msg, |
2055 | struct GNUNET_SOCIAL_Slicer *slicer, | 2230 | struct GNUNET_SOCIAL_Slicer *slicer, |
2056 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | 2231 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, |
2057 | GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb, | 2232 | GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb, |
@@ -2060,9 +2235,9 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
2060 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); | 2235 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); |
2061 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | 2236 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; |
2062 | 2237 | ||
2063 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | 2238 | plc->ego_pub_key = ego->pub_key; |
2064 | plc->pub_key = *place_key; | 2239 | plc->pub_key = *place_pub_key; |
2065 | plc->cfg = cfg; | 2240 | plc->cfg = app->cfg; |
2066 | plc->is_host = GNUNET_YES; | 2241 | plc->is_host = GNUNET_YES; |
2067 | plc->slicer = slicer; | 2242 | plc->slicer = slicer; |
2068 | 2243 | ||
@@ -2070,86 +2245,22 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
2070 | gst->entry_dcsn_cb = entry_dcsn_cb; | 2245 | gst->entry_dcsn_cb = entry_dcsn_cb; |
2071 | gst->cb_cls = cls; | 2246 | gst->cb_cls = cls; |
2072 | 2247 | ||
2073 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", guest_handlers); | 2248 | plc->client = GNUNET_CLIENT_MANAGER_connect (plc->cfg, "social", guest_handlers); |
2074 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); | 2249 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); |
2075 | 2250 | ||
2076 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | 2251 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); |
2077 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); | 2252 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); |
2078 | 2253 | ||
2079 | struct GuestEnterRequest * | 2254 | struct GuestEnterRequest * |
2080 | req = guest_enter_request_create (&plc->ego_key, place_key, origin, | 2255 | greq = guest_enter_request_create (app->id, &ego->pub_key, &plc->pub_key, |
2081 | relay_count, relays, join_msg); | 2256 | origin, relay_count, relays, entry_msg); |
2082 | plc->connect_msg = &req->header; | 2257 | plc->connect_msg = &greq->header; |
2083 | place_send_connect_msg (plc); | 2258 | place_send_connect_msg (plc); |
2084 | return gst; | 2259 | return gst; |
2085 | } | 2260 | } |
2086 | 2261 | ||
2087 | 2262 | ||
2088 | /** | 2263 | /** |
2089 | * Result of a GNS name lookup for entering a place. | ||
2090 | * | ||
2091 | * @see GNUNET_SOCIAL_guest_enter_by_name | ||
2092 | */ | ||
2093 | static void | ||
2094 | gns_result_guest_enter (void *cls, uint32_t rd_count, | ||
2095 | const struct GNUNET_GNSRECORD_Data *rd) | ||
2096 | { | ||
2097 | struct GNUNET_SOCIAL_Guest *gst = cls; | ||
2098 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
2099 | |||
2100 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2101 | "%p GNS result: %u records.\n", gst, rd_count); | ||
2102 | |||
2103 | const struct GNUNET_GNSRECORD_PlaceData * | ||
2104 | rec = (const struct GNUNET_GNSRECORD_PlaceData *) rd->data; | ||
2105 | |||
2106 | if (0 == rd_count) | ||
2107 | { | ||
2108 | if (NULL != gst->enter_cb) | ||
2109 | gst->enter_cb (gst->cb_cls, GNUNET_SYSERR, 0); | ||
2110 | return; | ||
2111 | } | ||
2112 | |||
2113 | if (rd->data_size < sizeof (*rec)) | ||
2114 | { | ||
2115 | GNUNET_break_op (0); | ||
2116 | if (NULL != gst->enter_cb) | ||
2117 | gst->enter_cb (gst->cb_cls, GNUNET_SYSERR, 0); | ||
2118 | return; | ||
2119 | } | ||
2120 | |||
2121 | uint16_t relay_count = ntohl (rec->relay_count); | ||
2122 | struct GNUNET_PeerIdentity *relays = NULL; | ||
2123 | |||
2124 | if (0 < relay_count) | ||
2125 | { | ||
2126 | if (rd->data_size == sizeof (*rec) + relay_count * sizeof (struct GNUNET_PeerIdentity)) | ||
2127 | { | ||
2128 | relays = (struct GNUNET_PeerIdentity *) &rec[1]; | ||
2129 | } | ||
2130 | else | ||
2131 | { | ||
2132 | relay_count = 0; | ||
2133 | GNUNET_break_op (0); | ||
2134 | } | ||
2135 | } | ||
2136 | |||
2137 | struct GuestEnterRequest * | ||
2138 | req = guest_enter_request_create (&plc->ego_key, &rec->place_key, | ||
2139 | &rec->origin, relay_count, relays, | ||
2140 | (struct GNUNET_PSYC_Message *) plc->connect_msg); | ||
2141 | GNUNET_free (plc->connect_msg); | ||
2142 | plc->connect_msg = &req->header; | ||
2143 | plc->pub_key = req->place_key; | ||
2144 | |||
2145 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
2146 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); | ||
2147 | |||
2148 | place_send_connect_msg (plc); | ||
2149 | } | ||
2150 | |||
2151 | |||
2152 | /** | ||
2153 | * Request entry to a place by name as a guest. | 2264 | * Request entry to a place by name as a guest. |
2154 | * | 2265 | * |
2155 | * @param cfg | 2266 | * @param cfg |
@@ -2165,7 +2276,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count, | |||
2165 | * @param password | 2276 | * @param password |
2166 | * Password to decrypt the record, or NULL for cleartext records. | 2277 | * Password to decrypt the record, or NULL for cleartext records. |
2167 | * @param join_msg | 2278 | * @param join_msg |
2168 | * Entry request message. | 2279 | * Entry request message or NULL. |
2169 | * @param slicer | 2280 | * @param slicer |
2170 | * Slicer to use for processing incoming requests from guests. | 2281 | * Slicer to use for processing incoming requests from guests. |
2171 | * @param local_enter_cb | 2282 | * @param local_enter_cb |
@@ -2176,9 +2287,10 @@ gns_result_guest_enter (void *cls, uint32_t rd_count, | |||
2176 | * @return NULL on errors, otherwise handle for the guest. | 2287 | * @return NULL on errors, otherwise handle for the guest. |
2177 | */ | 2288 | */ |
2178 | struct GNUNET_SOCIAL_Guest * | 2289 | struct GNUNET_SOCIAL_Guest * |
2179 | GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, | 2290 | GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_SOCIAL_App *app, |
2180 | const struct GNUNET_IDENTITY_Ego *ego, | 2291 | const struct GNUNET_SOCIAL_Ego *ego, |
2181 | const char *gns_name, const char *password, | 2292 | const char *gns_name, |
2293 | const char *password, | ||
2182 | const struct GNUNET_PSYC_Message *join_msg, | 2294 | const struct GNUNET_PSYC_Message *join_msg, |
2183 | struct GNUNET_SOCIAL_Slicer *slicer, | 2295 | struct GNUNET_SOCIAL_Slicer *slicer, |
2184 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | 2296 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, |
@@ -2188,32 +2300,109 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg | |||
2188 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); | 2300 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); |
2189 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | 2301 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; |
2190 | 2302 | ||
2191 | GNUNET_assert (NULL != join_msg); | 2303 | if (NULL == password) |
2304 | password = ""; | ||
2305 | |||
2306 | uint16_t app_id_size = strlen (app->id) + 1; | ||
2307 | uint16_t gns_name_size = strlen (gns_name) + 1; | ||
2308 | uint16_t password_size = strlen (password) + 1; | ||
2309 | |||
2310 | uint16_t join_msg_size = 0; | ||
2311 | if (NULL != join_msg); | ||
2312 | join_msg_size = ntohs (join_msg->header.size); | ||
2313 | |||
2314 | uint16_t greq_size = sizeof (struct GuestEnterByNameRequest) | ||
2315 | + app_id_size + gns_name_size + password_size + join_msg_size; | ||
2316 | struct GuestEnterByNameRequest *greq = GNUNET_malloc (greq_size); | ||
2317 | greq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME); | ||
2318 | greq->header.size = htons (greq_size); | ||
2319 | greq->ego_pub_key = ego->pub_key; | ||
2320 | |||
2321 | char *p = (char *) &greq[1]; | ||
2322 | memcpy (p, app->id, app_id_size); | ||
2323 | p += app_id_size; | ||
2324 | memcpy (p, gns_name, gns_name_size); | ||
2325 | p += gns_name_size; | ||
2326 | memcpy (p, password, password_size); | ||
2327 | p += password_size; | ||
2328 | if (NULL != join_msg) | ||
2329 | memcpy (p, join_msg, join_msg_size); | ||
2192 | 2330 | ||
2193 | gst->enter_cb = local_enter_cb; | 2331 | gst->enter_cb = local_enter_cb; |
2194 | gst->entry_dcsn_cb = entry_decision_cb; | 2332 | gst->entry_dcsn_cb = entry_decision_cb; |
2195 | gst->cb_cls = cls; | 2333 | gst->cb_cls = cls; |
2196 | 2334 | ||
2197 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | 2335 | plc->ego_pub_key = ego->pub_key; |
2198 | plc->cfg = cfg; | 2336 | plc->cfg = app->cfg; |
2199 | plc->is_host = GNUNET_NO; | 2337 | plc->is_host = GNUNET_NO; |
2200 | plc->slicer = slicer; | 2338 | plc->slicer = slicer; |
2201 | 2339 | ||
2202 | uint16_t join_msg_size = ntohs (join_msg->header.size); | 2340 | plc->client = GNUNET_CLIENT_MANAGER_connect (app->cfg, "social", guest_handlers); |
2203 | plc->connect_msg = GNUNET_malloc (join_msg_size); | 2341 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); |
2204 | memcpy (plc->connect_msg, join_msg, join_msg_size); | 2342 | |
2343 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
2344 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); | ||
2345 | |||
2346 | plc->connect_msg = &greq->header; | ||
2347 | place_send_connect_msg (plc); | ||
2348 | |||
2349 | return gst; | ||
2350 | } | ||
2205 | 2351 | ||
2206 | if (NULL == gns) | ||
2207 | gns = GNUNET_GNS_connect (cfg); | ||
2208 | 2352 | ||
2209 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", guest_handlers); | 2353 | /** |
2354 | * Reconnect to an already entered place as guest. | ||
2355 | * | ||
2356 | * @param gconn | ||
2357 | * Guest connection handle. | ||
2358 | * @see GNUNET_SOCIAL_app_connect() & GNUNET_SOCIAL_AppGuestPlaceCallback() | ||
2359 | * @param slicer | ||
2360 | * Slicer to use for processing incoming requests from guests. | ||
2361 | * @param local_enter_cb | ||
2362 | * Called upon connection established to the social service. | ||
2363 | * @param entry_decision_cb | ||
2364 | * Called upon receiving entry decision. | ||
2365 | * | ||
2366 | * @return NULL on errors, otherwise handle for the guest. | ||
2367 | */ | ||
2368 | struct GNUNET_SOCIAL_Guest * | ||
2369 | GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn, | ||
2370 | struct GNUNET_SOCIAL_Slicer *slicer, | ||
2371 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | ||
2372 | void *cls) | ||
2373 | { | ||
2374 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); | ||
2375 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
2376 | |||
2377 | uint16_t app_id_size = strlen (gconn->app->id) + 1; | ||
2378 | uint16_t greq_size = sizeof (struct GuestEnterRequest) + app_id_size; | ||
2379 | struct GuestEnterRequest *greq = GNUNET_malloc (greq_size); | ||
2380 | greq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER); | ||
2381 | greq->header.size = htons (greq_size); | ||
2382 | greq->ego_pub_key = gconn->plc_msg.ego_pub_key; | ||
2383 | greq->place_pub_key = gconn->plc_msg.place_pub_key; | ||
2384 | |||
2385 | memcpy (&greq[1], gconn->app->id, app_id_size); | ||
2386 | |||
2387 | gst->enter_cb = local_enter_cb; | ||
2388 | gst->cb_cls = cls; | ||
2389 | |||
2390 | plc->cfg = gconn->app->cfg; | ||
2391 | plc->is_host = GNUNET_NO; | ||
2392 | plc->slicer = slicer; | ||
2393 | plc->pub_key = gconn->plc_msg.place_pub_key; | ||
2394 | plc->ego_pub_key = gconn->plc_msg.ego_pub_key; | ||
2395 | |||
2396 | plc->client = GNUNET_CLIENT_MANAGER_connect (plc->cfg, "social", guest_handlers); | ||
2210 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); | 2397 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); |
2211 | 2398 | ||
2212 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | 2399 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); |
2213 | GNUNET_IDENTITY_ego_get_public_key (ego, &ego_pub_key); | 2400 | plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer); |
2214 | GNUNET_GNS_lookup (gns, gns_name, &ego_pub_key, | 2401 | |
2215 | GNUNET_GNSRECORD_TYPE_PLACE, GNUNET_GNS_LO_DEFAULT, | 2402 | plc->connect_msg = &greq->header; |
2216 | NULL, gns_result_guest_enter, gst); | 2403 | place_send_connect_msg (plc); |
2404 | |||
2405 | GNUNET_free (gconn); | ||
2217 | return gst; | 2406 | return gst; |
2218 | } | 2407 | } |
2219 | 2408 | ||
@@ -2284,6 +2473,23 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) | |||
2284 | 2473 | ||
2285 | 2474 | ||
2286 | /** | 2475 | /** |
2476 | * Disconnect from a place. | ||
2477 | * | ||
2478 | * Invalidates guest handle. | ||
2479 | * | ||
2480 | * @param gst | ||
2481 | * The guest to disconnect. | ||
2482 | */ | ||
2483 | void | ||
2484 | GNUNET_SOCIAL_guest_disconnect (struct GNUNET_SOCIAL_Guest *gst, | ||
2485 | GNUNET_ContinuationCallback disconnect_cb, | ||
2486 | void *cls) | ||
2487 | { | ||
2488 | place_disconnect (&gst->plc, disconnect_cb, cls); | ||
2489 | } | ||
2490 | |||
2491 | |||
2492 | /** | ||
2287 | * Leave a place temporarily or permanently. | 2493 | * Leave a place temporarily or permanently. |
2288 | * | 2494 | * |
2289 | * Notifies the owner of the place about leaving, and destroys the place handle. | 2495 | * Notifies the owner of the place about leaving, and destroys the place handle. |
@@ -2301,28 +2507,14 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) | |||
2301 | */ | 2507 | */ |
2302 | void | 2508 | void |
2303 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst, | 2509 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst, |
2304 | int keep_active, | ||
2305 | struct GNUNET_ENV_Environment *env, | 2510 | struct GNUNET_ENV_Environment *env, |
2306 | GNUNET_ContinuationCallback leave_cb, | 2511 | GNUNET_ContinuationCallback disconnect_cb, |
2307 | void *leave_cls) | 2512 | void *cls) |
2308 | { | 2513 | { |
2309 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | 2514 | GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL, |
2310 | 2515 | GNUNET_SOCIAL_TALK_NONE); | |
2311 | plc->is_disconnecting = GNUNET_YES; | 2516 | place_leave (&gst->plc); |
2312 | plc->disconnect_cb = leave_cb; | 2517 | GNUNET_SOCIAL_guest_disconnect (gst, disconnect_cb, cls); |
2313 | plc->disconnect_cls = leave_cls; | ||
2314 | |||
2315 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2316 | "Guest: leaving place.\n"); | ||
2317 | |||
2318 | if (GNUNET_NO == keep_active && NULL != plc->tmit) | ||
2319 | { | ||
2320 | GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL, | ||
2321 | GNUNET_SOCIAL_TALK_NONE); | ||
2322 | } | ||
2323 | |||
2324 | GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, | ||
2325 | &guest_cleanup, gst); | ||
2326 | } | 2518 | } |
2327 | 2519 | ||
2328 | 2520 | ||
@@ -2342,6 +2534,21 @@ GNUNET_SOCIAL_guest_get_place (struct GNUNET_SOCIAL_Guest *gst) | |||
2342 | } | 2534 | } |
2343 | 2535 | ||
2344 | 2536 | ||
2537 | /** | ||
2538 | * Obtain the public key of a place. | ||
2539 | * | ||
2540 | * @param plc | ||
2541 | * Place. | ||
2542 | * | ||
2543 | * @return Public key of the place. | ||
2544 | */ | ||
2545 | const struct GNUNET_CRYPTO_EddsaPublicKey * | ||
2546 | GNUNET_SOCIAL_place_get_key (struct GNUNET_SOCIAL_Place *plc) | ||
2547 | { | ||
2548 | return &plc->pub_key; | ||
2549 | } | ||
2550 | |||
2551 | |||
2345 | static struct GNUNET_SOCIAL_HistoryRequest * | 2552 | static struct GNUNET_SOCIAL_HistoryRequest * |
2346 | place_history_replay (struct GNUNET_SOCIAL_Place *plc, | 2553 | place_history_replay (struct GNUNET_SOCIAL_Place *plc, |
2347 | uint64_t start_message_id, | 2554 | uint64_t start_message_id, |
@@ -2571,8 +2778,119 @@ GNUNET_SOCIAL_place_look_cancel (struct GNUNET_SOCIAL_LookHandle *look) | |||
2571 | } | 2778 | } |
2572 | 2779 | ||
2573 | 2780 | ||
2781 | static void | ||
2782 | op_recv_zone_add_place_result (void *cls, int64_t result, | ||
2783 | const void *err_msg, uint16_t err_msg_size) | ||
2784 | { | ||
2785 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2786 | "Received zone add place result: %" PRId64 ".\n", result); | ||
2787 | |||
2788 | struct ZoneAddPlaceHandle *add_plc = cls; | ||
2789 | if (NULL != add_plc->result_cb) | ||
2790 | add_plc->result_cb (add_plc->result_cls, result, err_msg, err_msg_size); | ||
2791 | |||
2792 | GNUNET_free (add_plc->req); | ||
2793 | GNUNET_free (add_plc); | ||
2794 | } | ||
2795 | |||
2796 | |||
2574 | /** | 2797 | /** |
2575 | * Add public key to the GNS zone of the @e ego. | 2798 | * Advertise @e place in the GNS zone of @e ego. |
2799 | * | ||
2800 | * @param app | ||
2801 | * Application handle. | ||
2802 | * @param ego | ||
2803 | * Ego. | ||
2804 | * @param place_pub_key | ||
2805 | * Public key of place to add. | ||
2806 | * @param name | ||
2807 | * The name for the PLACE record to put in the zone. | ||
2808 | * @param password | ||
2809 | * Password used to encrypt the record or NULL to keep it cleartext. | ||
2810 | * @param relay_count | ||
2811 | * Number of elements in the @a relays array. | ||
2812 | * @param relays | ||
2813 | * List of relays to put in the PLACE record to advertise | ||
2814 | * as entry points to the place in addition to the origin. | ||
2815 | * @param expiration_time | ||
2816 | * Expiration time of the record, use 0 to remove the record. | ||
2817 | * @param result_cb | ||
2818 | * Function called with the result of the operation. | ||
2819 | * @param result_cls | ||
2820 | * Closure for @a result_cb | ||
2821 | * | ||
2822 | * @return #GNUNET_OK if the request was sent, | ||
2823 | * #GNUNET_SYSERR on error, e.g. the name/password is too long. | ||
2824 | */ | ||
2825 | int | ||
2826 | GNUNET_SOCIAL_zone_add_place (const struct GNUNET_SOCIAL_App *app, | ||
2827 | const struct GNUNET_SOCIAL_Ego *ego, | ||
2828 | const char *name, | ||
2829 | const char *password, | ||
2830 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key, | ||
2831 | const struct GNUNET_PeerIdentity *origin, | ||
2832 | uint32_t relay_count, | ||
2833 | const struct GNUNET_PeerIdentity *relays, | ||
2834 | struct GNUNET_TIME_Absolute expiration_time, | ||
2835 | GNUNET_ResultCallback result_cb, | ||
2836 | void *result_cls) | ||
2837 | { | ||
2838 | struct ZoneAddPlaceRequest *preq; | ||
2839 | size_t name_size = strlen (name) + 1; | ||
2840 | size_t password_size = strlen (password) + 1; | ||
2841 | size_t relay_size = relay_count * sizeof (*relays); | ||
2842 | size_t preq_size = sizeof (*preq) + name_size + password_size + relay_size; | ||
2843 | |||
2844 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE < preq_size) | ||
2845 | return GNUNET_SYSERR; | ||
2846 | |||
2847 | preq = GNUNET_malloc (preq_size); | ||
2848 | preq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE); | ||
2849 | preq->header.size = htons (preq_size); | ||
2850 | preq->expiration_time = GNUNET_htonll (expiration_time.abs_value_us); | ||
2851 | preq->ego_pub_key = ego->pub_key; | ||
2852 | preq->place_pub_key = *place_pub_key; | ||
2853 | preq->origin = *origin; | ||
2854 | preq->relay_count = htonl (relay_count); | ||
2855 | |||
2856 | char *p = (char *) &preq[1]; | ||
2857 | memcpy (p, name, name_size); | ||
2858 | p += name_size; | ||
2859 | memcpy (p, password, password_size); | ||
2860 | p += password_size; | ||
2861 | memcpy (p, relays, relay_size); | ||
2862 | |||
2863 | struct ZoneAddPlaceHandle * add_plc = GNUNET_malloc (sizeof (*add_plc)); | ||
2864 | add_plc->req = preq; | ||
2865 | add_plc->result_cb = result_cb; | ||
2866 | add_plc->result_cls = result_cls; | ||
2867 | |||
2868 | preq->op_id = GNUNET_htonll (GNUNET_CLIENT_MANAGER_op_add (app->client, | ||
2869 | op_recv_zone_add_place_result, | ||
2870 | add_plc)); | ||
2871 | GNUNET_CLIENT_MANAGER_transmit_now (app->client, &preq->header); | ||
2872 | return GNUNET_OK; | ||
2873 | } | ||
2874 | |||
2875 | |||
2876 | static void | ||
2877 | op_recv_zone_add_nym_result (void *cls, int64_t result, | ||
2878 | const void *err_msg, uint16_t err_msg_size) | ||
2879 | { | ||
2880 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2881 | "Received zone add nym result: %" PRId64 ".\n", result); | ||
2882 | |||
2883 | struct ZoneAddNymHandle *add_nym = cls; | ||
2884 | if (NULL != add_nym->result_cb) | ||
2885 | add_nym->result_cb (add_nym->result_cls, result, err_msg, err_msg_size); | ||
2886 | |||
2887 | GNUNET_free (add_nym->req); | ||
2888 | GNUNET_free (add_nym); | ||
2889 | } | ||
2890 | |||
2891 | |||
2892 | /** | ||
2893 | * Add nym to the GNS zone of @e ego. | ||
2576 | * | 2894 | * |
2577 | * @param cfg | 2895 | * @param cfg |
2578 | * Configuration. | 2896 | * Configuration. |
@@ -2588,43 +2906,57 @@ GNUNET_SOCIAL_place_look_cancel (struct GNUNET_SOCIAL_LookHandle *look) | |||
2588 | * Function called with the result of the operation. | 2906 | * Function called with the result of the operation. |
2589 | * @param result_cls | 2907 | * @param result_cls |
2590 | * Closure for @a result_cb | 2908 | * Closure for @a result_cb |
2909 | * | ||
2910 | * @return #GNUNET_OK if the request was sent, | ||
2911 | * #GNUNET_SYSERR on error, e.g. the name is too long. | ||
2591 | */ | 2912 | */ |
2592 | void | 2913 | int |
2593 | GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg, | 2914 | GNUNET_SOCIAL_zone_add_nym (const struct GNUNET_SOCIAL_App *app, |
2594 | const struct GNUNET_IDENTITY_Ego *ego, | 2915 | const struct GNUNET_SOCIAL_Ego *ego, |
2595 | const char *name, | 2916 | const char *name, |
2596 | const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key, | 2917 | const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key, |
2597 | struct GNUNET_TIME_Absolute expiration_time, | 2918 | struct GNUNET_TIME_Absolute expiration_time, |
2598 | GNUNET_NAMESTORE_ContinuationWithStatus result_cb, | 2919 | GNUNET_ResultCallback result_cb, |
2599 | void *result_cls) | 2920 | void *result_cls) |
2600 | { | 2921 | { |
2601 | if (NULL == namestore) | 2922 | struct ZoneAddNymRequest *nreq; |
2602 | namestore = GNUNET_NAMESTORE_connect (cfg); | 2923 | |
2603 | 2924 | size_t name_size = strlen (name) + 1; | |
2604 | struct GNUNET_GNSRECORD_Data rd = { }; | 2925 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (*nreq) + name_size) |
2605 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | 2926 | return GNUNET_SYSERR; |
2606 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
2607 | rd.expiration_time = expiration_time.abs_value_us; | ||
2608 | rd.data = nym_pub_key; | ||
2609 | rd.data_size = sizeof (*nym_pub_key); | ||
2610 | 2927 | ||
2611 | GNUNET_NAMESTORE_records_store (namestore, | 2928 | nreq = GNUNET_malloc (sizeof (*nreq) + name_size); |
2612 | GNUNET_IDENTITY_ego_get_private_key (ego), | 2929 | nreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM); |
2613 | name, 1, &rd, result_cb, result_cls); | 2930 | nreq->header.size = htons (sizeof (*nreq) + name_size); |
2931 | nreq->expiration_time = GNUNET_htonll (expiration_time.abs_value_us); | ||
2932 | nreq->ego_pub_key = ego->pub_key; | ||
2933 | nreq->nym_pub_key = *nym_pub_key; | ||
2934 | memcpy (&nreq[1], name, name_size); | ||
2935 | |||
2936 | struct ZoneAddNymHandle * add_nym = GNUNET_malloc (sizeof (*add_nym)); | ||
2937 | add_nym->req = nreq; | ||
2938 | add_nym->result_cb = result_cb; | ||
2939 | add_nym->result_cls = result_cls; | ||
2940 | |||
2941 | nreq->op_id = GNUNET_htonll (GNUNET_CLIENT_MANAGER_op_add (app->client, | ||
2942 | op_recv_zone_add_nym_result, | ||
2943 | add_nym)); | ||
2944 | GNUNET_CLIENT_MANAGER_transmit_now (app->client, &nreq->header); | ||
2945 | return GNUNET_OK; | ||
2614 | } | 2946 | } |
2615 | 2947 | ||
2616 | 2948 | ||
2617 | /** | 2949 | /** |
2618 | * Start listening for entered places as host or guest. | 2950 | * Connect application to the social service. |
2619 | * | 2951 | * |
2620 | * The @notify_host and @notify_guest functions are | 2952 | * The @host_place_cb and @guest_place_cb functions are |
2621 | * initially called with the full list of entered places, | 2953 | * initially called for each entered places, |
2622 | * then later each time a new place is entered. | 2954 | * then later each time a new place is entered with the current application ID. |
2623 | * | 2955 | * |
2624 | * @param cfg | 2956 | * @param cfg |
2625 | * Configuration. | 2957 | * Configuration. |
2626 | * @param ego | 2958 | * @param id |
2627 | * Listen for places of this ego. | 2959 | * Application ID. |
2628 | * @param notify_host | 2960 | * @param notify_host |
2629 | * Function to notify about a place entered as host. | 2961 | * Function to notify about a place entered as host. |
2630 | * @param notify_guest | 2962 | * @param notify_guest |
@@ -2634,48 +2966,81 @@ GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
2634 | * | 2966 | * |
2635 | * @return Handle that can be used to stop listening. | 2967 | * @return Handle that can be used to stop listening. |
2636 | */ | 2968 | */ |
2637 | struct GNUNET_SOCIAL_PlaceListenHandle * | 2969 | struct GNUNET_SOCIAL_App * |
2638 | GNUNET_SOCIAL_place_listen_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | 2970 | GNUNET_SOCIAL_app_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, |
2639 | const struct GNUNET_IDENTITY_Ego *ego, | 2971 | const char *id, |
2640 | GNUNET_SOCIAL_PlaceNotifyHostCallback notify_host, | 2972 | GNUNET_SOCIAL_AppEgoCallback ego_cb, |
2641 | GNUNET_SOCIAL_PlaceNotifyGuestCallback notify_guest, | 2973 | GNUNET_SOCIAL_AppHostPlaceCallback host_cb, |
2642 | void *notify_cls) | 2974 | GNUNET_SOCIAL_AppGuestPlaceCallback guest_cb, |
2643 | { | 2975 | void *cls) |
2644 | struct GNUNET_SOCIAL_PlaceListenHandle *pl = GNUNET_malloc (sizeof *pl); | 2976 | { |
2645 | pl->notify_host = notify_host; | 2977 | uint16_t app_id_size = strnlen (id, GNUNET_SOCIAL_APP_MAX_ID_SIZE); |
2646 | pl->notify_guest = notify_guest; | 2978 | if (GNUNET_SOCIAL_APP_MAX_ID_SIZE == app_id_size) |
2647 | pl->notify_cls = notify_cls; | 2979 | return NULL; |
2648 | 2980 | app_id_size++; | |
2649 | struct GNUNET_SOCIAL_Place *plc = &pl->plc; | 2981 | |
2650 | 2982 | struct GNUNET_SOCIAL_App *app = GNUNET_malloc (sizeof *app); | |
2651 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | 2983 | app->cfg = cfg; |
2652 | plc->cfg = cfg; | 2984 | app->ego_cb = ego_cb; |
2653 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", | 2985 | app->host_cb = host_cb; |
2654 | notify_handlers); | 2986 | app->guest_cb = guest_cb; |
2655 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, pl, sizeof (*pl)); | 2987 | app->cb_cls = cls; |
2656 | 2988 | app->egos = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | |
2657 | struct PlaceListenRequest *req = GNUNET_malloc (sizeof (*req)); | 2989 | app->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", |
2658 | req->ego_key = plc->ego_key; | 2990 | app_handlers); |
2659 | req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN); | 2991 | GNUNET_CLIENT_MANAGER_set_user_context_ (app->client, app, sizeof (*app)); |
2660 | req->header.size = htons (sizeof (*req)); | ||
2661 | |||
2662 | plc->connect_msg = (struct GNUNET_MessageHeader *) req; | ||
2663 | place_send_connect_msg (plc); | ||
2664 | 2992 | ||
2665 | return pl; | 2993 | app->id = GNUNET_malloc (app_id_size); |
2994 | memcpy (app->id, id, app_id_size); | ||
2995 | |||
2996 | struct AppConnectRequest *creq = GNUNET_malloc (sizeof (*creq) + app_id_size); | ||
2997 | creq->header.size = htons (sizeof (*creq) + app_id_size); | ||
2998 | creq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT); | ||
2999 | memcpy (&creq[1], app->id, app_id_size); | ||
3000 | |||
3001 | app->connect_msg = &creq->header; | ||
3002 | app_send_connect_msg (app); | ||
3003 | |||
3004 | return app; | ||
3005 | } | ||
3006 | |||
3007 | |||
3008 | /** | ||
3009 | * Disconnect application. | ||
3010 | * | ||
3011 | * @param app | ||
3012 | * Application handle. | ||
3013 | */ | ||
3014 | void | ||
3015 | GNUNET_SOCIAL_app_disconnect (struct GNUNET_SOCIAL_App *app) | ||
3016 | { | ||
3017 | GNUNET_CLIENT_MANAGER_disconnect (app->client, GNUNET_NO, NULL, NULL); | ||
2666 | } | 3018 | } |
2667 | 3019 | ||
2668 | 3020 | ||
2669 | /** | 3021 | /** |
2670 | * Stop listening for entered places. | 3022 | * Detach application from a place. |
2671 | * | 3023 | * |
2672 | * @param pl | 3024 | * Removes the place from the entered places list for this application. |
2673 | * Place listen handle. | 3025 | * Note: this does not disconnect from the place. |
3026 | * | ||
3027 | * @see GNUNET_SOCIAL_host_disconnect() and GNUNET_SOCIAL_guest_disconnect() | ||
3028 | * | ||
3029 | * @param app | ||
3030 | * Application. | ||
3031 | * @param plc | ||
3032 | * Place. | ||
2674 | */ | 3033 | */ |
2675 | void | 3034 | void |
2676 | GNUNET_SOCIAL_place_listen_stop (struct GNUNET_SOCIAL_PlaceListenHandle *pl) | 3035 | GNUNET_SOCIAL_app_detach (struct GNUNET_SOCIAL_App *app, |
3036 | struct GNUNET_SOCIAL_Place *plc) | ||
2677 | { | 3037 | { |
2678 | GNUNET_CLIENT_MANAGER_disconnect (pl->plc.client, GNUNET_NO, NULL, NULL); | 3038 | struct AppDetachRequest dreq; |
3039 | dreq.header.size = htons (sizeof (dreq)); | ||
3040 | dreq.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH); | ||
3041 | dreq.place_pub_key = plc->pub_key; | ||
3042 | GNUNET_CLIENT_MANAGER_transmit_now (plc->client, &dreq.header); | ||
2679 | } | 3043 | } |
2680 | 3044 | ||
3045 | |||
2681 | /* end of social_api.c */ | 3046 | /* end of social_api.c */ |
diff --git a/src/social/test_social.c b/src/social/test_social.c index 158fa469d..38710cd1a 100644 --- a/src/social/test_social.c +++ b/src/social/test_social.c | |||
@@ -45,6 +45,9 @@ | |||
45 | */ | 45 | */ |
46 | int res; | 46 | int res; |
47 | 47 | ||
48 | struct GNUNET_SOCIAL_App *app; | ||
49 | const char *app_id = "test"; | ||
50 | |||
48 | /** | 51 | /** |
49 | * Handle for task for timeout termination. | 52 | * Handle for task for timeout termination. |
50 | */ | 53 | */ |
@@ -57,8 +60,8 @@ struct GNUNET_PeerIdentity this_peer; | |||
57 | 60 | ||
58 | struct GNUNET_IDENTITY_Handle *id; | 61 | struct GNUNET_IDENTITY_Handle *id; |
59 | 62 | ||
60 | const struct GNUNET_IDENTITY_Ego *host_ego; | 63 | const struct GNUNET_SOCIAL_Ego *host_ego; |
61 | const struct GNUNET_IDENTITY_Ego *guest_ego; | 64 | const struct GNUNET_SOCIAL_Ego *guest_ego; |
62 | 65 | ||
63 | const char *host_name = "Host One"; | 66 | const char *host_name = "Host One"; |
64 | const char *guest_name = "Guest One"; | 67 | const char *guest_name = "Guest One"; |
@@ -67,6 +70,8 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *place_key; | |||
67 | struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key; | 70 | struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key; |
68 | 71 | ||
69 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | 72 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; |
73 | struct GNUNET_HashCode place_pub_hash; | ||
74 | |||
70 | struct GNUNET_CRYPTO_EcdsaPublicKey guest_pub_key; | 75 | struct GNUNET_CRYPTO_EcdsaPublicKey guest_pub_key; |
71 | struct GNUNET_CRYPTO_EcdsaPublicKey host_pub_key; | 76 | struct GNUNET_CRYPTO_EcdsaPublicKey host_pub_key; |
72 | 77 | ||
@@ -111,32 +116,57 @@ struct GNUNET_PSYC_Message *join_resp; | |||
111 | 116 | ||
112 | uint32_t counter; | 117 | uint32_t counter; |
113 | 118 | ||
114 | uint8_t guest_pkey_added = GNUNET_NO; | 119 | uint8_t is_guest_nym_added = GNUNET_NO; |
120 | uint8_t is_host_reconnected = GNUNET_NO; | ||
121 | uint8_t is_guest_reconnected = GNUNET_NO; | ||
115 | 122 | ||
116 | enum | 123 | enum |
117 | { | 124 | { |
118 | TEST_NONE = 0, | 125 | TEST_NONE = 0, |
119 | TEST_HOST_ANSWER_DOOR_REFUSE = 1, | 126 | TEST_HOST_CREATE = 1, |
120 | TEST_GUEST_RECV_ENTRY_DCSN_REFUSE = 2, | 127 | TEST_HOST_ENTER = 2, |
121 | TEST_HOST_ANSWER_DOOR_ADMIT = 3, | 128 | TEST_GUEST_CREATE = 3, |
122 | TEST_GUEST_RECV_ENTRY_DCSN_ADMIT = 4, | 129 | TEST_GUEST_ENTER = 4, |
123 | TEST_HOST_ANNOUNCE = 5, | 130 | TEST_HOST_ANSWER_DOOR_REFUSE = 5, |
124 | TEST_HOST_ANNOUNCE_END = 6, | 131 | TEST_GUEST_RECV_ENTRY_DCSN_REFUSE = 6, |
125 | TEST_HOST_ANNOUNCE2 = 7, | 132 | TEST_HOST_ANSWER_DOOR_ADMIT = 7, |
126 | TEST_HOST_ANNOUNCE2_END = 8, | 133 | TEST_GUEST_RECV_ENTRY_DCSN_ADMIT = 8, |
127 | TEST_GUEST_TALK = 9, | 134 | TEST_HOST_ANNOUNCE = 9, |
128 | TEST_GUEST_HISTORY_REPLAY = 10, | 135 | TEST_HOST_ANNOUNCE_END = 10, |
129 | TEST_GUEST_HISTORY_REPLAY_LATEST = 11, | 136 | TEST_HOST_ANNOUNCE2 = 11, |
130 | TEST_GUEST_LOOK_AT = 12, | 137 | TEST_HOST_ANNOUNCE2_END = 12, |
131 | TEST_GUEST_LOOK_FOR = 13, | 138 | TEST_GUEST_TALK = 13, |
132 | TEST_GUEST_LEAVE = 14, | 139 | TEST_GUEST_HISTORY_REPLAY = 14, |
133 | TEST_HOST_ADVERTISE = 15, | 140 | TEST_GUEST_HISTORY_REPLAY_LATEST = 15, |
134 | TEST_GUEST_ENTER_BY_NAME = 16, | 141 | TEST_GUEST_LOOK_AT = 16, |
135 | TEST_HOST_LEAVE = 17, | 142 | TEST_GUEST_LOOK_FOR = 17, |
143 | TEST_GUEST_LEAVE = 18, | ||
144 | TEST_ZONE_ADD_PLACE = 19, | ||
145 | TEST_GUEST_ENTER_BY_NAME = 20, | ||
146 | TEST_RECONNECT = 21, | ||
147 | TEST_GUEST_LEAVE2 = 22, | ||
148 | TEST_HOST_LEAVE = 23, | ||
136 | } test; | 149 | } test; |
137 | 150 | ||
138 | 151 | ||
139 | static void | 152 | static void |
153 | schedule_guest_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
154 | |||
155 | static void | ||
156 | host_answer_door (void *cls, | ||
157 | struct GNUNET_SOCIAL_Nym *nym, | ||
158 | const char *method_name, | ||
159 | struct GNUNET_ENV_Environment *env, | ||
160 | size_t data_size, | ||
161 | const void *data); | ||
162 | |||
163 | static void | ||
164 | host_enter (); | ||
165 | |||
166 | static void | ||
167 | guest_init (); | ||
168 | |||
169 | static void | ||
140 | guest_enter (); | 170 | guest_enter (); |
141 | 171 | ||
142 | static void | 172 | static void |
@@ -167,18 +197,31 @@ cleanup () | |||
167 | id = NULL; | 197 | id = NULL; |
168 | } | 198 | } |
169 | 199 | ||
200 | if (NULL != guest_slicer) | ||
201 | { | ||
202 | GNUNET_SOCIAL_slicer_destroy (guest_slicer); | ||
203 | guest_slicer = NULL; | ||
204 | } | ||
205 | |||
206 | if (NULL != host_slicer) | ||
207 | { | ||
208 | GNUNET_SOCIAL_slicer_destroy (host_slicer); | ||
209 | host_slicer = NULL; | ||
210 | } | ||
211 | |||
170 | if (NULL != gst) | 212 | if (NULL != gst) |
171 | { | 213 | { |
172 | GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, NULL, NULL, NULL); | 214 | GNUNET_SOCIAL_guest_leave (gst, NULL, NULL, NULL); |
173 | gst = NULL; | 215 | gst = NULL; |
174 | gst_plc = NULL; | 216 | gst_plc = NULL; |
175 | } | 217 | } |
176 | if (NULL != hst) | 218 | if (NULL != hst) |
177 | { | 219 | { |
178 | GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, NULL, NULL); | 220 | GNUNET_SOCIAL_host_leave (hst, NULL, NULL, NULL); |
179 | hst = NULL; | 221 | hst = NULL; |
180 | hst_plc = NULL; | 222 | hst_plc = NULL; |
181 | } | 223 | } |
224 | GNUNET_SOCIAL_app_disconnect (app); | ||
182 | GNUNET_SCHEDULER_shutdown (); | 225 | GNUNET_SCHEDULER_shutdown (); |
183 | } | 226 | } |
184 | 227 | ||
@@ -295,58 +338,186 @@ host_left () | |||
295 | { | 338 | { |
296 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 339 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
297 | "The host has left the place.\n"); | 340 | "The host has left the place.\n"); |
298 | GNUNET_SOCIAL_slicer_destroy (host_slicer); | 341 | end (); |
299 | host_slicer = NULL; | 342 | } |
343 | |||
344 | |||
345 | static void | ||
346 | schedule_host_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
347 | { | ||
348 | test = TEST_HOST_LEAVE; | ||
349 | GNUNET_SOCIAL_host_leave (hst, NULL, &host_left, NULL); | ||
300 | hst = NULL; | 350 | hst = NULL; |
301 | hst_plc = NULL; | 351 | hst_plc = NULL; |
352 | } | ||
302 | 353 | ||
303 | // TODO: GNUNET_SOCIAL_place_listen_start () | ||
304 | 354 | ||
305 | end (); | 355 | static void |
356 | host_farewell2 (void *cls, | ||
357 | const struct GNUNET_SOCIAL_Nym *nym, | ||
358 | struct GNUNET_ENV_Environment *env) | ||
359 | { | ||
360 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
361 | "Nym left the place again.\n"); | ||
362 | GNUNET_SCHEDULER_add_now (schedule_host_leave, NULL); | ||
306 | } | 363 | } |
307 | 364 | ||
308 | 365 | ||
309 | static void | 366 | static void |
310 | schedule_host_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 367 | host_reconnected (void *cls, int result, |
368 | const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key, | ||
369 | uint64_t max_message_id) | ||
311 | { | 370 | { |
312 | test = TEST_HOST_LEAVE; | 371 | place_pub_key = *home_pub_key; |
313 | GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, &host_left, NULL); | 372 | GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash); |
373 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
374 | "Test #%u: Host reconnected to place %s\n", | ||
375 | test, GNUNET_h2s (&place_pub_hash)); | ||
376 | |||
377 | is_host_reconnected = GNUNET_YES; | ||
378 | if (GNUNET_YES == is_guest_reconnected) | ||
379 | { | ||
380 | GNUNET_SCHEDULER_add_now (schedule_guest_leave, NULL); | ||
381 | } | ||
314 | } | 382 | } |
315 | 383 | ||
316 | 384 | ||
317 | static void | 385 | static void |
318 | id_guest_ego_cb2 (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | 386 | guest_reconnected (void *cls, int result, uint64_t max_message_id) |
319 | { | 387 | { |
320 | GNUNET_assert (NULL != ego); | 388 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
321 | guest_ego = ego; | 389 | "Test #%u: Guest reconnected to place: %d\n", |
390 | test, result); | ||
391 | GNUNET_assert (0 <= result); | ||
322 | 392 | ||
323 | guest_enter_by_name (); | 393 | is_guest_reconnected = GNUNET_YES; |
394 | if (GNUNET_YES == is_host_reconnected) | ||
395 | { | ||
396 | GNUNET_SCHEDULER_add_now (schedule_guest_leave, NULL); | ||
397 | } | ||
324 | } | 398 | } |
325 | 399 | ||
326 | 400 | ||
327 | static void | 401 | static void |
328 | host_recv_advertise_result (void *cls, int32_t success, const char *emsg) | 402 | app_recv_host (void *cls, |
403 | struct GNUNET_SOCIAL_HostConnection *hconn, | ||
404 | struct GNUNET_SOCIAL_Ego *ego, | ||
405 | const struct GNUNET_CRYPTO_EddsaPublicKey *host_pub_key) | ||
406 | { | ||
407 | struct GNUNET_HashCode host_pub_hash; | ||
408 | GNUNET_CRYPTO_hash (host_pub_key, sizeof (*host_pub_key), &host_pub_hash); | ||
409 | |||
410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
411 | "Got app host place notification: %s\n", | ||
412 | GNUNET_h2s (&host_pub_hash)); | ||
413 | |||
414 | if (test == TEST_RECONNECT) | ||
415 | { | ||
416 | if (0 == memcmp (&place_pub_key, host_pub_key, sizeof (*host_pub_key))) | ||
417 | { | ||
418 | hst = GNUNET_SOCIAL_host_enter_reconnect (hconn, host_slicer, host_reconnected, | ||
419 | host_answer_door, host_farewell2, NULL); | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | |||
424 | |||
425 | static void | ||
426 | app_recv_guest (void *cls, | ||
427 | struct GNUNET_SOCIAL_GuestConnection *gconn, | ||
428 | struct GNUNET_SOCIAL_Ego *ego, | ||
429 | const struct GNUNET_CRYPTO_EddsaPublicKey *guest_pub_key) | ||
430 | { | ||
431 | struct GNUNET_HashCode guest_pub_hash; | ||
432 | GNUNET_CRYPTO_hash (guest_pub_key, sizeof (*guest_pub_key), &guest_pub_hash); | ||
433 | |||
434 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
435 | "Got app guest place notification: %s\n", | ||
436 | GNUNET_h2s (&guest_pub_hash)); | ||
437 | |||
438 | if (test == TEST_RECONNECT) | ||
439 | { | ||
440 | if (0 == memcmp (&place_pub_key, guest_pub_key, sizeof (*guest_pub_key))) | ||
441 | { | ||
442 | gst = GNUNET_SOCIAL_guest_enter_reconnect (gconn, guest_slicer, | ||
443 | guest_reconnected, NULL); | ||
444 | } | ||
445 | } | ||
446 | } | ||
447 | |||
448 | |||
449 | static void | ||
450 | app_recv_ego (void *cls, | ||
451 | struct GNUNET_SOCIAL_Ego *ego, | ||
452 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key, | ||
453 | const char *name) | ||
329 | { | 454 | { |
330 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 455 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
331 | "Test #%u: Advertise result: %d (%s).\n", | 456 | "Got app ego notification: %p %s %s\n", |
332 | test, success, emsg); | 457 | ego, name, |
333 | GNUNET_assert (GNUNET_YES == success); | 458 | GNUNET_CRYPTO_ecdsa_public_key_to_string (ego_pub_key)); |
459 | |||
460 | if (NULL != strstr (name, host_name) && TEST_HOST_CREATE == test) | ||
461 | { | ||
462 | host_ego = ego; | ||
463 | host_pub_key = *(GNUNET_SOCIAL_ego_get_pub_key (host_ego)); | ||
464 | GNUNET_assert (TEST_HOST_CREATE == test); | ||
465 | host_enter (); | ||
466 | } | ||
467 | else if (NULL != strstr (name, guest_name)) | ||
468 | { | ||
469 | guest_ego = ego; | ||
470 | |||
471 | if (TEST_GUEST_CREATE == test) | ||
472 | guest_init (); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | |||
477 | static void | ||
478 | schedule_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
479 | { | ||
480 | test = TEST_RECONNECT; | ||
334 | 481 | ||
335 | GNUNET_assert (GNUNET_YES == guest_pkey_added); | 482 | GNUNET_SOCIAL_host_disconnect (hst, NULL, NULL); |
336 | GNUNET_IDENTITY_ego_lookup (cfg, guest_name, id_guest_ego_cb2, NULL); | 483 | GNUNET_SOCIAL_guest_disconnect (gst, NULL, NULL); |
484 | hst = NULL; | ||
485 | gst = NULL; | ||
486 | |||
487 | GNUNET_SOCIAL_app_disconnect (app); | ||
488 | app = GNUNET_SOCIAL_app_connect (cfg, app_id, | ||
489 | app_recv_ego, | ||
490 | app_recv_host, | ||
491 | app_recv_guest, | ||
492 | NULL); | ||
337 | } | 493 | } |
338 | 494 | ||
339 | 495 | ||
340 | static void | 496 | static void |
341 | host_advertise () | 497 | host_recv_zone_add_place_result (void *cls, int64_t result, |
498 | const void *data, uint16_t data_size) | ||
342 | { | 499 | { |
343 | test = TEST_HOST_ADVERTISE; | ||
344 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 500 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
345 | "Test #%u: Advertising place.\n", test); | 501 | "Test #%u: Zone add place result: %d (%.*s).\n", |
502 | test, result, data_size, data); | ||
503 | GNUNET_assert (GNUNET_YES == result); | ||
346 | 504 | ||
347 | GNUNET_SOCIAL_host_advertise (hst, "home", 1, &this_peer, | 505 | GNUNET_assert (GNUNET_YES == is_guest_nym_added); |
506 | guest_enter_by_name (); | ||
507 | } | ||
508 | |||
509 | |||
510 | static void | ||
511 | zone_add_place () | ||
512 | { | ||
513 | test = TEST_ZONE_ADD_PLACE; | ||
514 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
515 | "Test #%u: Adding place to zone.\n", test); | ||
516 | |||
517 | GNUNET_SOCIAL_zone_add_place (app, host_ego, "home", "let.me*in!", | ||
518 | &place_pub_key, &this_peer, 1, &this_peer, | ||
348 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES), | 519 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES), |
349 | "let.me*in!", host_recv_advertise_result, hst); | 520 | host_recv_zone_add_place_result, app); |
350 | } | 521 | } |
351 | 522 | ||
352 | 523 | ||
@@ -356,12 +527,12 @@ host_farewell (void *cls, | |||
356 | struct GNUNET_ENV_Environment *env) | 527 | struct GNUNET_ENV_Environment *env) |
357 | { | 528 | { |
358 | const struct GNUNET_CRYPTO_EcdsaPublicKey * | 529 | const struct GNUNET_CRYPTO_EcdsaPublicKey * |
359 | nym_key = GNUNET_SOCIAL_nym_get_key (nym); | 530 | nym_key = GNUNET_SOCIAL_nym_get_pub_key (nym); |
360 | 531 | ||
361 | char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key); | 532 | char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key); |
362 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 533 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
363 | "Farewell: nym %s (%s) has left the place.\n", | 534 | "Farewell: nym %s (%s) has left the place.\n", |
364 | GNUNET_h2s (GNUNET_SOCIAL_nym_get_key_hash (nym)), str); | 535 | GNUNET_h2s (GNUNET_SOCIAL_nym_get_pub_key_hash (nym)), str); |
365 | GNUNET_free (str); | 536 | GNUNET_free (str); |
366 | GNUNET_assert (1 == GNUNET_ENV_environment_get_count (env)); | 537 | GNUNET_assert (1 == GNUNET_ENV_environment_get_count (env)); |
367 | if (0 != memcmp (&guest_pub_key, nym_key, sizeof (*nym_key))) | 538 | if (0 != memcmp (&guest_pub_key, nym_key, sizeof (*nym_key))) |
@@ -372,7 +543,7 @@ host_farewell (void *cls, | |||
372 | GNUNET_free (str); | 543 | GNUNET_free (str); |
373 | GNUNET_assert (0); | 544 | GNUNET_assert (0); |
374 | } | 545 | } |
375 | host_advertise (); | 546 | zone_add_place (); |
376 | } | 547 | } |
377 | 548 | ||
378 | 549 | ||
@@ -381,25 +552,24 @@ guest_left (void *cls) | |||
381 | { | 552 | { |
382 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 553 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
383 | "The guest has left the place.\n"); | 554 | "The guest has left the place.\n"); |
384 | GNUNET_SOCIAL_slicer_destroy (guest_slicer); | ||
385 | guest_slicer = NULL; | ||
386 | gst = NULL; | ||
387 | gst_plc = NULL; | ||
388 | } | 555 | } |
389 | 556 | ||
390 | 557 | ||
391 | static void | 558 | static void |
392 | guest_leave() | 559 | guest_leave() |
393 | { | 560 | { |
394 | test = TEST_GUEST_LEAVE; | 561 | if (test < TEST_RECONNECT) |
562 | test = TEST_GUEST_LEAVE; | ||
563 | else | ||
564 | test = TEST_GUEST_LEAVE2; | ||
395 | 565 | ||
396 | struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); | 566 | struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); |
397 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET, | 567 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET, |
398 | "_message", DATA2ARG ("Leaving.")); | 568 | "_message", DATA2ARG ("Leaving.")); |
399 | GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, env, &guest_left, NULL); | 569 | GNUNET_SOCIAL_guest_leave (gst, env, &guest_left, NULL); |
400 | GNUNET_ENV_environment_destroy (env); | 570 | GNUNET_ENV_environment_destroy (env); |
401 | 571 | gst = NULL; | |
402 | /* @todo test keep_active */ | 572 | gst_plc = NULL; |
403 | } | 573 | } |
404 | 574 | ||
405 | 575 | ||
@@ -871,7 +1041,7 @@ guest_recv_entry_decision (void *cls, | |||
871 | break; | 1041 | break; |
872 | 1042 | ||
873 | case TEST_GUEST_ENTER_BY_NAME: | 1043 | case TEST_GUEST_ENTER_BY_NAME: |
874 | GNUNET_SCHEDULER_add_now (schedule_host_leave, NULL); | 1044 | GNUNET_SCHEDULER_add_now (schedule_reconnect, NULL); |
875 | break; | 1045 | break; |
876 | 1046 | ||
877 | default: | 1047 | default: |
@@ -951,7 +1121,7 @@ guest_enter () | |||
951 | emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env, | 1121 | emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env, |
952 | emsg->data, emsg->data_size); | 1122 | emsg->data, emsg->data_size); |
953 | 1123 | ||
954 | gst = GNUNET_SOCIAL_guest_enter (cfg, guest_ego, &place_pub_key, | 1124 | gst = GNUNET_SOCIAL_guest_enter (app, guest_ego, &place_pub_key, |
955 | &this_peer, 0, NULL, emsg->msg, guest_slicer, | 1125 | &this_peer, 0, NULL, emsg->msg, guest_slicer, |
956 | guest_recv_local_enter, | 1126 | guest_recv_local_enter, |
957 | guest_recv_entry_decision, NULL); | 1127 | guest_recv_entry_decision, NULL); |
@@ -979,7 +1149,7 @@ guest_enter_by_name () | |||
979 | emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env, | 1149 | emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env, |
980 | emsg->data, emsg->data_size); | 1150 | emsg->data, emsg->data_size); |
981 | 1151 | ||
982 | gst = GNUNET_SOCIAL_guest_enter_by_name (cfg, guest_ego, | 1152 | gst = GNUNET_SOCIAL_guest_enter_by_name (app, guest_ego, |
983 | "home.host.gnu", "let.me*in!", | 1153 | "home.host.gnu", "let.me*in!", |
984 | emsg->msg, guest_slicer, | 1154 | emsg->msg, guest_slicer, |
985 | guest_recv_local_enter, | 1155 | guest_recv_local_enter, |
@@ -989,19 +1159,18 @@ guest_enter_by_name () | |||
989 | 1159 | ||
990 | 1160 | ||
991 | static void | 1161 | static void |
992 | guest_recv_add_pkey_result (void *cls, int32_t success, const char *emsg) | 1162 | app_recv_zone_add_nym_result (void *cls, int64_t result, |
1163 | const void *data, uint16_t data_size) | ||
993 | { | 1164 | { |
994 | GNUNET_assert (GNUNET_YES == success); | 1165 | GNUNET_assert (GNUNET_YES == result); |
995 | guest_pkey_added = GNUNET_YES; | 1166 | is_guest_nym_added = GNUNET_YES; |
996 | } | 1167 | } |
997 | 1168 | ||
998 | 1169 | ||
999 | static void | 1170 | static void |
1000 | id_guest_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | 1171 | guest_init () |
1001 | { | 1172 | { |
1002 | GNUNET_assert (NULL != ego); | 1173 | guest_pub_key = *(GNUNET_SOCIAL_ego_get_pub_key (guest_ego)); |
1003 | guest_ego = ego; | ||
1004 | GNUNET_IDENTITY_ego_get_public_key (ego, &guest_pub_key); | ||
1005 | 1174 | ||
1006 | guest_slicer = GNUNET_SOCIAL_slicer_create (); | 1175 | guest_slicer = GNUNET_SOCIAL_slicer_create (); |
1007 | GNUNET_SOCIAL_slicer_method_add (guest_slicer, "", | 1176 | GNUNET_SOCIAL_slicer_method_add (guest_slicer, "", |
@@ -1011,10 +1180,9 @@ id_guest_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | |||
1011 | guest_recv_mod_foo_bar, &mod_foo_bar_rcls); | 1180 | guest_recv_mod_foo_bar, &mod_foo_bar_rcls); |
1012 | test = TEST_HOST_ANSWER_DOOR_ADMIT; | 1181 | test = TEST_HOST_ANSWER_DOOR_ADMIT; |
1013 | 1182 | ||
1014 | GNUNET_SOCIAL_zone_add_pkey (cfg, guest_ego, "host", &host_pub_key, | 1183 | GNUNET_SOCIAL_zone_add_nym (app, guest_ego, "host", &host_pub_key, |
1015 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES), | 1184 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES), |
1016 | guest_recv_add_pkey_result, NULL); | 1185 | app_recv_zone_add_nym_result, NULL); |
1017 | |||
1018 | guest_enter (); | 1186 | guest_enter (); |
1019 | } | 1187 | } |
1020 | 1188 | ||
@@ -1030,37 +1198,40 @@ id_guest_created (void *cls, const char *emsg) | |||
1030 | GNUNET_assert (0); | 1198 | GNUNET_assert (0); |
1031 | #endif | 1199 | #endif |
1032 | } | 1200 | } |
1033 | 1201 | if (NULL != guest_ego) | |
1034 | GNUNET_IDENTITY_ego_lookup (cfg, guest_name, &id_guest_ego_cb, NULL); | 1202 | guest_init (); |
1035 | } | 1203 | } |
1036 | 1204 | ||
1037 | 1205 | ||
1038 | static void | 1206 | static void |
1039 | host_entered (void *cls, int result, uint64_t max_message_id) | 1207 | host_entered (void *cls, int result, |
1208 | const struct GNUNET_CRYPTO_EddsaPublicKey *home_pub_key, | ||
1209 | uint64_t max_message_id) | ||
1040 | { | 1210 | { |
1041 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Host entered to place.\n"); | 1211 | place_pub_key = *home_pub_key; |
1212 | GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash); | ||
1213 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1214 | "Host entered to place %s\n", GNUNET_h2s (&place_pub_hash)); | ||
1042 | 1215 | ||
1216 | test = TEST_GUEST_CREATE; | ||
1043 | GNUNET_IDENTITY_create (id, guest_name, &id_guest_created, NULL); | 1217 | GNUNET_IDENTITY_create (id, guest_name, &id_guest_created, NULL); |
1044 | } | 1218 | } |
1045 | 1219 | ||
1046 | 1220 | ||
1047 | static void | 1221 | static void |
1048 | id_host_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | 1222 | host_enter () |
1049 | { | 1223 | { |
1050 | GNUNET_assert (NULL != ego); | ||
1051 | host_ego = ego; | ||
1052 | GNUNET_IDENTITY_ego_get_public_key (ego, &host_pub_key); | ||
1053 | |||
1054 | host_slicer = GNUNET_SOCIAL_slicer_create (); | 1224 | host_slicer = GNUNET_SOCIAL_slicer_create (); |
1055 | GNUNET_SOCIAL_slicer_method_add (host_slicer, "", | 1225 | GNUNET_SOCIAL_slicer_method_add (host_slicer, "", |
1056 | &host_recv_method, &host_recv_modifier, | 1226 | &host_recv_method, &host_recv_modifier, |
1057 | &host_recv_data, &host_recv_eom, NULL); | 1227 | &host_recv_data, &host_recv_eom, NULL); |
1058 | 1228 | ||
1059 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n"); | 1229 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n"); |
1060 | hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key, | 1230 | test = TEST_HOST_ENTER; |
1061 | GNUNET_PSYC_CHANNEL_PRIVATE, host_slicer, | 1231 | hst = GNUNET_SOCIAL_host_enter (app, host_ego, |
1062 | host_entered, host_answer_door, | 1232 | GNUNET_PSYC_CHANNEL_PRIVATE, |
1063 | host_farewell, NULL); | 1233 | host_slicer, host_entered, |
1234 | host_answer_door, host_farewell, NULL); | ||
1064 | hst_plc = GNUNET_SOCIAL_host_get_place (hst); | 1235 | hst_plc = GNUNET_SOCIAL_host_get_place (hst); |
1065 | } | 1236 | } |
1066 | 1237 | ||
@@ -1068,6 +1239,12 @@ id_host_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | |||
1068 | static void | 1239 | static void |
1069 | id_host_created (void *cls, const char *emsg) | 1240 | id_host_created (void *cls, const char *emsg) |
1070 | { | 1241 | { |
1242 | if (NULL != core) | ||
1243 | { | ||
1244 | GNUNET_CORE_disconnect (core); | ||
1245 | core = NULL; | ||
1246 | } | ||
1247 | |||
1071 | if (NULL != emsg) | 1248 | if (NULL != emsg) |
1072 | { | 1249 | { |
1073 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -1077,7 +1254,11 @@ id_host_created (void *cls, const char *emsg) | |||
1077 | #endif | 1254 | #endif |
1078 | } | 1255 | } |
1079 | 1256 | ||
1080 | GNUNET_IDENTITY_ego_lookup (cfg, host_name, &id_host_ego_cb, NULL); | 1257 | app = GNUNET_SOCIAL_app_connect (cfg, app_id, |
1258 | app_recv_ego, | ||
1259 | app_recv_host, | ||
1260 | app_recv_guest, | ||
1261 | NULL); | ||
1081 | } | 1262 | } |
1082 | 1263 | ||
1083 | 1264 | ||
@@ -1085,7 +1266,6 @@ static void | |||
1085 | identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego, | 1266 | identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego, |
1086 | void **ctx, const char *name) | 1267 | void **ctx, const char *name) |
1087 | { | 1268 | { |
1088 | |||
1089 | } | 1269 | } |
1090 | 1270 | ||
1091 | 1271 | ||
@@ -1093,8 +1273,9 @@ static void | |||
1093 | core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity) | 1273 | core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity) |
1094 | { | 1274 | { |
1095 | this_peer = *my_identity; | 1275 | this_peer = *my_identity; |
1096 | |||
1097 | id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL); | 1276 | id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL); |
1277 | |||
1278 | test = TEST_HOST_CREATE; | ||
1098 | GNUNET_IDENTITY_create (id, host_name, &id_host_created, NULL); | 1279 | GNUNET_IDENTITY_create (id, host_name, &id_host_created, NULL); |
1099 | } | 1280 | } |
1100 | 1281 | ||
@@ -1119,9 +1300,6 @@ run (void *cls, | |||
1119 | cfg = c; | 1300 | cfg = c; |
1120 | end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); | 1301 | end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); |
1121 | 1302 | ||
1122 | place_key = GNUNET_CRYPTO_eddsa_key_create (); | ||
1123 | GNUNET_CRYPTO_eddsa_key_get_public (place_key, &place_pub_key); | ||
1124 | |||
1125 | core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL, | 1303 | core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL, |
1126 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); | 1304 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); |
1127 | } | 1305 | } |