aboutsummaryrefslogtreecommitdiff
path: root/src/social/social_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/social/social_api.c')
-rw-r--r--src/social/social_api.c292
1 files changed, 186 insertions, 106 deletions
diff --git a/src/social/social_api.c b/src/social/social_api.c
index d57d16cfb..89843831b 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -183,6 +183,7 @@ struct GNUNET_SOCIAL_Place
183 */ 183 */
184 struct GNUNET_PSYC_Slicer *slicer; 184 struct GNUNET_PSYC_Slicer *slicer;
185 185
186 // FIXME: do we need is_disconnecing like on the psyc and multicast APIs?
186 /** 187 /**
187 * Function called after disconnected from the service. 188 * Function called after disconnected from the service.
188 */ 189 */
@@ -371,6 +372,68 @@ struct ZoneAddNymHandle
371}; 372};
372 373
373 374
375/*** CLEANUP / DISCONNECT ***/
376
377
378static void
379host_cleanup (struct GNUNET_SOCIAL_Host *hst)
380{
381 if (NULL != hst->slicer)
382 {
383 GNUNET_PSYC_slicer_destroy (hst->slicer);
384 hst->slicer = NULL;
385 }
386 GNUNET_free (hst);
387}
388
389
390static void
391guest_cleanup (struct GNUNET_SOCIAL_Guest *gst)
392{
393 GNUNET_free (gst);
394}
395
396
397static void
398place_cleanup (struct GNUNET_SOCIAL_Place *plc)
399{
400 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
401 "cleaning up place %p\n",
402 plc);
403 if (NULL != plc->tmit)
404 {
405 GNUNET_PSYC_transmit_destroy (plc->tmit);
406 plc->tmit = NULL;
407 }
408 if (NULL != plc->connect_env)
409 {
410 GNUNET_MQ_discard (plc->connect_env);
411 plc->connect_env = NULL;
412 }
413 if (NULL != plc->mq)
414 {
415 GNUNET_MQ_destroy (plc->mq);
416 plc->mq = NULL;
417 }
418 if (NULL != plc->disconnect_cb)
419 {
420 plc->disconnect_cb (plc->disconnect_cls);
421 plc->disconnect_cb = NULL;
422 }
423
424 (GNUNET_YES == plc->is_host)
425 ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
426 : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
427}
428
429
430static void
431place_disconnect (struct GNUNET_SOCIAL_Place *plc)
432{
433 place_cleanup (plc);
434}
435
436
374/*** NYM ***/ 437/*** NYM ***/
375 438
376static struct GNUNET_SOCIAL_Nym * 439static struct GNUNET_SOCIAL_Nym *
@@ -428,7 +491,7 @@ host_recv_notice_place_leave_method (void *cls,
428 491
429 struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&msg->slave_pub_key); 492 struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&msg->slave_pub_key);
430 493
431 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432 "Host received method for message ID %" PRIu64 " from nym %s: %s\n", 495 "Host received method for message ID %" PRIu64 " from nym %s: %s\n",
433 message_id, GNUNET_h2s (&nym->pub_key_hash), method_name); 496 message_id, GNUNET_h2s (&nym->pub_key_hash), method_name);
434 497
@@ -436,7 +499,7 @@ host_recv_notice_place_leave_method (void *cls,
436 hst->notice_place_leave_env = GNUNET_PSYC_env_create (); 499 hst->notice_place_leave_env = GNUNET_PSYC_env_create ();
437 500
438 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key); 501 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key);
439 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 "_notice_place_leave: got method from nym %s (%s).\n", 503 "_notice_place_leave: got method from nym %s (%s).\n",
441 GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str); 504 GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
442 GNUNET_free (str); 505 GNUNET_free (str);
@@ -458,7 +521,7 @@ host_recv_notice_place_leave_modifier (void *cls,
458 if (NULL == hst->notice_place_leave_env) 521 if (NULL == hst->notice_place_leave_env)
459 return; 522 return;
460 523
461 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
462 "Host received modifier for _notice_place_leave message with ID %" PRIu64 ":\n" 525 "Host received modifier for _notice_place_leave message with ID %" PRIu64 ":\n"
463 "%c%s: %.*s\n", 526 "%c%s: %.*s\n",
464 message_id, oper, name, value_size, (const char *) value); 527 message_id, oper, name, value_size, (const char *) value);
@@ -485,7 +548,7 @@ host_recv_notice_place_leave_eom (void *cls,
485 return; 548 return;
486 549
487 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key); 550 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key);
488 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489 "_notice_place_leave: got EOM from nym %s (%s).\n", 552 "_notice_place_leave: got EOM from nym %s (%s).\n",
490 GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str); 553 GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
491 GNUNET_free (str); 554 GNUNET_free (str);
@@ -1015,100 +1078,24 @@ handle_app_place_end (void *cls,
1015} 1078}
1016 1079
1017 1080
1018/*** CLEANUP / DISCONNECT ***/ 1081/**
1019 1082 * Handler for a #GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK message received
1020 1083 * from the social service.
1021static void 1084 *
1022host_cleanup (struct GNUNET_SOCIAL_Host *hst) 1085 * @param cls the place of type `struct GNUNET_SOCIAL_Place`
1023{ 1086 * @param msg the message received from the service
1024 if (NULL != hst->slicer) 1087 */
1025 {
1026 GNUNET_PSYC_slicer_destroy (hst->slicer);
1027 hst->slicer = NULL;
1028 }
1029 GNUNET_free (hst);
1030}
1031
1032
1033static void 1088static void
1034guest_cleanup (struct GNUNET_SOCIAL_Guest *gst) 1089handle_place_leave_ack (void *cls,
1090 const struct GNUNET_MessageHeader *msg)
1035{ 1091{
1036 GNUNET_free (gst); 1092 struct GNUNET_SOCIAL_Place *plc = cls;
1037}
1038
1039 1093
1040static void
1041place_cleanup (struct GNUNET_SOCIAL_Place *plc)
1042{
1043 struct GNUNET_HashCode place_pub_hash;
1044 GNUNET_CRYPTO_hash (&plc->pub_key, sizeof (plc->pub_key), &place_pub_hash);
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1046 "%s place cleanup: %s\n", 1095 "%s left place %p\n",
1047 GNUNET_YES == plc->is_host ? "host" : "guest", 1096 plc->is_host ? "host" : "guest",
1048 GNUNET_h2s (&place_pub_hash)); 1097 plc);
1049 1098 place_disconnect (plc);
1050 if (NULL != plc->tmit)
1051 {
1052 GNUNET_PSYC_transmit_destroy (plc->tmit);
1053 plc->tmit = NULL;
1054 }
1055 if (NULL != plc->connect_env)
1056 {
1057 GNUNET_MQ_discard (plc->connect_env);
1058 plc->connect_env = NULL;
1059 }
1060 if (NULL != plc->mq)
1061 {
1062 GNUNET_MQ_destroy (plc->mq);
1063 plc->mq = NULL;
1064 }
1065 if (NULL != plc->disconnect_cb)
1066 {
1067 plc->disconnect_cb (plc->disconnect_cls);
1068 plc->disconnect_cb = NULL;
1069 }
1070
1071 (GNUNET_YES == plc->is_host)
1072 ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
1073 : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
1074}
1075
1076
1077void
1078place_disconnect (struct GNUNET_SOCIAL_Place *plc,
1079 GNUNET_ContinuationCallback cb,
1080 void *cls)
1081{
1082 plc->disconnect_cb = cb;
1083 plc->disconnect_cls = cls;
1084
1085 if (NULL != plc->mq)
1086 {
1087 struct GNUNET_MQ_Envelope *env = GNUNET_MQ_get_last_envelope (plc->mq);
1088 if (NULL != env)
1089 {
1090 GNUNET_MQ_notify_sent (env, (GNUNET_SCHEDULER_TaskCallback) place_cleanup, plc);
1091 }
1092 else
1093 {
1094 place_cleanup (plc);
1095 }
1096 }
1097 else
1098 {
1099 place_cleanup (plc);
1100 }
1101}
1102
1103
1104void
1105place_leave (struct GNUNET_SOCIAL_Place *plc)
1106{
1107 struct GNUNET_MessageHeader *msg;
1108 struct GNUNET_MQ_Envelope *
1109 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
1110
1111 GNUNET_MQ_send (plc->mq, env);
1112} 1099}
1113 1100
1114 1101
@@ -1168,6 +1155,10 @@ host_connect (struct GNUNET_SOCIAL_Host *hst)
1168 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK, 1155 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK,
1169 struct HostEnterAck, 1156 struct HostEnterAck,
1170 hst), 1157 hst),
1158 GNUNET_MQ_hd_fixed_size (place_leave_ack,
1159 GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
1160 struct GNUNET_MessageHeader,
1161 plc),
1171 GNUNET_MQ_hd_var_size (host_enter_request, 1162 GNUNET_MQ_hd_var_size (host_enter_request,
1172 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, 1163 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
1173 struct GNUNET_PSYC_JoinRequestMessage, 1164 struct GNUNET_PSYC_JoinRequestMessage,
@@ -1516,6 +1507,9 @@ GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host *hst,
1516 void *notify_data_cls, 1507 void *notify_data_cls,
1517 enum GNUNET_SOCIAL_AnnounceFlags flags) 1508 enum GNUNET_SOCIAL_AnnounceFlags flags)
1518{ 1509{
1510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1511 "PSYC_transmit_message for host, method: %s\n",
1512 method_name);
1519 if (GNUNET_OK == 1513 if (GNUNET_OK ==
1520 GNUNET_PSYC_transmit_message (hst->plc.tmit, method_name, env, 1514 GNUNET_PSYC_transmit_message (hst->plc.tmit, method_name, env,
1521 NULL, notify_data, notify_data_cls, flags)) 1515 NULL, notify_data, notify_data_cls, flags))
@@ -1580,7 +1574,11 @@ GNUNET_SOCIAL_host_disconnect (struct GNUNET_SOCIAL_Host *hst,
1580 GNUNET_ContinuationCallback disconnect_cb, 1574 GNUNET_ContinuationCallback disconnect_cb,
1581 void *cls) 1575 void *cls)
1582{ 1576{
1583 place_disconnect (&hst->plc, disconnect_cb, cls); 1577 struct GNUNET_SOCIAL_Place *plc = &hst->plc;
1578
1579 plc->disconnect_cb = disconnect_cb;
1580 plc->disconnect_cls = cls;
1581 place_disconnect (plc);
1584} 1582}
1585 1583
1586 1584
@@ -1607,10 +1605,15 @@ GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst,
1607 GNUNET_ContinuationCallback disconnect_cb, 1605 GNUNET_ContinuationCallback disconnect_cb,
1608 void *cls) 1606 void *cls)
1609{ 1607{
1608 struct GNUNET_MQ_Envelope *envelope;
1609
1610 GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL, 1610 GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL,
1611 GNUNET_SOCIAL_ANNOUNCE_NONE); 1611 GNUNET_SOCIAL_ANNOUNCE_NONE);
1612 place_leave (&hst->plc); 1612 hst->plc.disconnect_cb = disconnect_cb;
1613 GNUNET_SOCIAL_host_disconnect (hst, disconnect_cb, cls); 1613 hst->plc.disconnect_cls = cls;
1614 envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
1615 GNUNET_MQ_send (hst->plc.mq,
1616 envelope);
1614} 1617}
1615 1618
1616 1619
@@ -1670,6 +1673,10 @@ guest_connect (struct GNUNET_SOCIAL_Guest *gst)
1670 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK, 1673 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK,
1671 struct GNUNET_PSYC_CountersResultMessage, 1674 struct GNUNET_PSYC_CountersResultMessage,
1672 gst), 1675 gst),
1676 GNUNET_MQ_hd_fixed_size (place_leave_ack,
1677 GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
1678 struct GNUNET_MessageHeader,
1679 plc),
1673 GNUNET_MQ_hd_var_size (guest_enter_decision, 1680 GNUNET_MQ_hd_var_size (guest_enter_decision,
1674 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 1681 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
1675 struct GNUNET_PSYC_JoinDecisionMessage, 1682 struct GNUNET_PSYC_JoinDecisionMessage,
@@ -1896,6 +1903,64 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_SOCIAL_App *app,
1896} 1903}
1897 1904
1898 1905
1906struct ReconnectContext
1907{
1908 struct GNUNET_SOCIAL_Guest *guest;
1909 int *result;
1910 int64_t *max_message_id;
1911 GNUNET_SOCIAL_GuestEnterCallback enter_cb;
1912 void *enter_cls;
1913};
1914
1915
1916static void
1917guest_enter_reconnect_cb (void *cls,
1918 int result,
1919 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
1920 uint64_t max_message_id)
1921{
1922 struct ReconnectContext *reconnect_ctx = cls;
1923
1924 GNUNET_assert (NULL != reconnect_ctx);
1925 reconnect_ctx->result = GNUNET_new (int);
1926 *(reconnect_ctx->result) = result;
1927 reconnect_ctx->max_message_id = GNUNET_new (int64_t);
1928 *(reconnect_ctx->max_message_id) = max_message_id;
1929}
1930
1931
1932static void
1933guest_entry_dcsn_reconnect_cb (void *cls,
1934 int is_admitted,
1935 const struct GNUNET_PSYC_Message *entry_resp)
1936{
1937 struct ReconnectContext *reconnect_ctx = cls;
1938 struct GNUNET_SOCIAL_Guest *gst = reconnect_ctx->guest;
1939
1940 GNUNET_assert (NULL != reconnect_ctx);
1941 GNUNET_assert (NULL != reconnect_ctx->result);
1942 GNUNET_assert (NULL != reconnect_ctx->max_message_id);
1943 if (GNUNET_YES != is_admitted)
1944 {
1945 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1946 "Guest was rejected after calling "
1947 "GNUNET_SOCIAL_guest_enter_reconnect ()\n");
1948 }
1949 else if (NULL != reconnect_ctx->enter_cb)
1950 {
1951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1952 "guest reconnected!\n");
1953 reconnect_ctx->enter_cb (reconnect_ctx->enter_cls,
1954 *(reconnect_ctx->result),
1955 &gst->plc.pub_key,
1956 *(reconnect_ctx->max_message_id));
1957 }
1958 GNUNET_free (reconnect_ctx->result);
1959 GNUNET_free (reconnect_ctx->max_message_id);
1960 GNUNET_free (reconnect_ctx);
1961}
1962
1963
1899/** 1964/**
1900 * Reconnect to an already entered place as guest. 1965 * Reconnect to an already entered place as guest.
1901 * 1966 *
@@ -1906,8 +1971,8 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_SOCIAL_App *app,
1906 * Flags for the entry. 1971 * Flags for the entry.
1907 * @param slicer 1972 * @param slicer
1908 * Slicer to use for processing incoming requests from guests. 1973 * Slicer to use for processing incoming requests from guests.
1909 * @param local_enter_cb 1974 * @param enter_cb
1910 * Called upon connection established to the social service. 1975 * Called upon re-entering is complete.
1911 * @param entry_decision_cb 1976 * @param entry_decision_cb
1912 * Called upon receiving entry decision. 1977 * Called upon receiving entry decision.
1913 * 1978 *
@@ -1917,11 +1982,12 @@ struct GNUNET_SOCIAL_Guest *
1917GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn, 1982GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn,
1918 enum GNUNET_PSYC_SlaveJoinFlags flags, 1983 enum GNUNET_PSYC_SlaveJoinFlags flags,
1919 struct GNUNET_PSYC_Slicer *slicer, 1984 struct GNUNET_PSYC_Slicer *slicer,
1920 GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, 1985 GNUNET_SOCIAL_GuestEnterCallback enter_cb,
1921 void *cls) 1986 void *cls)
1922{ 1987{
1923 struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); 1988 struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst));
1924 struct GNUNET_SOCIAL_Place *plc = &gst->plc; 1989 struct GNUNET_SOCIAL_Place *plc = &gst->plc;
1990 struct ReconnectContext *reconnect_ctx;
1925 1991
1926 uint16_t app_id_size = strlen (gconn->app->id) + 1; 1992 uint16_t app_id_size = strlen (gconn->app->id) + 1;
1927 struct GuestEnterRequest *greq; 1993 struct GuestEnterRequest *greq;
@@ -1940,10 +2006,15 @@ GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn
1940 plc->pub_key = gconn->plc_msg.place_pub_key; 2006 plc->pub_key = gconn->plc_msg.place_pub_key;
1941 plc->ego_pub_key = gconn->plc_msg.ego_pub_key; 2007 plc->ego_pub_key = gconn->plc_msg.ego_pub_key;
1942 2008
1943 plc->op = GNUNET_OP_create (); 2009 reconnect_ctx = GNUNET_new (struct ReconnectContext);
2010 reconnect_ctx->guest = gst;
2011 reconnect_ctx->enter_cb = enter_cb;
2012 reconnect_ctx->enter_cls = cls;
1944 2013
1945 gst->enter_cb = local_enter_cb; 2014 plc->op = GNUNET_OP_create ();
1946 gst->cb_cls = cls; 2015 gst->enter_cb = &guest_enter_reconnect_cb;
2016 gst->entry_dcsn_cb = &guest_entry_dcsn_reconnect_cb;
2017 gst->cb_cls = reconnect_ctx;
1947 2018
1948 guest_connect (gst); 2019 guest_connect (gst);
1949 return gst; 2020 return gst;
@@ -2028,7 +2099,11 @@ GNUNET_SOCIAL_guest_disconnect (struct GNUNET_SOCIAL_Guest *gst,
2028 GNUNET_ContinuationCallback disconnect_cb, 2099 GNUNET_ContinuationCallback disconnect_cb,
2029 void *cls) 2100 void *cls)
2030{ 2101{
2031 place_disconnect (&gst->plc, disconnect_cb, cls); 2102 struct GNUNET_SOCIAL_Place *plc = &gst->plc;
2103
2104 plc->disconnect_cb = disconnect_cb;
2105 plc->disconnect_cls = cls;
2106 place_disconnect (plc);
2032} 2107}
2033 2108
2034 2109
@@ -2054,10 +2129,15 @@ GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst,
2054 GNUNET_ContinuationCallback disconnect_cb, 2129 GNUNET_ContinuationCallback disconnect_cb,
2055 void *cls) 2130 void *cls)
2056{ 2131{
2132 struct GNUNET_MQ_Envelope *envelope;
2133
2057 GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL, 2134 GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL,
2058 GNUNET_SOCIAL_TALK_NONE); 2135 GNUNET_SOCIAL_TALK_NONE);
2059 place_leave (&gst->plc); 2136 gst->plc.disconnect_cb = disconnect_cb;
2060 GNUNET_SOCIAL_guest_disconnect (gst, disconnect_cb, cls); 2137 gst->plc.disconnect_cls = cls;
2138 envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
2139 GNUNET_MQ_send (gst->plc.mq,
2140 envelope);
2061} 2141}
2062 2142
2063 2143