+ reschedule_connect (h);
+ return;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received message of type %d from identity service\n",
+ ntohs (msg->type));
+ size = ntohs (msg->size);
+ switch (ntohs (msg->type))
+ {
+ case GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE:
+ if (size < sizeof (struct GNUNET_IDENTITY_ResultCodeMessage))
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ rcm = (const struct GNUNET_IDENTITY_ResultCodeMessage *) msg;
+ str = (const char *) &rcm[1];
+ if ( (size > sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) &&
+ ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) - 1]) )
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ if (size == sizeof (struct GNUNET_IDENTITY_ResultCodeMessage))
+ str = NULL;
+
+ op = h->op_head;
+ GNUNET_CONTAINER_DLL_remove (h->op_head,
+ h->op_tail,
+ op);
+ if (NULL != op->cont)
+ op->cont (op->cls,
+ str);
+ else if (NULL != op->cb)
+ op->cb (op->cls, NULL, NULL, NULL);
+ GNUNET_free (op);
+ break;
+ case GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE:
+ if (size < sizeof (struct GNUNET_IDENTITY_UpdateMessage))
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ um = (const struct GNUNET_IDENTITY_UpdateMessage *) msg;
+ name_len = ntohs (um->name_len);
+
+ str = (const char *) &um[1];
+ if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_UpdateMessage)) ||
+ ( (0 != name_len) &&
+ ('\0' != str[name_len - 1])) )
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ if (GNUNET_YES == ntohs (um->end_of_list))
+ {
+ /* end of initial list of data */
+ if (NULL != h->cb)
+ h->cb (h->cb_cls, NULL, NULL, NULL);
+ break;
+ }
+ GNUNET_CRYPTO_ecc_key_get_public (&um->private_key,
+ &pub);
+ GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id);
+ if (0 == name_len)
+ str = NULL;
+ else
+ str = (const char *) &um[1];
+ ego = GNUNET_CONTAINER_multihashmap_get (h->egos,
+ &id);
+ if (NULL == ego)
+ {
+ /* ego was created */
+ if (NULL == str)
+ {
+ /* deletion of unknown ego? not allowed */
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ ego = GNUNET_new (struct GNUNET_IDENTITY_Ego);
+ ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey);
+ *ego->pk = um->private_key;
+ ego->name = GNUNET_strdup (str);
+ ego->id = id;
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_put (h->egos,
+ &ego->id,
+ ego,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ }
+ /* inform application about change */
+ if (NULL != h->cb)
+ h->cb (h->cb_cls,
+ ego,
+ &ego->ctx,
+ str);
+ if (NULL == str)
+ {
+ /* ego was deleted */
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove (h->egos,
+ &ego->id,
+ ego));
+ GNUNET_free (ego->pk);
+ GNUNET_free (ego->name);
+ GNUNET_free (ego);
+ }
+ else
+ {
+ /* ego changed name */
+ GNUNET_free (ego->name);
+ ego->name = GNUNET_strdup (str);
+ }
+ break;
+ case GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT:
+ if (size < sizeof (struct GNUNET_IDENTITY_SetDefaultMessage))
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) msg;
+ GNUNET_break (0 == ntohs (sdm->reserved));
+ name_len = ntohs (sdm->name_len);
+ str = (const char *) &sdm[1];
+ if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) ||
+ ( (0 != name_len) &&
+ ('\0' != str[name_len - 1]) ) )
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ /* Note: we know which service this should be for, so we're not
+ really using 'str' henceforth */
+ GNUNET_CRYPTO_ecc_key_get_public (&sdm->private_key,
+ &pub);
+ GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id);
+ ego = GNUNET_CONTAINER_multihashmap_get (h->egos,
+ &id);
+ if (NULL == ego)
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ op = h->op_head;
+ GNUNET_CONTAINER_DLL_remove (h->op_head,
+ h->op_tail,
+ op);
+ GNUNET_free (ego->name);
+ if (NULL != op->cb)
+ op->cb (op->cls,
+ ego,
+ &ego->ctx,
+ ego->name);
+ GNUNET_free (op);
+ break;
+ default:
+ GNUNET_break (0);
+ reschedule_connect (h);