uint8_t is_ready;
/**
- * Is the client disconnected?
+ * Is the client disconnecting?
* #GNUNET_YES or #GNUNET_NO
*/
- uint8_t is_disconnected;
+ uint8_t is_disconnecting;
/**
* Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)?
/**
* Join request to be transmitted to the master on join.
*/
- struct GNUNET_MessageHeader *join_req;
+ struct GNUNET_MessageHeader *join_req; // FIXME: not used!
/**
* Join decision received from PSYC.
{
struct Place *plc = &hst->place;
- if (NULL != hst->master)
- GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME
GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs);
GNUNET_CONTAINER_multihashmap_destroy (hst->relay_msgs);
GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc);
struct GNUNET_CONTAINER_MultiHashMap *
plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests,
&plc->pub_key_hash);
- GNUNET_assert (NULL != plc_gst); // FIXME
+ GNUNET_assert (NULL != plc_gst);
GNUNET_CONTAINER_multihashmap_remove (plc_gst, &plc->ego_pub_hash, gst);
if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst))
GNUNET_free (gst->join_req);
if (NULL != gst->relays)
GNUNET_free (gst->relays);
- if (NULL != gst->slave)
- GNUNET_PSYC_slave_part (gst->slave, GNUNET_NO, NULL, NULL); // FIXME
GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, plc);
}
{
struct Place *plc = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "cleaning up place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
+
(GNUNET_YES == plc->is_host)
? cleanup_host ((struct Host *) plc)
: cleanup_guest ((struct Guest *) plc);
if (NULL != c->app_id)
GNUNET_free (c->app_id);
+
GNUNET_free (c);
if (NULL == plc)
plc, (GNUNET_YES == plc->is_host) ? "host" : "guest",
GNUNET_h2s (&plc->pub_key_hash));
- // FIXME (due to protocol change): here we must not remove all clients,
- // only the one we were notified about!
struct ClientListItem *cli = plc->clients_head;
while (NULL != cli)
{
}
cli = cli->next;
}
+ if (GNUNET_YES == plc->is_disconnecting)
+ {
+ GNUNET_PSYC_slicer_destroy (plc->slicer);
+ GNUNET_free (plc);
+ }
}
"%p Sending message to clients of place.\n", plc);
while (NULL != cli)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending message to client %p\n",
+ cli);
GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
env);
cli = cli->next;
static void
-place_send_leave_ack (const struct Place *plc)
+place_send_leave_ack (struct Place *plc)
{
struct GNUNET_MQ_Envelope *env;
struct GNUNET_MQ_Envelope *env;
struct Guest *gst = cls;
struct Place *plc = &gst->place;
-
+
plc->max_message_id = max_message_id;
plc->is_ready = GNUNET_YES;
env = GNUNET_MQ_msg (res,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
- res->result_code = htonl (result);
+ res->result_code =
+ (result != GNUNET_SYSERR) ? htonl (GNUNET_OK) : htonl (GNUNET_SYSERR);
res->max_message_id = GNUNET_htonll (plc->max_message_id);
place_send_msg (plc, env);
}
+static void
+slave_parted_after_join_decision (void *cls)
+{
+ struct Guest *gst = cls;
+
+ GNUNET_assert (NULL != gst->join_dcsn);
+ place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
+}
+
+
/**
* Called when a PSYC slave receives a join decision.
*/
const struct GNUNET_PSYC_Message *join_msg)
{
struct Guest *gst = cls;
- place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&dcsn->header));
+
+ gst->join_dcsn = GNUNET_malloc (dcsn->header.size);
+ GNUNET_memcpy (gst->join_dcsn,
+ dcsn,
+ dcsn->header.size);
+ if (GNUNET_NO == is_admitted)
+ {
+ GNUNET_PSYC_slave_part (gst->slave,
+ GNUNET_NO,
+ &slave_parted_after_join_decision,
+ gst);
+ gst->slave = NULL;
+ return;
+ }
+ place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
}
static int
place_add (const struct PlaceEnterRequest *ereq)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding place to hashmap:\n");
-
struct EgoPlacePublicKey ego_place_pub_key = {
.ego_pub_key = ereq->ego_pub_key,
.place_pub_key = ereq->place_pub_key,
return GNUNET_SYSERR;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "entering as guest\n");
struct GNUNET_HashCode place_pub_hash;
GNUNET_CRYPTO_hash (&greq->place_pub_key, sizeof (greq->place_pub_key),
&place_pub_hash);
if (NULL != plc_gst)
gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &ego_pub_hash);
- if (NULL == gst || NULL == gst->slave)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "plc_gst = %p, gst = %p\n",
+ plc_gst,
+ gst);
+ if (NULL == gst)
{
gst = GNUNET_new (struct Guest);
+ }
+ if (NULL == gst->slave)
+ {
gst->origin = greq->origin;
gst->relay_count = ntohl (greq->relay_count);
plc_gst = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
(void) GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- }
- (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
+ (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+
+ }
gst->slave
= GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &plc->ego_key,
gst->join_flags, &gst->origin,
&psyc_recv_join_dcsn,
gst, join_msg);
plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "slave entered channel %p\n",
+ plc->channel);
ret = GNUNET_YES;
}
client_guest_enter (struct Client *c,
const struct GuestEnterRequest *greq)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "client_guest_enter\n");
struct GNUNET_PSYC_CountersResultMessage *result_msg;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_SERVICE_Client *client = c->client;
switch (guest_enter (greq, &gst))
{
case GNUNET_YES:
+ {
plc = c->place = &gst->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "guest entered successfully to local place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
plc->guest = gst;
app_place_save (app_id, (const struct PlaceEnterRequest *) greq);
app_notify_place (&greq->header, client);
break;
-
+ }
case GNUNET_NO:
{
plc = c->place = &gst->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "guest re-entered successfully to local place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
plc->guest = gst;
env = GNUNET_MQ_msg (result_msg,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
break;
}
case GNUNET_SYSERR:
+ {
return GNUNET_SYSERR;
}
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%p Client connected as guest to place %s.\n",
- gst, GNUNET_h2s (&plc->pub_key_hash));
+ }
struct ClientListItem *cli = GNUNET_new (struct ClientListItem);
cli->client = client;
}
+static void
+place_leave_cb (void *cls)
+{
+ struct Place *plc = cls;
+
+ place_send_leave_ack (plc);
+ (GNUNET_YES == plc->is_host)
+ ? cleanup_host ((struct Host *) plc)
+ : cleanup_guest ((struct Guest *) plc);
+}
+
+
/**
* Handle application leave request.
*/
struct GNUNET_SERVICE_Client *client = c->client;
struct Place *plc = c->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "got leave request from %s for place %s",
+ plc->is_host? "host" : "slave",
+ GNUNET_h2s (&plc->pub_key_hash));
if (NULL == plc)
{
GNUNET_break (0);
return;
}
- if (GNUNET_YES != plc->is_disconnected)
+ if (GNUNET_YES != plc->is_disconnecting)
{
- plc->is_disconnected = GNUNET_YES;
- if (NULL != plc->tmit_msgs_head)
- { /* Send pending messages to PSYC before cleanup. */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "not cleaning up place of client %p\n",
- client);
- psyc_transmit_message (plc);
+ plc->is_disconnecting = GNUNET_YES;
+ if (plc->is_host)
+ {
+ struct Host *host = plc->host;
+ GNUNET_assert (NULL != host);
+ GNUNET_PSYC_master_stop (host->master, GNUNET_NO, &place_leave_cb, plc);
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "cleaning up place of client %p\n",
- client);
- place_send_leave_ack (plc);
- cleanup_place (plc);
- c->place = NULL;
+ struct Guest *guest = plc->guest;
+ GNUNET_assert (NULL != guest);
+ GNUNET_PSYC_slave_part (guest->slave, GNUNET_NO, &place_leave_cb, plc);
}
}
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "got leave request but place is already leaving\n");
+ }
GNUNET_SERVICE_client_continue (client);
}
? (struct GNUNET_PSYC_Message *) &dcsn[1]
: NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "jcls.msg = %p\n",
+ jcls.msg);
struct GNUNET_HashCode slave_pub_hash;
GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key),
&slave_pub_hash);
struct GNUNET_MQ_Envelope *env;
env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "sending psyc message ack to client %p, mq = %p\n",
- client,
- GNUNET_SERVICE_client_get_mq (client));
GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
env);
}
{
*data_size = 0;
tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
- plc->is_disconnected = GNUNET_YES;
GNUNET_SERVICE_client_drop (tmit_frag->client);
GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
return ret;
{
psyc_transmit_message (plc);
}
- else if (GNUNET_YES == plc->is_disconnected)
- {
- /* FIXME: handle partial message (when still in_transmit) */
- cleanup_place (plc);
- }
+ /* FIXME: handle partial message (when still in_transmit) */
}
return ret;
}
*data_size = 0;
ret = GNUNET_SYSERR;
tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
- plc->is_disconnected = GNUNET_YES;
GNUNET_SERVICE_client_drop (tmit_frag->client);
GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
}
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%p Received message from client.\n", plc);
+ "%p Received message of type %d from client.\n", plc, ntohs (msg->type));
GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, msg);
if (GNUNET_YES != plc->is_ready)
enum GNUNET_SOCIAL_AnnounceFlags flags)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "PSYC_transmit_message for host\n");
+ "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))
{
struct GNUNET_MQ_Envelope *envelope;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "sending _notice_place_closing\n");
GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL,
GNUNET_SOCIAL_ANNOUNCE_NONE);
hst->plc.disconnect_cb = disconnect_cb;
}
+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.
*
plc->ego_pub_key = gconn->plc_msg.ego_pub_key;
plc->op = GNUNET_OP_create ();
-
gst->enter_cb = local_enter_cb;
gst->cb_cls = cls;
void *notify_data_cls,
enum GNUNET_SOCIAL_TalkFlags flags)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "PSYC_transmit_message for guest\n");
-
struct GNUNET_SOCIAL_Place *plc = &gst->plc;
GNUNET_assert (NULL != plc->tmit);