- struct GNUNET_DV_SendMessage *send_msg;
- struct GNUNET_DV_SendResultMessage *send_result_msg;
- struct PendingMessage *pending_message;
- size_t address_len;
- size_t message_size;
- struct GNUNET_PeerIdentity *destination;
- struct GNUNET_PeerIdentity *direct;
- struct GNUNET_MessageHeader *message_buf;
- char *temp_pos;
- int offset;
- static struct GNUNET_CRYPTO_HashAsciiEncoded dest_hash;
- struct DV_SendContext *send_context;
-#if DEBUG_DV_MESSAGES
- char *cbuf;
- struct GNUNET_MessageHeader *packed_message;
-#endif
-
- if (client_handle == NULL)
- {
- client_handle = client;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Setting initial client handle, never received `%s' message?\n", "dv", "START");
- }
- else if (client_handle != client)
- {
- client_handle = client;
- /* What should we do in this case, assert fail or just log the warning? */
-#if DEBUG_DV
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Setting client handle (was a different client!)!\n", "dv");
-#endif
- }
-
- GNUNET_assert(ntohs(message->size) > sizeof(struct GNUNET_DV_SendMessage));
- send_msg = (struct GNUNET_DV_SendMessage *)message;
-
- address_len = ntohl(send_msg->addrlen);
- GNUNET_assert(address_len == sizeof(struct GNUNET_PeerIdentity) * 2);
- message_size = ntohs(message->size) - sizeof(struct GNUNET_DV_SendMessage) - address_len;
- destination = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
- direct = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
- message_buf = GNUNET_malloc(message_size);
-
- temp_pos = (char *)&send_msg[1]; /* Set pointer to end of message */
- offset = 0; /* Offset starts at zero */
-
- memcpy(destination, &temp_pos[offset], sizeof(struct GNUNET_PeerIdentity));
- offset += sizeof(struct GNUNET_PeerIdentity);
-
- memcpy(direct, &temp_pos[offset], sizeof(struct GNUNET_PeerIdentity));
- offset += sizeof(struct GNUNET_PeerIdentity);
-
-
- memcpy(message_buf, &temp_pos[offset], message_size);
- if (memcmp(&send_msg->target, destination, sizeof(struct GNUNET_PeerIdentity)) != 0)
- {
- GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */
- dest_hash.encoding[4] = '\0';
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: asked to send message to `%s', but address is for `%s'!", "DV SERVICE", GNUNET_i2s(&send_msg->target), (const char *)&dest_hash.encoding);
- }
-
-#if DEBUG_DV_MESSAGES
- cbuf = (char *)message_buf;
- offset = 0;
- while(offset < message_size)
- {
- packed_message = (struct GNUNET_MessageHeader *)&cbuf[offset];
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: DV PLUGIN SEND uid %u type %d to %s\n", my_short_id, ntohl(send_msg->uid), ntohs(packed_message->type), GNUNET_i2s(destination));
- offset += ntohs(packed_message->size);
- }
- /*GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: DV PLUGIN SEND uid %u type %d to %s\n", my_short_id, ntohl(send_msg->uid), ntohs(message_buf->type), GNUNET_i2s(destination));*/
-#endif
- GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */
- dest_hash.encoding[4] = '\0';
- send_context = GNUNET_malloc(sizeof(struct DV_SendContext));
-
- send_result_msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendResultMessage));
- send_result_msg->header.size = htons(sizeof(struct GNUNET_DV_SendResultMessage));
- send_result_msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT);
- send_result_msg->uid = send_msg->uid; /* No need to ntohl->htonl this */
-
- send_context->importance = ntohl(send_msg->priority);
- send_context->timeout = send_msg->timeout;
- send_context->direct_peer = direct;
- send_context->distant_peer = destination;
- send_context->message = message_buf;
- send_context->message_size = message_size;
- send_context->send_result = send_result_msg;
-#if DEBUG_DV_MESSAGES
- send_context->uid = send_msg->uid;
-#endif
-
- if (send_message_via(&my_identity, direct, send_context) != GNUNET_YES)
- {
- send_result_msg->result = htons(1);
- pending_message = GNUNET_malloc(sizeof(struct PendingMessage) + sizeof(struct GNUNET_DV_SendResultMessage));
- pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
- memcpy(&pending_message[1], send_result_msg, sizeof(struct GNUNET_DV_SendResultMessage));
- GNUNET_free(send_result_msg);
-
- GNUNET_CONTAINER_DLL_insert_after(plugin_pending_head, plugin_pending_tail, plugin_pending_tail, pending_message);
-
- if (client_handle != NULL)
- {
- if (plugin_transmit_handle == NULL)
- {
- plugin_transmit_handle = GNUNET_SERVER_notify_transmit_ready (client_handle,
- sizeof(struct GNUNET_DV_SendResultMessage),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &transmit_to_plugin, NULL);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to queue message for plugin, must be one in progress already!!\n");
- }
- }
- GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */
- dest_hash.encoding[4] = '\0';
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s DV SEND failed to send message to destination `%s' via `%s'\n", my_short_id, (const char *)&dest_hash.encoding, GNUNET_i2s(direct));
- }
-
- /* In bizarro world GNUNET_SYSERR indicates that we succeeded */
-#if UNSIMPLER
- if (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple(extended_neighbors, &destination->hashPubKey, &send_iterator, send_context))
- {
- send_result_msg->result = htons(1);
- pending_message = GNUNET_malloc(sizeof(struct PendingMessage) + sizeof(struct GNUNET_DV_SendResultMessage));
- pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
- memcpy(&pending_message[1], send_result_msg, sizeof(struct GNUNET_DV_SendResultMessage));
- GNUNET_free(send_result_msg);
-
- GNUNET_CONTAINER_DLL_insert_after(plugin_pending_head, plugin_pending_tail, plugin_pending_tail, pending_message);
-
- if (client_handle != NULL)
- {
- if (plugin_transmit_handle == NULL)
- {
- plugin_transmit_handle = GNUNET_SERVER_notify_transmit_ready (client_handle,
- sizeof(struct GNUNET_DV_SendResultMessage),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &transmit_to_plugin, NULL);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to queue message for plugin, must be one in progress already!!\n");
- }
- }
- GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */
- dest_hash.encoding[4] = '\0';
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s DV SEND failed to send message to destination `%s' via `%s'\n", my_short_id, (const char *)&dest_hash.encoding, GNUNET_i2s(direct));
- }
-#endif
- GNUNET_free(message_buf);
- GNUNET_free(send_context);
- GNUNET_free(direct);
- GNUNET_free(destination);
-
- GNUNET_SERVER_receive_done(client, GNUNET_OK);