aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2015-09-05 23:44:11 +0000
committerGabor X Toth <*@tg-x.net>2015-09-05 23:44:11 +0000
commit8752370da610cd9313b4dbfcb261420b6c181344 (patch)
tree7b19fc7ea58565ed0df19e1b4849996bb702338c
parent878b09fe6521df37c2d39f884a6c892b370473a5 (diff)
downloadgnunet-8752370da610cd9313b4dbfcb261420b6c181344.tar.gz
gnunet-8752370da610cd9313b4dbfcb261420b6c181344.zip
social: farewell
-rw-r--r--src/include/gnunet_social_service.h55
-rw-r--r--src/social/social_api.c295
-rw-r--r--src/social/test_social.c53
3 files changed, 285 insertions, 118 deletions
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h
index 24aa871ed..62f6ab7c7 100644
--- a/src/include/gnunet_social_service.h
+++ b/src/include/gnunet_social_service.h
@@ -339,17 +339,15 @@ typedef void
339 * This is also called if the @a nym was never given permission to enter 339 * This is also called if the @a nym was never given permission to enter
340 * (i.e. the @a nym stopped asking to get in). 340 * (i.e. the @a nym stopped asking to get in).
341 * 341 *
342 * @param cls Closure. 342 * @param cls
343 * @param nym Handle for the user who left. 343 * Closure.
344 * @param variable_count Number of elements in the @a variables array. 344 * @param nym
345 * @param variables Variables present in the message. 345 * Handle for the user who left.
346 */ 346 */
347typedef void 347typedef void
348(*GNUNET_SOCIAL_FarewellCallback) (void *cls, 348(*GNUNET_SOCIAL_FarewellCallback) (void *cls,
349 struct GNUNET_SOCIAL_Nym *nym, 349 const struct GNUNET_SOCIAL_Nym *nym,
350 struct GNUNET_ENV_Environment *env, 350 struct GNUNET_ENV_Environment *env);
351 size_t variable_count,
352 struct GNUNET_ENV_Modifier *variables);
353 351
354 352
355/** 353/**
@@ -443,12 +441,14 @@ GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst,
443 * #GNUNET_SOCIAL_FarewellCallback is invoked, 441 * #GNUNET_SOCIAL_FarewellCallback is invoked,
444 * which should be very soon after this call. 442 * which should be very soon after this call.
445 * 443 *
446 * @param host Host of the place. 444 * @param host
447 * @param nym Handle for the entity to be ejected. 445 * Host of the place.
446 * @param nym
447 * Handle for the entity to be ejected.
448 */ 448 */
449void 449void
450GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host, 450GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host,
451 struct GNUNET_SOCIAL_Nym *nym); 451 const struct GNUNET_SOCIAL_Nym *nym);
452 452
453 453
454/** 454/**
@@ -461,21 +461,8 @@ GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host,
461 * 461 *
462 * @return Public key of nym; 462 * @return Public key of nym;
463 */ 463 */
464struct GNUNET_CRYPTO_EcdsaPublicKey * 464const struct GNUNET_CRYPTO_EcdsaPublicKey *
465GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym); 465GNUNET_SOCIAL_nym_get_key (const struct GNUNET_SOCIAL_Nym *nym);
466
467
468/**
469 * Obtain the private-public key pair of the host.
470 *
471 * @param host Host to get the key of.
472 * @param[out] host_key Set to the private-public key pair of the host. The
473 * public part is suitable for storing in GNS within a "PLACE"
474 * record, along with peer IDs to join at.
475 */
476void
477GNUNET_SOCIAL_host_get_key (struct GNUNET_SOCIAL_Host *host,
478 struct GNUNET_CRYPTO_EddsaPrivateKey *host_key);
479 466
480 467
481/** 468/**
@@ -782,23 +769,25 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr);
782 769
783 770
784/** 771/**
785 * Leave a place permanently. 772 * Leave a place temporarily or permanently.
786 * 773 *
787 * Notifies the owner of the place about leaving, and destroys the place handle. 774 * Notifies the owner of the place about leaving, and destroys the place handle.
788 * 775 *
789 * @param place 776 * @param place
790 * Place to leave permanently. 777 * Place to leave.
791 * @param keep_active 778 * @param keep_active
792 * Keep place active after last application disconnected. 779 * Keep place active after last application disconnected.
780 * #GNUNET_YES or #GNUNET_NO
781 * @param env
782 * Optional environment for the leave message if @a keep_active
783 * is #GNUNET_NO. NULL if not needed.
793 * @param leave_cb 784 * @param leave_cb
794 * Function called after the guest left the place 785 * Called upon disconnecting from the social service.
795 * and disconnected from the social service.
796 * @param leave_cls
797 * Closure for @a leave_cb.
798 */ 786 */
799void 787void
800GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *guest, 788GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst,
801 int keep_active, 789 int keep_active,
790 struct GNUNET_ENV_Environment *env,
802 GNUNET_ContinuationCallback leave_cb, 791 GNUNET_ContinuationCallback leave_cb,
803 void *leave_cls); 792 void *leave_cls);
804 793
diff --git a/src/social/social_api.c b/src/social/social_api.c
index c4045975a..23a977beb 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -49,6 +49,16 @@ static struct GNUNET_PeerIdentity this_peer;
49 49
50 50
51/** 51/**
52 * Handle for a pseudonym of another user in the network.
53 */
54struct GNUNET_SOCIAL_Nym
55{
56 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
57 struct GNUNET_HashCode pub_key_hash;
58};
59
60
61/**
52 * Handle for a place where social interactions happen. 62 * Handle for a place where social interactions happen.
53 */ 63 */
54struct GNUNET_SOCIAL_Place 64struct GNUNET_SOCIAL_Place
@@ -64,24 +74,24 @@ struct GNUNET_SOCIAL_Place
64 struct GNUNET_CLIENT_MANAGER_Connection *client; 74 struct GNUNET_CLIENT_MANAGER_Connection *client;
65 75
66 /** 76 /**
67 * Transmission handle; 77 * Transmission handle.
68 */ 78 */
69 struct GNUNET_PSYC_TransmitHandle *tmit; 79 struct GNUNET_PSYC_TransmitHandle *tmit;
70 80
71 /** 81 /**
72 * Receipt handle; 82 * Receipt handle.
73 */ 83 */
74 struct GNUNET_PSYC_ReceiveHandle *recv; 84 struct GNUNET_PSYC_ReceiveHandle *recv;
75 85
76 /** 86 /**
77 * Message to send on reconnect. 87 * Slicer for processing incoming methods.
78 */ 88 */
79 struct GNUNET_MessageHeader *connect_msg; 89 struct GNUNET_SOCIAL_Slicer *slicer;
80 90
81 /** 91 /**
82 * Slicer for processing incoming methods. 92 * Message to send on reconnect.
83 */ 93 */
84 struct GNUNET_SOCIAL_Slicer *slicer; 94 struct GNUNET_MessageHeader *connect_msg;
85 95
86 /** 96 /**
87 * Function called after disconnected from the service. 97 * Function called after disconnected from the service.
@@ -125,6 +135,16 @@ struct GNUNET_SOCIAL_Host
125 135
126 struct GNUNET_CRYPTO_EddsaPrivateKey place_key; 136 struct GNUNET_CRYPTO_EddsaPrivateKey place_key;
127 137
138 /**
139 * Receipt handle.
140 */
141 struct GNUNET_PSYC_ReceiveHandle *recv;
142
143 /**
144 * Slicer for processing incoming methods.
145 */
146 struct GNUNET_SOCIAL_Slicer *slicer;
147
128 GNUNET_SOCIAL_HostEnterCallback enter_cb; 148 GNUNET_SOCIAL_HostEnterCallback enter_cb;
129 149
130 GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb; 150 GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb;
@@ -135,6 +155,9 @@ struct GNUNET_SOCIAL_Host
135 * Closure for callbacks. 155 * Closure for callbacks.
136 */ 156 */
137 void *cb_cls; 157 void *cb_cls;
158
159 struct GNUNET_SOCIAL_Nym *notice_place_leave_nym;
160 struct GNUNET_ENV_Environment *notice_place_leave_env;
138}; 161};
139 162
140 163
@@ -145,6 +168,16 @@ struct GNUNET_SOCIAL_Guest
145{ 168{
146 struct GNUNET_SOCIAL_Place plc; 169 struct GNUNET_SOCIAL_Place plc;
147 170
171 /**
172 * Receipt handle.
173 */
174 struct GNUNET_PSYC_ReceiveHandle *recv;
175
176 /**
177 * Slicer for processing incoming methods.
178 */
179 struct GNUNET_SOCIAL_Slicer *slicer;
180
148 GNUNET_SOCIAL_GuestEnterCallback enter_cb; 181 GNUNET_SOCIAL_GuestEnterCallback enter_cb;
149 182
150 GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb; 183 GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb;
@@ -157,16 +190,6 @@ struct GNUNET_SOCIAL_Guest
157 190
158 191
159/** 192/**
160 * Handle for a pseudonym of another user in the network.
161 */
162struct GNUNET_SOCIAL_Nym
163{
164 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
165 struct GNUNET_HashCode pub_key_hash;
166};
167
168
169/**
170 * Hash map of all nyms. 193 * Hash map of all nyms.
171 * pub_key_hash -> struct GNUNET_SOCIAL_Nym * 194 * pub_key_hash -> struct GNUNET_SOCIAL_Nym *
172 */ 195 */
@@ -381,6 +404,8 @@ struct GNUNET_SOCIAL_LookHandle
381}; 404};
382 405
383 406
407/*** NYM ***/
408
384static struct GNUNET_SOCIAL_Nym * 409static struct GNUNET_SOCIAL_Nym *
385nym_get_or_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key) 410nym_get_or_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key)
386{ 411{
@@ -417,6 +442,91 @@ nym_destroy (struct GNUNET_SOCIAL_Nym *nym)
417} 442}
418 443
419 444
445/*** MESSAGE HANDLERS ***/
446
447/** _notice_place_leave from guests */
448
449static void
450host_recv_notice_place_leave_method (void *cls,
451 const struct GNUNET_PSYC_MessageMethod *meth,
452 uint64_t message_id,
453 uint32_t flags,
454 const struct GNUNET_SOCIAL_Nym *nym,
455 const char *method_name)
456{
457 struct GNUNET_SOCIAL_Host *hst = cls;
458 if (NULL == nym)
459 return;
460
461 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
462 "Host received method for message ID %" PRIu64 " from nym %s: %s\n",
463 message_id, GNUNET_h2s (&nym->pub_key_hash), method_name);
464
465 hst->notice_place_leave_nym = (struct GNUNET_SOCIAL_Nym *) nym;
466 hst->notice_place_leave_env = GNUNET_ENV_environment_create ();
467}
468
469
470static void
471host_recv_notice_place_leave_modifier (void *cls,
472 const struct GNUNET_MessageHeader *msg,
473 uint64_t message_id,
474 enum GNUNET_ENV_Operator oper,
475 const char *name,
476 const void *value,
477 uint16_t value_size,
478 uint16_t full_value_size)
479{
480 struct GNUNET_SOCIAL_Host *hst = cls;
481 if (NULL == hst->notice_place_leave_env)
482 return;
483
484 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
485 "Host received modifier for _notice_place_leave message with ID %" PRIu64 ":\n"
486 "%c%s: %.*s\n",
487 message_id, oper, name, value_size, value);
488
489 /* skip _nym, it's added later in eom() */
490 if (0 == memcmp (name, "_nym", sizeof ("_nym"))
491 || 0 == memcmp (name, "_nym_", sizeof ("_nym_") - 1))
492 return;
493
494 GNUNET_ENV_environment_add (hst->notice_place_leave_env,
495 GNUNET_ENV_OP_SET, name, value, value_size);
496}
497
498
499static void
500host_recv_notice_place_leave_eom (void *cls,
501 const struct GNUNET_MessageHeader *msg,
502 uint64_t message_id,
503 uint8_t cancelled)
504{
505 struct GNUNET_SOCIAL_Host *hst = cls;
506 if (NULL == hst->notice_place_leave_env)
507 return;
508
509 if (GNUNET_YES != cancelled)
510 {
511 if (NULL != hst->farewell_cb)
512 hst->farewell_cb (hst->cb_cls, hst->notice_place_leave_nym,
513 hst->notice_place_leave_env);
514 /* announce leaving guest to place */
515 GNUNET_ENV_environment_add (hst->notice_place_leave_env, GNUNET_ENV_OP_SET,
516 "_nym", hst->notice_place_leave_nym,
517 sizeof (*hst->notice_place_leave_nym));
518 GNUNET_SOCIAL_host_announce (hst, "_notice_place_leave",
519 hst->notice_place_leave_env,
520 NULL, NULL, GNUNET_SOCIAL_ANNOUNCE_NONE);
521 nym_destroy (hst->notice_place_leave_nym);
522 }
523 GNUNET_ENV_environment_destroy (hst->notice_place_leave_env);
524 hst->notice_place_leave_env = NULL;
525}
526
527
528/*** SLICER ***/
529
420/** 530/**
421 * Call a method handler for an incoming message part. 531 * Call a method handler for an incoming message part.
422 */ 532 */
@@ -526,10 +636,13 @@ slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
526 * The message part. as it arrived from the network. 636 * The message part. as it arrived from the network.
527 */ 637 */
528static void 638static void
529slicer_message (void *cls, uint64_t message_id, uint64_t fragment_offset, 639slicer_message (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
530 uint32_t flags, const struct GNUNET_MessageHeader *msg) 640 uint64_t message_id, uint32_t flags, uint64_t fragment_offset,
641 const struct GNUNET_MessageHeader *msg)
531{ 642{
532 struct GNUNET_SOCIAL_Slicer *slicer = cls; 643 struct GNUNET_SOCIAL_Slicer *slicer = cls;
644 slicer->nym_key = *slave_key;
645
533 uint16_t ptype = ntohs (msg->type); 646 uint16_t ptype = ntohs (msg->type);
534 if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype) 647 if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype)
535 { 648 {
@@ -874,6 +987,9 @@ GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer)
874} 987}
875 988
876 989
990/*** PLACE ***/
991
992
877static void 993static void
878place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc) 994place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc)
879{ 995{
@@ -885,6 +1001,19 @@ place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc)
885 1001
886 1002
887static void 1003static void
1004place_recv_disconnect (void *cls,
1005 struct GNUNET_CLIENT_MANAGER_Connection *client,
1006 const struct GNUNET_MessageHeader *msg)
1007{
1008 struct GNUNET_SOCIAL_Place *
1009 plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc));
1010
1011 GNUNET_CLIENT_MANAGER_reconnect (client);
1012 place_send_connect_msg (plc);
1013}
1014
1015
1016static void
888place_recv_result (void *cls, 1017place_recv_result (void *cls,
889 struct GNUNET_CLIENT_MANAGER_Connection *client, 1018 struct GNUNET_CLIENT_MANAGER_Connection *client,
890 const struct GNUNET_MessageHeader *msg) 1019 const struct GNUNET_MessageHeader *msg)
@@ -1084,15 +1213,16 @@ place_recv_message (void *cls,
1084 1213
1085 1214
1086static void 1215static void
1087place_recv_disconnect (void *cls, 1216host_recv_message (void *cls,
1088 struct GNUNET_CLIENT_MANAGER_Connection *client, 1217 struct GNUNET_CLIENT_MANAGER_Connection *client,
1089 const struct GNUNET_MessageHeader *msg) 1218 const struct GNUNET_MessageHeader *msg)
1090{ 1219{
1091 struct GNUNET_SOCIAL_Place * 1220 struct GNUNET_SOCIAL_Host *
1092 plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc)); 1221 hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (hst->plc));
1093 1222 GNUNET_PSYC_receive_message (hst->recv,
1094 GNUNET_CLIENT_MANAGER_reconnect (client); 1223 (const struct GNUNET_PSYC_MessageHeader *) msg);
1095 place_send_connect_msg (plc); 1224 GNUNET_PSYC_receive_message (hst->plc.recv,
1225 (const struct GNUNET_PSYC_MessageHeader *) msg);
1096} 1226}
1097 1227
1098 1228
@@ -1203,35 +1333,35 @@ guest_recv_join_decision (void *cls,
1203 1333
1204static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] = 1334static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] =
1205{ 1335{
1206 { &host_recv_enter_ack, NULL, 1336 { host_recv_enter_ack, NULL,
1207 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK, 1337 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK,
1208 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO }, 1338 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO },
1209 1339
1210 { &host_recv_enter_request, NULL, 1340 { host_recv_enter_request, NULL,
1211 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, 1341 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
1212 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, 1342 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES },
1213 1343
1214 { &place_recv_message, NULL, 1344 { host_recv_message, NULL,
1215 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 1345 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE,
1216 sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES }, 1346 sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES },
1217 1347
1218 { &place_recv_message_ack, NULL, 1348 { place_recv_message_ack, NULL,
1219 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK, 1349 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK,
1220 sizeof (struct GNUNET_MessageHeader), GNUNET_NO }, 1350 sizeof (struct GNUNET_MessageHeader), GNUNET_NO },
1221 1351
1222 { &place_recv_history_result, NULL, 1352 { place_recv_history_result, NULL,
1223 GNUNET_MESSAGE_TYPE_PSYC_HISTORY_RESULT, 1353 GNUNET_MESSAGE_TYPE_PSYC_HISTORY_RESULT,
1224 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1354 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1225 1355
1226 { &place_recv_state_result, NULL, 1356 { place_recv_state_result, NULL,
1227 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT, 1357 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT,
1228 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1358 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1229 1359
1230 { &place_recv_result, NULL, 1360 { place_recv_result, NULL,
1231 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE, 1361 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE,
1232 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1362 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1233 1363
1234 { &place_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 1364 { place_recv_disconnect, NULL, 0, 0, GNUNET_NO },
1235 1365
1236 { NULL, NULL, 0, 0, GNUNET_NO } 1366 { NULL, NULL, 0, 0, GNUNET_NO }
1237}; 1367};
@@ -1239,39 +1369,39 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] =
1239 1369
1240static struct GNUNET_CLIENT_MANAGER_MessageHandler guest_handlers[] = 1370static struct GNUNET_CLIENT_MANAGER_MessageHandler guest_handlers[] =
1241{ 1371{
1242 { &guest_recv_enter_ack, NULL, 1372 { guest_recv_enter_ack, NULL,
1243 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK, 1373 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK,
1244 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO }, 1374 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO },
1245 1375
1246 { &host_recv_enter_request, NULL, 1376 { host_recv_enter_request, NULL,
1247 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, 1377 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
1248 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, 1378 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES },
1249 1379
1250 { &place_recv_message, NULL, 1380 { place_recv_message, NULL,
1251 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 1381 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE,
1252 sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES }, 1382 sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES },
1253 1383
1254 { &place_recv_message_ack, NULL, 1384 { place_recv_message_ack, NULL,
1255 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK, 1385 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK,
1256 sizeof (struct GNUNET_MessageHeader), GNUNET_NO }, 1386 sizeof (struct GNUNET_MessageHeader), GNUNET_NO },
1257 1387
1258 { &guest_recv_join_decision, NULL, 1388 { guest_recv_join_decision, NULL,
1259 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 1389 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
1260 sizeof (struct GNUNET_PSYC_JoinDecisionMessage), GNUNET_YES }, 1390 sizeof (struct GNUNET_PSYC_JoinDecisionMessage), GNUNET_YES },
1261 1391
1262 { &place_recv_history_result, NULL, 1392 { place_recv_history_result, NULL,
1263 GNUNET_MESSAGE_TYPE_PSYC_HISTORY_RESULT, 1393 GNUNET_MESSAGE_TYPE_PSYC_HISTORY_RESULT,
1264 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1394 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1265 1395
1266 { &place_recv_state_result, NULL, 1396 { place_recv_state_result, NULL,
1267 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT, 1397 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT,
1268 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1398 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1269 1399
1270 { &place_recv_result, NULL, 1400 { place_recv_result, NULL,
1271 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE, 1401 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE,
1272 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES }, 1402 sizeof (struct GNUNET_OperationResultMessage), GNUNET_YES },
1273 1403
1274 { &place_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 1404 { place_recv_disconnect, NULL, 0, 0, GNUNET_NO },
1275 1405
1276 { NULL, NULL, 0, 0, GNUNET_NO } 1406 { NULL, NULL, 0, 0, GNUNET_NO }
1277}; 1407};
@@ -1293,6 +1423,8 @@ host_cleanup (void *cls)
1293{ 1423{
1294 struct GNUNET_SOCIAL_Host *hst = cls; 1424 struct GNUNET_SOCIAL_Host *hst = cls;
1295 place_cleanup (&hst->plc); 1425 place_cleanup (&hst->plc);
1426 GNUNET_PSYC_receive_destroy (hst->recv);
1427 GNUNET_SOCIAL_slicer_destroy (hst->slicer);
1296 GNUNET_free (hst); 1428 GNUNET_free (hst);
1297} 1429}
1298 1430
@@ -1306,6 +1438,8 @@ guest_cleanup (void *cls)
1306} 1438}
1307 1439
1308 1440
1441/*** HOST ***/
1442
1309/** 1443/**
1310 * Enter a place as host. 1444 * Enter a place as host.
1311 * 1445 *
@@ -1376,13 +1510,21 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1376 hst->plc.ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); 1510 hst->plc.ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego);
1377 hst->enter_cb = enter_cb; 1511 hst->enter_cb = enter_cb;
1378 hst->answer_door_cb = answer_door_cb; 1512 hst->answer_door_cb = answer_door_cb;
1513 hst->farewell_cb = farewell_cb;
1379 hst->cb_cls = cls; 1514 hst->cb_cls = cls;
1380 1515
1381 plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", host_handlers); 1516 plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", host_handlers);
1382 GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); 1517 GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc));
1383 1518
1384 plc->tmit = GNUNET_PSYC_transmit_create (plc->client); 1519 plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
1385 plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc->slicer); 1520 plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer);
1521
1522 hst->slicer = GNUNET_SOCIAL_slicer_create ();
1523 GNUNET_SOCIAL_slicer_method_add (hst->slicer, "_notice_place_leave",
1524 host_recv_notice_place_leave_method,
1525 host_recv_notice_place_leave_modifier,
1526 NULL, host_recv_notice_place_leave_eom, hst);
1527 hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer);
1386 1528
1387 place_send_connect_msg (plc); 1529 place_send_connect_msg (plc);
1388 return hst; 1530 return hst;
@@ -1495,14 +1637,20 @@ GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst,
1495 * #GNUNET_SOCIAL_FarewellCallback is invoked, 1637 * #GNUNET_SOCIAL_FarewellCallback is invoked,
1496 * which should be very soon after this call. 1638 * which should be very soon after this call.
1497 * 1639 *
1498 * @param host Host of the place. 1640 * @param host
1499 * @param nym Handle for the entity to be ejected. 1641 * Host of the place.
1642 * @param nym
1643 * Handle for the entity to be ejected.
1500 */ 1644 */
1501void 1645void
1502GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host, 1646GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *hst,
1503 struct GNUNET_SOCIAL_Nym *nym) 1647 const struct GNUNET_SOCIAL_Nym *nym)
1504{ 1648{
1505 1649 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
1650 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET,
1651 "_nym", &nym->pub_key, sizeof (nym->pub_key));
1652 GNUNET_SOCIAL_host_announce (hst, "_notice_place_leave", env, NULL, NULL,
1653 GNUNET_SOCIAL_ANNOUNCE_NONE);
1506} 1654}
1507 1655
1508 1656
@@ -1511,11 +1659,13 @@ GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host,
1511 * 1659 *
1512 * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). 1660 * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name().
1513 * 1661 *
1514 * @param nym Pseudonym to map to a cryptographic identifier. 1662 * @param nym
1515 * @param[out] nym_key Set to the public key of the nym. 1663 * Pseudonym to map to a cryptographic identifier.
1664 * @param[out] nym_key
1665 * Set to the public key of the nym.
1516 */ 1666 */
1517struct GNUNET_CRYPTO_EcdsaPublicKey * 1667const struct GNUNET_CRYPTO_EcdsaPublicKey *
1518GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym) 1668GNUNET_SOCIAL_nym_get_key (const struct GNUNET_SOCIAL_Nym *nym)
1519{ 1669{
1520 return &nym->pub_key; 1670 return &nym->pub_key;
1521} 1671}
@@ -1703,6 +1853,8 @@ GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst,
1703} 1853}
1704 1854
1705 1855
1856/*** GUEST ***/
1857
1706static struct GuestEnterRequest * 1858static struct GuestEnterRequest *
1707guest_enter_request_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key, 1859guest_enter_request_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key,
1708 const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, 1860 const struct GNUNET_CRYPTO_EddsaPublicKey *place_key,
@@ -1768,10 +1920,6 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1768 struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); 1920 struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst));
1769 struct GNUNET_SOCIAL_Place *plc = &gst->plc; 1921 struct GNUNET_SOCIAL_Place *plc = &gst->plc;
1770 1922
1771 struct GuestEnterRequest *
1772 req = guest_enter_request_create (&plc->ego_key, place_key, origin,
1773 relay_count, relays, entry_msg);
1774 plc->connect_msg = &req->header;
1775 plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); 1923 plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego);
1776 plc->pub_key = *place_key; 1924 plc->pub_key = *place_key;
1777 plc->cfg = cfg; 1925 plc->cfg = cfg;
@@ -1786,8 +1934,12 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1786 GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); 1934 GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc));
1787 1935
1788 plc->tmit = GNUNET_PSYC_transmit_create (plc->client); 1936 plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
1789 plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc->slicer); 1937 plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc->slicer);
1790 1938
1939 struct GuestEnterRequest *
1940 req = guest_enter_request_create (&plc->ego_key, place_key, origin,
1941 relay_count, relays, entry_msg);
1942 plc->connect_msg = &req->header;
1791 place_send_connect_msg (plc); 1943 place_send_connect_msg (plc);
1792 return gst; 1944 return gst;
1793} 1945}
@@ -1871,7 +2023,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count,
1871 plc->pub_key = req->place_key; 2023 plc->pub_key = req->place_key;
1872 2024
1873 plc->tmit = GNUNET_PSYC_transmit_create (plc->client); 2025 plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
1874 plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc); 2026 plc->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, plc);
1875 2027
1876 place_send_connect_msg (plc); 2028 place_send_connect_msg (plc);
1877} 2029}
@@ -2000,16 +2152,25 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr)
2000 2152
2001 2153
2002/** 2154/**
2003 * Leave a place permanently. 2155 * Leave a place temporarily or permanently.
2004 * 2156 *
2005 * Notifies the owner of the place about leaving, and destroys the place handle. 2157 * Notifies the owner of the place about leaving, and destroys the place handle.
2006 * 2158 *
2007 * @param place Place to leave permanently. 2159 * @param place
2008 * @param keep_active Keep place active after last application disconnected. 2160 * Place to leave.
2161 * @param keep_active
2162 * Keep place active after last application disconnected.
2163 * #GNUNET_YES or #GNUNET_NO
2164 * @param env
2165 * Optional environment for the leave message if @a keep_active
2166 * is #GNUNET_NO. NULL if not needed.
2167 * @param leave_cb
2168 * Called upon disconnecting from the social service.
2009 */ 2169 */
2010void 2170void
2011GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst, 2171GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst,
2012 int keep_active, 2172 int keep_active,
2173 struct GNUNET_ENV_Environment *env,
2013 GNUNET_ContinuationCallback leave_cb, 2174 GNUNET_ContinuationCallback leave_cb,
2014 void *leave_cls) 2175 void *leave_cls)
2015{ 2176{
@@ -2021,6 +2182,12 @@ GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst,
2021 plc->disconnect_cb = leave_cb; 2182 plc->disconnect_cb = leave_cb;
2022 plc->disconnect_cls = leave_cls; 2183 plc->disconnect_cls = leave_cls;
2023 2184
2185 if (GNUNET_NO == keep_active)
2186 {
2187 GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL,
2188 GNUNET_SOCIAL_TALK_NONE);
2189 }
2190
2024 GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, 2191 GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES,
2025 &guest_cleanup, gst); 2192 &guest_cleanup, gst);
2026} 2193}
@@ -2056,7 +2223,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc,
2056 struct GNUNET_PSYC_HistoryRequestMessage *req; 2223 struct GNUNET_PSYC_HistoryRequestMessage *req;
2057 struct GNUNET_SOCIAL_HistoryRequest *hist = GNUNET_malloc (sizeof (*hist)); 2224 struct GNUNET_SOCIAL_HistoryRequest *hist = GNUNET_malloc (sizeof (*hist));
2058 hist->plc = plc; 2225 hist->plc = plc;
2059 hist->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, slicer); 2226 hist->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, slicer);
2060 hist->result_cb = result_cb; 2227 hist->result_cb = result_cb;
2061 hist->cls = cls; 2228 hist->cls = cls;
2062 hist->op_id = GNUNET_CLIENT_MANAGER_op_add (plc->client, 2229 hist->op_id = GNUNET_CLIENT_MANAGER_op_add (plc->client,
diff --git a/src/social/test_social.c b/src/social/test_social.c
index 93e7c9bf2..ad4101bd6 100644
--- a/src/social/test_social.c
+++ b/src/social/test_social.c
@@ -78,6 +78,8 @@ struct GNUNET_SOCIAL_Guest *gst;
78struct GNUNET_SOCIAL_Place *hst_plc; 78struct GNUNET_SOCIAL_Place *hst_plc;
79struct GNUNET_SOCIAL_Place *gst_plc; 79struct GNUNET_SOCIAL_Place *gst_plc;
80 80
81struct GNUNET_SOCIAL_Nym *nym_eject;
82
81struct GuestEnterMessage 83struct GuestEnterMessage
82{ 84{
83 struct GNUNET_PSYC_Message *msg; 85 struct GNUNET_PSYC_Message *msg;
@@ -161,7 +163,7 @@ cleanup ()
161 163
162 if (NULL != gst) 164 if (NULL != gst)
163 { 165 {
164 GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, NULL, NULL); 166 GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, NULL, NULL, NULL);
165 gst = NULL; 167 gst = NULL;
166 gst_plc = NULL; 168 gst_plc = NULL;
167 } 169 }
@@ -306,21 +308,26 @@ schedule_host_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
306 308
307static void 309static void
308host_farewell (void *cls, 310host_farewell (void *cls,
309 struct GNUNET_SOCIAL_Nym *nym, 311 const struct GNUNET_SOCIAL_Nym *nym,
310 struct GNUNET_ENV_Environment *env, 312 struct GNUNET_ENV_Environment *env)
311 size_t variable_count,
312 struct GNUNET_ENV_Modifier *variables)
313{ 313{
314 // FIXME: this function is not called yet 314 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_key = GNUNET_SOCIAL_nym_get_key (nym);
315 struct GNUNET_CRYPTO_EcdsaPublicKey *nym_key = GNUNET_SOCIAL_nym_get_key (nym);
316 char *str; 315 char *str;
317 316
318 str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key); 317 str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
319 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 318 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
320 "Nym %s has left the place.\n", 319 "Farewell: nym %s has left the place.\n",
321 str); 320 str);
322 GNUNET_free (str); 321 GNUNET_free (str);
323 GNUNET_assert (0 == memcmp (&guest_pub_key, nym_key, sizeof (*nym_key))); 322 GNUNET_assert (1 == GNUNET_ENV_environment_get_count (env));
323 if (0 != memcmp (&guest_pub_key, nym_key, sizeof (*nym_key)))
324 {
325 str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&guest_pub_key);
326 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
327 "Farewell: nym does not match guest: %s\n", str);
328 GNUNET_free (str);
329 GNUNET_assert (0);
330 }
324 331
325 GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL); 332 GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
326} 333}
@@ -335,8 +342,6 @@ guest_left (void *cls)
335 guest_slicer = NULL; 342 guest_slicer = NULL;
336 gst = NULL; 343 gst = NULL;
337 gst_plc = NULL; 344 gst_plc = NULL;
338
339 GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
340} 345}
341 346
342 347
@@ -344,8 +349,14 @@ static void
344guest_leave() 349guest_leave()
345{ 350{
346 test = TEST_GUEST_LEAVE; 351 test = TEST_GUEST_LEAVE;
347 /* FIXME test keep_active */ 352
348 GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, &guest_left, NULL); 353 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
354 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_SET,
355 "_message", DATA2ARG ("Leaving."));
356 GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, env, &guest_left, NULL);
357 GNUNET_ENV_environment_destroy (env);
358
359 /* @todo test keep_active */
349} 360}
350 361
351 362
@@ -683,6 +694,9 @@ host_recv_eom (void *cls,
683 guest_history_replay (); 694 guest_history_replay ();
684 break; 695 break;
685 696
697 case TEST_GUEST_LEAVE:
698 break;
699
686 default: 700 default:
687 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test); 701 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid test: %d\n", test);
688 GNUNET_assert (0); 702 GNUNET_assert (0);
@@ -738,8 +752,7 @@ host_announce ()
738 tmit.host_ann 752 tmit.host_ann
739 = GNUNET_SOCIAL_host_announce (hst, "_message_host", tmit.env, 753 = GNUNET_SOCIAL_host_announce (hst, "_message_host", tmit.env,
740 &notify_data, &tmit, 754 &notify_data, &tmit,
741 GNUNET_SOCIAL_ANNOUNCE_NONE 755 GNUNET_SOCIAL_ANNOUNCE_NONE);
742 | GNUNET_PSYC_MASTER_TRANSMIT_STATE_MODIFY);
743} 756}
744 757
745 758
@@ -753,7 +766,7 @@ host_announce2 ()
753 test = TEST_HOST_ANNOUNCE2; 766 test = TEST_HOST_ANNOUNCE2;
754 767
755 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 768 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
756 "Test #%u: Host announcement.\n", test); 769 "Test #%u: Host announcement 2.\n", test);
757 770
758 tmit = (struct TransmitClosure) {}; 771 tmit = (struct TransmitClosure) {};
759 tmit.env = GNUNET_ENV_environment_create (); 772 tmit.env = GNUNET_ENV_environment_create ();
@@ -898,6 +911,7 @@ id_guest_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
898{ 911{
899 GNUNET_assert (NULL != ego); 912 GNUNET_assert (NULL != ego);
900 guest_ego = ego; 913 guest_ego = ego;
914 GNUNET_IDENTITY_ego_get_public_key (ego, &guest_pub_key);
901 915
902 guest_slicer = GNUNET_SOCIAL_slicer_create (); 916 guest_slicer = GNUNET_SOCIAL_slicer_create ();
903 GNUNET_SOCIAL_slicer_method_add (guest_slicer, "", 917 GNUNET_SOCIAL_slicer_method_add (guest_slicer, "",
@@ -950,8 +964,8 @@ id_host_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
950 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n"); 964 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n");
951 hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key, 965 hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key,
952 GNUNET_PSYC_CHANNEL_PRIVATE, host_slicer, 966 GNUNET_PSYC_CHANNEL_PRIVATE, host_slicer,
953 &host_entered, &host_answer_door, 967 host_entered, host_answer_door,
954 &host_farewell, NULL); 968 host_farewell, NULL);
955 hst_plc = GNUNET_SOCIAL_host_get_place (hst); 969 hst_plc = GNUNET_SOCIAL_host_get_place (hst);
956} 970}
957 971
@@ -1011,10 +1025,7 @@ run (void *cls,
1011 end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); 1025 end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
1012 1026
1013 place_key = GNUNET_CRYPTO_eddsa_key_create (); 1027 place_key = GNUNET_CRYPTO_eddsa_key_create ();
1014 guest_key = GNUNET_CRYPTO_ecdsa_key_create ();
1015
1016 GNUNET_CRYPTO_eddsa_key_get_public (place_key, &place_pub_key); 1028 GNUNET_CRYPTO_eddsa_key_get_public (place_key, &place_pub_key);
1017 GNUNET_CRYPTO_ecdsa_key_get_public (guest_key, &guest_pub_key);
1018 1029
1019 core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL, 1030 core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL,
1020 NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); 1031 NULL, GNUNET_NO, NULL, GNUNET_NO, NULL);