*/
struct GNUNET_PSYC_Slicer *slicer;
+ // FIXME: do we need is_disconnecing like on the psyc and multicast APIs?
/**
* Function called after disconnected from the service.
*/
};
+/*** CLEANUP / DISCONNECT ***/
+
+
+static void
+host_cleanup (struct GNUNET_SOCIAL_Host *hst)
+{
+ if (NULL != hst->slicer)
+ {
+ GNUNET_PSYC_slicer_destroy (hst->slicer);
+ hst->slicer = NULL;
+ }
+ GNUNET_free (hst);
+}
+
+
+static void
+guest_cleanup (struct GNUNET_SOCIAL_Guest *gst)
+{
+ GNUNET_free (gst);
+}
+
+
+static void
+place_cleanup (struct GNUNET_SOCIAL_Place *plc)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "cleaning up place %p\n",
+ plc);
+ if (NULL != plc->tmit)
+ {
+ GNUNET_PSYC_transmit_destroy (plc->tmit);
+ plc->tmit = NULL;
+ }
+ if (NULL != plc->connect_env)
+ {
+ GNUNET_MQ_discard (plc->connect_env);
+ plc->connect_env = NULL;
+ }
+ if (NULL != plc->mq)
+ {
+ GNUNET_MQ_destroy (plc->mq);
+ plc->mq = NULL;
+ }
+ if (NULL != plc->disconnect_cb)
+ {
+ plc->disconnect_cb (plc->disconnect_cls);
+ plc->disconnect_cb = NULL;
+ }
+
+ (GNUNET_YES == plc->is_host)
+ ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
+ : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
+}
+
+
+static void
+place_disconnect (struct GNUNET_SOCIAL_Place *plc)
+{
+ place_cleanup (plc);
+}
+
+
/*** NYM ***/
static struct GNUNET_SOCIAL_Nym *
struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&msg->slave_pub_key);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Host received method for message ID %" PRIu64 " from nym %s: %s\n",
message_id, GNUNET_h2s (&nym->pub_key_hash), method_name);
hst->notice_place_leave_env = GNUNET_PSYC_env_create ();
char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"_notice_place_leave: got method from nym %s (%s).\n",
GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
GNUNET_free (str);
if (NULL == hst->notice_place_leave_env)
return;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Host received modifier for _notice_place_leave message with ID %" PRIu64 ":\n"
"%c%s: %.*s\n",
message_id, oper, name, value_size, (const char *) value);
return;
char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&hst->notice_place_leave_nym->pub_key);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"_notice_place_leave: got EOM from nym %s (%s).\n",
GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
GNUNET_free (str);
{
struct GNUNET_SOCIAL_Host *hst = cls;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "handle_host_enter_request\n");
-
if (NULL == hst->answer_door_cb)
return;
}
-/*** CLEANUP / DISCONNECT ***/
-
-
-static void
-host_cleanup (struct GNUNET_SOCIAL_Host *hst)
-{
- if (NULL != hst->slicer)
- {
- GNUNET_PSYC_slicer_destroy (hst->slicer);
- hst->slicer = NULL;
- }
- GNUNET_free (hst);
-}
-
-
-static void
-guest_cleanup (struct GNUNET_SOCIAL_Guest *gst)
-{
- GNUNET_free (gst);
-}
-
-
-static void
-place_cleanup (struct GNUNET_SOCIAL_Place *plc)
-{
- struct GNUNET_HashCode place_pub_hash;
-
- GNUNET_CRYPTO_hash (&plc->pub_key, sizeof (plc->pub_key), &place_pub_hash);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "%s place cleanup: %s\n",
- GNUNET_YES == plc->is_host ? "host" : "guest",
- GNUNET_h2s (&place_pub_hash));
-
- if (NULL != plc->tmit)
- {
- GNUNET_PSYC_transmit_destroy (plc->tmit);
- plc->tmit = NULL;
- }
- if (NULL != plc->connect_env)
- {
- GNUNET_MQ_discard (plc->connect_env);
- plc->connect_env = NULL;
- }
- if (NULL != plc->mq)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "destroying MQ (place_cleanup)\n");
- GNUNET_MQ_destroy (plc->mq);
- plc->mq = NULL;
- }
- if (NULL != plc->disconnect_cb)
- {
- plc->disconnect_cb (plc->disconnect_cls);
- plc->disconnect_cb = NULL;
- }
-
- (GNUNET_YES == plc->is_host)
- ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
- : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
-}
-
-
+/**
+ * Handler for a #GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK message received
+ * from the social service.
+ *
+ * @param cls the place of type `struct GNUNET_SOCIAL_Place`
+ * @param msg the message received from the service
+ */
static void
-place_disconnect (struct GNUNET_SOCIAL_Place *plc)
+handle_place_leave_ack (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_HashCode place_pub_hash;
+ struct GNUNET_SOCIAL_Place *plc = cls;
- GNUNET_CRYPTO_hash (&plc->pub_key,
- sizeof (plc->pub_key),
- &place_pub_hash);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "place_disconnect, plc = %s\n",
- GNUNET_h2s (&place_pub_hash));
- place_cleanup (plc);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s left place %p\n",
+ plc->is_host ? "host" : "guest",
+ plc);
+ place_disconnect (plc);
}
}
if (NULL != plc->mq)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "destroying MQ (host_disconnected)\n");
GNUNET_MQ_destroy (plc->mq);
plc->mq = NULL;
}
GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK,
struct HostEnterAck,
hst),
+ GNUNET_MQ_hd_fixed_size (place_leave_ack,
+ GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
+ struct GNUNET_MessageHeader,
+ plc),
GNUNET_MQ_hd_var_size (host_enter_request,
GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
struct GNUNET_PSYC_JoinRequestMessage,
void *notify_data_cls,
enum GNUNET_SOCIAL_AnnounceFlags flags)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "PSYC_transmit_message for host, method: %s\n",
+ method_name);
if (GNUNET_OK ==
GNUNET_PSYC_transmit_message (hst->plc.tmit, method_name, env,
NULL, notify_data, notify_data_cls, flags))
}
-/**
- * Closure for #host_leave_cont.
- */
-struct HostLeaveContext
-{
- struct GNUNET_SOCIAL_Host *hst;
- GNUNET_ContinuationCallback disconnect_cb;
- void *disconnect_cb_cls;
-};
-
-
-/**
- * FIXME.
- */
-static void
-host_leave_cont (void *cls)
-{
- struct HostLeaveContext *hlc = cls;
-
- GNUNET_SOCIAL_host_disconnect (hlc->hst,
- hlc->disconnect_cb,
- hlc->disconnect_cb_cls);
- GNUNET_free (hlc);
-}
-
-
/**
* Stop hosting the home.
*
GNUNET_ContinuationCallback disconnect_cb,
void *cls)
{
- struct GNUNET_MessageHeader *msg;
struct GNUNET_MQ_Envelope *envelope;
- struct HostLeaveContext *hlc;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "GNUNET_SOCIAL_host_leave\n");
GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL,
GNUNET_SOCIAL_ANNOUNCE_NONE);
- envelope = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
- hlc = GNUNET_new (struct HostLeaveContext);
- hlc->hst = hst;
- hlc->disconnect_cb = disconnect_cb;
- hlc->disconnect_cb_cls = cls;
- GNUNET_MQ_notify_sent (envelope,
- &host_leave_cont,
- hlc);
+ hst->plc.disconnect_cb = disconnect_cb;
+ hst->plc.disconnect_cls = cls;
+ envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
GNUNET_MQ_send (hst->plc.mq,
envelope);
}
}
if (NULL != plc->mq)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "destroying MQ (guest_disconnected)\n");
GNUNET_MQ_destroy (plc->mq);
plc->mq = NULL;
}
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK,
struct GNUNET_PSYC_CountersResultMessage,
gst),
+ GNUNET_MQ_hd_fixed_size (place_leave_ack,
+ GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
+ struct GNUNET_MessageHeader,
+ plc),
GNUNET_MQ_hd_var_size (guest_enter_decision,
GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
struct GNUNET_PSYC_JoinDecisionMessage,
}
+struct ReconnectContext
+{
+ struct GNUNET_SOCIAL_Guest *guest;
+ int *result;
+ int64_t *max_message_id;
+ GNUNET_SOCIAL_GuestEnterCallback enter_cb;
+ void *enter_cls;
+};
+
+
+static void
+guest_enter_reconnect_cb (void *cls,
+ int result,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
+ uint64_t max_message_id)
+{
+ struct ReconnectContext *reconnect_ctx = cls;
+
+ GNUNET_assert (NULL != reconnect_ctx);
+ reconnect_ctx->result = GNUNET_new (int);
+ *(reconnect_ctx->result) = result;
+ reconnect_ctx->max_message_id = GNUNET_new (int64_t);
+ *(reconnect_ctx->max_message_id) = max_message_id;
+}
+
+
+static void
+guest_entry_dcsn_reconnect_cb (void *cls,
+ int is_admitted,
+ const struct GNUNET_PSYC_Message *entry_resp)
+{
+ struct ReconnectContext *reconnect_ctx = cls;
+ struct GNUNET_SOCIAL_Guest *gst = reconnect_ctx->guest;
+
+ GNUNET_assert (NULL != reconnect_ctx);
+ GNUNET_assert (NULL != reconnect_ctx->result);
+ GNUNET_assert (NULL != reconnect_ctx->max_message_id);
+ if (GNUNET_YES != is_admitted)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Guest was rejected after calling "
+ "GNUNET_SOCIAL_guest_enter_reconnect ()\n");
+ }
+ else if (NULL != reconnect_ctx->enter_cb)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "guest reconnected!\n");
+ reconnect_ctx->enter_cb (reconnect_ctx->enter_cls,
+ *(reconnect_ctx->result),
+ &gst->plc.pub_key,
+ *(reconnect_ctx->max_message_id));
+ }
+ GNUNET_free (reconnect_ctx->result);
+ GNUNET_free (reconnect_ctx->max_message_id);
+ GNUNET_free (reconnect_ctx);
+}
+
+
/**
* Reconnect to an already entered place as guest.
*
* Flags for the entry.
* @param slicer
* Slicer to use for processing incoming requests from guests.
- * @param local_enter_cb
- * Called upon connection established to the social service.
+ * @param enter_cb
+ * Called upon re-entering is complete.
* @param entry_decision_cb
* Called upon receiving entry decision.
*
GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn,
enum GNUNET_PSYC_SlaveJoinFlags flags,
struct GNUNET_PSYC_Slicer *slicer,
- GNUNET_SOCIAL_GuestEnterCallback local_enter_cb,
+ GNUNET_SOCIAL_GuestEnterCallback enter_cb,
void *cls)
{
struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst));
struct GNUNET_SOCIAL_Place *plc = &gst->plc;
+ struct ReconnectContext *reconnect_ctx;
uint16_t app_id_size = strlen (gconn->app->id) + 1;
struct GuestEnterRequest *greq;
plc->pub_key = gconn->plc_msg.place_pub_key;
plc->ego_pub_key = gconn->plc_msg.ego_pub_key;
- plc->op = GNUNET_OP_create ();
+ reconnect_ctx = GNUNET_new (struct ReconnectContext);
+ reconnect_ctx->guest = gst;
+ reconnect_ctx->enter_cb = enter_cb;
+ reconnect_ctx->enter_cls = cls;
- gst->enter_cb = local_enter_cb;
- gst->cb_cls = cls;
+ plc->op = GNUNET_OP_create ();
+ gst->enter_cb = &guest_enter_reconnect_cb;
+ gst->entry_dcsn_cb = &guest_entry_dcsn_reconnect_cb;
+ gst->cb_cls = reconnect_ctx;
guest_connect (gst);
return gst;
{
struct GNUNET_SOCIAL_Place *plc = &gst->plc;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "GNUNET_SOCIAL_guest_disconnect, gst = %p\n",
- gst);
plc->disconnect_cb = disconnect_cb;
plc->disconnect_cls = cls;
place_disconnect (plc);
}
-/**
- * Closure for #leave_done_cont.
- */
-struct LeaveContext
-{
- struct GNUNET_SOCIAL_Guest *gst;
- GNUNET_ContinuationCallback disconnect_cb;
- void *disconnect_cb_cls;
-};
-
-
-/**
- * The leave message was transmitted, now complete the
- * disconnection process.
- *
- * @param cls a `struct LeaveContext`
- */
-static void
-leave_done_cont (void *cls)
-{
- struct LeaveContext *lc = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "social_api: guest's place_leave message sent!\n");
- GNUNET_SOCIAL_guest_disconnect (lc->gst,
- lc->disconnect_cb,
- lc->disconnect_cb_cls);
- GNUNET_free (lc);
-}
-
-
/**
* Leave a place temporarily or permanently.
*
GNUNET_ContinuationCallback disconnect_cb,
void *cls)
{
- struct GNUNET_MessageHeader *msg;
struct GNUNET_MQ_Envelope *envelope;
- struct LeaveContext *lc;
GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL,
GNUNET_SOCIAL_TALK_NONE);
-
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "social_api: place_leave\n");
- envelope = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
- lc = GNUNET_new (struct LeaveContext);
- lc->gst = gst;
- lc->disconnect_cb = disconnect_cb;
- lc->disconnect_cb_cls = cls;
- GNUNET_MQ_notify_sent (envelope,
- &leave_done_cont,
- lc);
+ gst->plc.disconnect_cb = disconnect_cb;
+ gst->plc.disconnect_cls = cls;
+ envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
GNUNET_MQ_send (gst->plc.mq,
envelope);
}
GNUNET_ContinuationCallback disconnect_cb,
void *disconnect_cls)
{
+ if (NULL == app) return;
+
app->disconnect_cb = disconnect_cb;
app->disconnect_cls = disconnect_cls;