[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r26393 - gnunet/src/dv
From: |
gnunet |
Subject: |
[GNUnet-SVN] r26393 - gnunet/src/dv |
Date: |
Tue, 12 Mar 2013 20:32:02 +0100 |
Author: grothoff
Date: 2013-03-12 20:32:02 +0100 (Tue, 12 Mar 2013)
New Revision: 26393
Modified:
gnunet/src/dv/dv_api.c
gnunet/src/dv/gnunet-service-dv.c
Log:
-removing useless parts of old code, work on DHT API
Modified: gnunet/src/dv/dv_api.c
===================================================================
--- gnunet/src/dv/dv_api.c 2013-03-12 14:23:57 UTC (rev 26392)
+++ gnunet/src/dv/dv_api.c 2013-03-12 19:32:02 UTC (rev 26393)
@@ -39,18 +39,39 @@
*/
struct GNUNET_DV_TransmitHandle
{
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_DV_TransmitHandle *next;
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_DV_TransmitHandle *prev;
+ /**
+ * Handle to the service.
+ */
struct GNUNET_DV_ServiceHandle *sh;
+ /**
+ * Function to call upon completion.
+ */
GNUNET_DV_MessageSentCallback cb;
+ /**
+ * Closure for 'cb'.
+ */
void *cb_cls;
+ /**
+ * The actual message (allocated at the end of this struct).
+ */
const struct GNUNET_MessageHeader *msg;
+ /**
+ * Destination for the message.
+ */
struct GNUNET_PeerIdentity target;
};
@@ -62,413 +83,132 @@
struct GNUNET_DV_ServiceHandle
{
- struct GNUNET_ClientHandle *client;
-
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- void *cls;
-
- GNUNET_DV_ConnectCallback connect_cb;
-
- GNUNET_DV_DisconnectCallback disconnect_cb;
-
- GNUNET_DV_MessageReceivedCallback message_cb;
-
- struct GNUNET_DV_TransmitHandle *th_head;
-
- struct GNUNET_DV_TransmitHandle *th_tail;
-
-};
-
-
-/**
- * Connect to the DV service.
- *
- * @param cfg configuration
- * @param cls closure for callbacks
- * @param connect_cb function to call on connects
- * @param disconnect_cb function to call on disconnects
- * @param message_cb function to call if we receive messages
- * @return handle to access the service
- */
-struct GNUNET_DV_ServiceHandle *
-GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- void *cls,
- GNUNET_DV_ConnectCallback connect_cb,
- GNUNET_DV_DisconnectCallback disconnect_cb,
- GNUNET_DV_MessageReceivedCallback message_cb)
-{
- GNUNET_break (0);
- return NULL;
-}
-
-
-/**
- * Disconnect from DV service.
- *
- * @param sh service handle
- */
-void
-GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
-{
- GNUNET_break (0);
-}
-
-
-
-/**
- * Send a message via DV service.
- *
- * @param sh service handle
- * @param target intended recpient
- * @param msg message payload
- * @param cb function to invoke when done
- * @param cb_cls closure for 'cb'
- * @return handle to cancel the operation
- */
-struct GNUNET_DV_TransmitHandle *
-GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh,
- const struct GNUNET_PeerIdentity *target,
- const struct GNUNET_MessageHeader *msg,
- GNUNET_DV_MessageSentCallback cb,
- void *cb_cls)
-{
- GNUNET_break (0);
- return NULL;
-}
-
-
-/**
- * Abort send operation (naturally, the message may have
- * already been transmitted; this only stops the 'cb'
- * from being called again).
- *
- * @param th send operation to cancel
- */
-void
-GNUNET_DV_send_cancel (struct GNUNET_DV_TransmitHandle *th)
-{
- GNUNET_break (0);
-}
-
-
-
-#if 0
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Store ready to send messages
- */
-struct PendingMessages
-{
/**
- * Linked list of pending messages
+ * Connection to DV service.
*/
- struct PendingMessages *next;
+ struct GNUNET_CLIENT_Connection *client;
/**
- * Message that is pending
+ * Active request for transmission to DV service.
*/
- struct GNUNET_DV_SendMessage *msg;
+ struct GNUNET_CLIENT_TransmitHandle *th;
/**
- * Timeout for this message
+ * Our configuration.
*/
- struct GNUNET_TIME_Absolute timeout;
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
-};
-
-/**
- * Handle for the service.
- */
-struct GNUNET_DV_Handle
-{
-
/**
- * Configuration to use.
+ * Closure for the callbacks.
*/
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
+ void *cls;
+
/**
- * Socket (if available).
+ * Function to call on connect events.
*/
- struct GNUNET_CLIENT_Connection *client;
+ GNUNET_DV_ConnectCallback connect_cb;
/**
- * Currently pending transmission request.
+ * Function to call on disconnect events.
*/
- struct GNUNET_CLIENT_TransmitHandle *th;
+ GNUNET_DV_DisconnectCallback disconnect_cb;
/**
- * List of the currently pending messages for the DV service.
+ * Function to call on receiving messages events.
*/
- struct PendingMessages *pending_list;
+ GNUNET_DV_MessageReceivedCallback message_cb;
/**
- * Message we are currently sending.
+ * Head of messages to transmit.
*/
- struct PendingMessages *current;
+ struct GNUNET_DV_TransmitHandle *th_head;
/**
- * Handler for messages we receive from the DV service
+ * Tail of messages to transmit.
*/
- GNUNET_DV_MessageReceivedHandler receive_handler;
+ struct GNUNET_DV_TransmitHandle *th_tail;
/**
- * Closure for the receive handler
+ * Mapping of peer identities to TransmitHandles to invoke
+ * upon successful transmission. The respective
+ * transmissions have already been done.
*/
- void *receive_cls;
+ struct GNUNET_CONTAINER_MultiHashMap *send_callbacks;
/**
* Current unique ID
*/
uint32_t uid_gen;
- /**
- * Hashmap containing outstanding send requests awaiting confirmation.
- */
- struct GNUNET_CONTAINER_MultiHashMap *send_callbacks;
-
};
-struct StartContext
-{
- /**
- * Start message
- */
- struct GNUNET_MessageHeader *message;
-
- /**
- * Handle to service, in case of timeout
- */
- struct GNUNET_DV_Handle *handle;
-};
-
-struct SendCallbackContext
-{
- /**
- * The continuation to call once a message is confirmed sent (or failed)
- */
- GNUNET_TRANSPORT_TransmitContinuation cont;
-
- /**
- * Closure to call with send continuation.
- */
- void *cont_cls;
-
- /**
- * Target of the message.
- */
- struct GNUNET_PeerIdentity target;
-
- /**
- * Payload size in bytes
- */
- size_t payload_size;
-
- /**
- * DV message size
- */
- size_t msg_size;
-};
-
/**
- * Convert unique ID to hash code.
+ * Disconnect and then reconnect to the DV service.
*
- * @param uid unique ID to convert
- * @param hash set to uid (extended with zeros)
+ * @param sh service handle
*/
static void
-hash_from_uid (uint32_t uid, struct GNUNET_HashCode * hash)
-{
- memset (hash, 0, sizeof (struct GNUNET_HashCode));
- *((uint32_t *) hash) = uid;
-}
+reconnect (struct GNUNET_DV_ServiceHandle *sh);
-/**
- * Try to (re)connect to the dv service.
- *
- * @param ret handle to the (disconnected) dv service
- *
- * @return GNUNET_YES on success, GNUNET_NO on failure.
- */
-static int
-try_connect (struct GNUNET_DV_Handle *ret)
-{
- if (ret->client != NULL)
- return GNUNET_OK;
- ret->client = GNUNET_CLIENT_connect ("dv", ret->cfg);
- if (ret->client != NULL)
- return GNUNET_YES;
-#if DEBUG_DV_MESSAGES
- LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failed to connect to the dv service!\n"));
-#endif
- return GNUNET_NO;
-}
-static void
-process_pending_message (struct GNUNET_DV_Handle *handle);
-
/**
- * Send complete, schedule next
+ * Gives a message from our queue to the DV service.
*
- * @param handle handle to the dv service
- * @param code return code for send (unused)
- */
-static void
-finish (struct GNUNET_DV_Handle *handle, int code)
-{
- struct PendingMessages *pos = handle->current;
-
- handle->current = NULL;
- process_pending_message (handle);
-
- GNUNET_free (pos->msg);
- GNUNET_free (pos);
-}
-
-/**
- * Notification that we can send data
- *
- * @param cls handle to the dv service (struct GNUNET_DV_Handle)
+ * @param cls handle to the dv service (struct GNUNET_DV_ServiceHandle)
* @param size how many bytes can we send
* @param buf where to copy the message to send
- *
* @return how many bytes we copied to buf
*/
static size_t
transmit_pending (void *cls, size_t size, void *buf)
{
- struct GNUNET_DV_Handle *handle = cls;
+ struct GNUNET_DV_ServiceHandle *sh = cls;
size_t ret;
size_t tsize;
-#if DEBUG_DV
- if (handle->current != NULL)
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "DV API: Transmit pending called with message type %d\n",
- ntohs (handle->current->msg->header.type));
-#endif
-
- if (buf == NULL)
+ sh->th = NULL;
+ if (NULL == buf)
{
-#if DEBUG_DV
- LOG (GNUNET_ERROR_TYPE_DEBUG, "DV API: Transmit pending FAILED!\n\n\n");
-#endif
- finish (handle, GNUNET_SYSERR);
+ reconnect (sh);
return 0;
}
- handle->th = NULL;
-
ret = 0;
-
- if (handle->current != NULL)
+ // FIXME: yuck! -- copy multiple, remove from DLL, and add to hash map!
+ if (NULL != sh->th_head)
{
- tsize = ntohs (handle->current->msg->header.size);
+ tsize = ntohs (sh->th_head->msg->size);
if (size >= tsize)
{
- memcpy (buf, handle->current->msg, tsize);
-#if DEBUG_DV
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "DV API: Copied %d bytes into buffer!\n\n\n", tsize);
-#endif
- finish (handle, GNUNET_OK);
+ memcpy (buf, sh->th_head->msg, tsize);
return tsize;
}
-
}
-
return ret;
}
+
/**
- * Try to send messages from list of messages to send
+ * Start sending messages from our queue to the service.
*
- * @param handle handle to the distance vector service
+ * @param sh service handle
*/
static void
-process_pending_message (struct GNUNET_DV_Handle *handle)
+start_transmit (struct GNUNET_DV_ServiceHandle *sh)
{
-
- if (handle->current != NULL)
- return; /* action already pending */
- if (GNUNET_YES != try_connect (handle))
- {
- finish (handle, GNUNET_SYSERR);
+ if (NULL != sh->th)
return;
- }
-
- /* schedule next action */
- handle->current = handle->pending_list;
- if (NULL == handle->current)
- {
- return;
- }
- handle->pending_list = handle->pending_list->next;
- handle->current->next = NULL;
-
- if (NULL ==
- (handle->th =
- GNUNET_CLIENT_notify_transmit_ready (handle->client,
- ntohs (handle->current->msg->
- header.size),
- handle->current->msg->timeout,
- GNUNET_YES, &transmit_pending,
- handle)))
- {
-#if DEBUG_DV
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to transmit request to dv service.\n");
-#endif
- finish (handle, GNUNET_SYSERR);
- }
+ if (NULL == sh->th_head)
+ return;
+ sh->th =
+ GNUNET_CLIENT_notify_transmit_ready (sh->client,
+ ntohs (sh->th_head->msg->size),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_NO,
+ &transmit_pending, sh);
}
-/**
- * Add a pending message to the linked list
- *
- * @param handle handle to the specified DV api
- * @param msg the message to add to the list
- */
-static void
-add_pending (struct GNUNET_DV_Handle *handle, struct GNUNET_DV_SendMessage
*msg)
-{
- struct PendingMessages *new_message;
- struct PendingMessages *pos;
- struct PendingMessages *last;
- new_message = GNUNET_malloc (sizeof (struct PendingMessages));
- new_message->msg = msg;
-
- if (handle->pending_list != NULL)
- {
- pos = handle->pending_list;
- while (pos != NULL)
- {
- last = pos;
- pos = pos->next;
- }
- last->next = new_message;
- }
- else
- {
- handle->pending_list = new_message;
- }
-
- process_pending_message (handle);
-}
-
/**
* Handles a message sent from the DV service to us.
* Parse it out and give it to the plugin.
@@ -476,295 +216,255 @@
* @param cls the handle to the DV API
* @param msg the message that was received
*/
-void
-handle_message_receipt (void *cls, const struct GNUNET_MessageHeader *msg)
+static void
+handle_message_receipt (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_DV_Handle *handle = cls;
- struct GNUNET_DV_MessageReceived *received_msg;
- struct GNUNET_DV_SendResultMessage *send_result_msg;
- size_t packed_msg_len;
- size_t sender_address_len;
- char *sender_address;
- char *packed_msg;
- char *packed_msg_start;
- struct GNUNET_HashCode uidhash;
- struct SendCallbackContext *send_ctx;
+ struct GNUNET_DV_ServiceHandle *sh = cls;
+ const struct GNUNET_DV_ConnectMessage *cm;
+ const struct GNUNET_DV_DisconnectMessage *dm;
+ const struct GNUNET_DV_ReceivedMessage *rm;
- if (msg == NULL)
+ if (NULL == msg)
{
-#if DEBUG_DV_MESSAGES
- LOG (GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: connection closed\n");
-#endif
- return; /* Connection closed? */
+ /* Connection closed */
+ reconnect (sh);
+ return;
}
-
- GNUNET_assert ((ntohs (msg->type) ==
GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE)
- || (ntohs (msg->type) ==
- GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT));
-
switch (ntohs (msg->type))
{
- case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE:
- if (ntohs (msg->size) < sizeof (struct GNUNET_DV_MessageReceived))
+ case GNUNET_MESSAGE_TYPE_DV_CONNECT:
+ if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ConnectMessage))
+ {
+ GNUNET_break (0);
+ reconnect (sh);
return;
-
- received_msg = (struct GNUNET_DV_MessageReceived *) msg;
- packed_msg_len = ntohl (received_msg->msg_len);
- sender_address_len =
- ntohs (msg->size) - packed_msg_len -
- sizeof (struct GNUNET_DV_MessageReceived);
- GNUNET_assert (sender_address_len > 0);
- sender_address = GNUNET_malloc (sender_address_len);
- memcpy (sender_address, &received_msg[1], sender_address_len);
- packed_msg_start = (char *) &received_msg[1];
- packed_msg = GNUNET_malloc (packed_msg_len);
- memcpy (packed_msg, &packed_msg_start[sender_address_len], packed_msg_len);
-
-#if DEBUG_DV_MESSAGES
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "DV_API receive: packed message type: %d or %d\n",
- ntohs (((struct GNUNET_MessageHeader *) packed_msg)->type),
- ((struct GNUNET_MessageHeader *) packed_msg)->type);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "DV_API receive: message sender reported as %s\n",
- GNUNET_i2s (&received_msg->sender));
- LOG (GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: distance is %u\n",
- ntohl (received_msg->distance));
-#endif
-
- handle->receive_handler (handle->receive_cls, &received_msg->sender,
- packed_msg, packed_msg_len,
- ntohl (received_msg->distance), sender_address,
- sender_address_len);
-
- GNUNET_free (sender_address);
+ }
+ cm = (const struct GNUNET_DV_ConnectMessage *) msg;
+ // FIXME
break;
- case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT:
- if (ntohs (msg->size) < sizeof (struct GNUNET_DV_SendResultMessage))
+ case GNUNET_MESSAGE_TYPE_DV_DISCONNECT:
+ if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage))
+ {
+ GNUNET_break (0);
+ reconnect (sh);
return;
-
- send_result_msg = (struct GNUNET_DV_SendResultMessage *) msg;
- hash_from_uid (ntohl (send_result_msg->uid), &uidhash);
- send_ctx =
- GNUNET_CONTAINER_multihashmap_get (handle->send_callbacks, &uidhash);
-
- if ((send_ctx != NULL) && (send_ctx->cont != NULL))
+ }
+ dm = (const struct GNUNET_DV_DisconnectMessage *) msg;
+ // FIXME
+ break;
+ case GNUNET_MESSAGE_TYPE_DV_RECV:
+ if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage))
{
- if (ntohl (send_result_msg->result) == 0)
- {
- send_ctx->cont (send_ctx->cont_cls, &send_ctx->target, GNUNET_OK,
- send_ctx->payload_size, send_ctx->msg_size);
- }
- else
- {
- send_ctx->cont (send_ctx->cont_cls, &send_ctx->target, GNUNET_SYSERR,
- send_ctx->payload_size, 0);
- }
+ GNUNET_break (0);
+ reconnect (sh);
+ return;
}
- GNUNET_free_non_null (send_ctx);
+ rm = (const struct GNUNET_DV_ReceivedMessage *) msg;
+ // FIXME
break;
default:
+ reconnect (sh);
break;
}
- GNUNET_CLIENT_receive (handle->client, &handle_message_receipt, handle,
+ GNUNET_CLIENT_receive (sh->client,
+ &handle_message_receipt, sh,
GNUNET_TIME_UNIT_FOREVER_REL);
}
+
/**
- * Send a message from the plugin to the DV service indicating that
- * a message should be sent via DV to some peer.
+ * Transmit the start message to the DV service.
*
- * @param dv_handle the handle to the DV api
- * @param target the final target of the message
- * @param msgbuf the msg(s) to send
- * @param msgbuf_size the size of msgbuf
- * @param priority priority to pass on to core when sending the message
- * @param timeout how long can this message be delayed (pass through to core)
- * @param addr the address of this peer (internally known to DV)
- * @param addrlen the length of the peer address
- * @param cont continuation to call once the message has been sent (or failed)
- * @param cont_cls closure for continuation
- *
- */
-int
-GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
- const struct GNUNET_PeerIdentity *target, const char *msgbuf,
- size_t msgbuf_size, unsigned int priority,
- struct GNUNET_TIME_Relative timeout, const void *addr,
- size_t addrlen, GNUNET_TRANSPORT_TransmitContinuation cont,
- void *cont_cls)
+ * @param cls the 'struct GNUNET_DV_ServiceHandle'
+ * @param size number of bytes available in buf
+ * @param buf where to copy the message
+ * @return number of bytes written to buf
+ */
+static size_t
+transmit_start (void *cls,
+ size_t size,
+ void *buf)
{
- struct GNUNET_DV_SendMessage *msg;
- struct SendCallbackContext *send_ctx;
- char *end_of_message;
- struct GNUNET_HashCode uidhash;
- int msize;
+ struct GNUNET_DV_ServiceHandle *sh = cls;
+ struct GNUNET_MessageHeader start_message;
-#if DEBUG_DV_MESSAGES
- dv_handle->uid_gen =
- GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, UINT32_MAX);
-#else
- dv_handle->uid_gen++;
-#endif
+ sh->th = NULL;
+ if (NULL == buf)
+ {
+ GNUNET_break (0);
+ reconnect (sh);
+ return 0;
+ }
+ GNUNET_assert (size >= sizeof (start_message));
+ start_message.size = htons (sizeof (struct GNUNET_MessageHeader));
+ start_message.type = htons (GNUNET_MESSAGE_TYPE_DV_START);
+ memcpy (buf, &start_message, sizeof (start_message));
+ GNUNET_CLIENT_receive (sh->client,
+ &handle_message_receipt, sh,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ start_transmit (sh);
+ return sizeof (start_message);
+}
- msize = sizeof (struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size;
- msg = GNUNET_malloc (msize);
- msg->header.size = htons (msize);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND);
- memcpy (&msg->target, target, sizeof (struct GNUNET_PeerIdentity));
- msg->priority = htonl (priority);
- msg->timeout = timeout;
- msg->addrlen = htonl (addrlen);
- msg->uid = htonl (dv_handle->uid_gen);
- memcpy (&msg[1], addr, addrlen);
- end_of_message = (char *) &msg[1];
- end_of_message = &end_of_message[addrlen];
- memcpy (end_of_message, msgbuf, msgbuf_size);
- add_pending (dv_handle, msg);
- send_ctx = GNUNET_malloc (sizeof (struct SendCallbackContext));
- send_ctx->payload_size = msgbuf_size;
- send_ctx->msg_size = msize;
- send_ctx->cont = cont;
- send_ctx->cont_cls = cont_cls;
- memcpy (&send_ctx->target, target, sizeof (struct GNUNET_PeerIdentity));
- hash_from_uid (dv_handle->uid_gen, &uidhash);
- GNUNET_CONTAINER_multihashmap_put (dv_handle->send_callbacks, &uidhash,
- send_ctx,
-
GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
- return GNUNET_OK;
-}
-
/**
- * Callback to transmit a start message to
- * the DV service, once we can send
+ * Disconnect and then reconnect to the DV service.
*
- * @param cls struct StartContext
- * @param size how much can we send
- * @param buf where to copy the message
- *
- * @return number of bytes copied to buf
+ * @param sh service handle
*/
-static size_t
-transmit_start (void *cls, size_t size, void *buf)
+static void
+reconnect (struct GNUNET_DV_ServiceHandle *sh)
{
- struct StartContext *start_context = cls;
- struct GNUNET_DV_Handle *handle = start_context->handle;
- size_t tsize;
-
-#if DEBUG_DV
- LOG (GNUNET_ERROR_TYPE_DEBUG, "DV API: sending start request to service\n");
-#endif
- if (buf == NULL)
+ if (NULL != sh->th)
{
- GNUNET_free (start_context->message);
- GNUNET_free (start_context);
- GNUNET_DV_disconnect (handle);
- return 0;
+ GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
+ sh->th = NULL;
}
-
- tsize = ntohs (start_context->message->size);
- if (size >= tsize)
+ if (NULL != sh->client)
{
- memcpy (buf, start_context->message, tsize);
- GNUNET_free (start_context->message);
- GNUNET_free (start_context);
- GNUNET_CLIENT_receive (handle->client, &handle_message_receipt, handle,
- GNUNET_TIME_UNIT_FOREVER_REL);
-
-
- return tsize;
+ GNUNET_CLIENT_disconnect (sh->client);
+ sh->client = NULL;
}
-
- return 0;
+ sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg);
+ if (NULL == sh->client)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ sh->th = GNUNET_CLIENT_notify_transmit_ready (sh->client,
+ sizeof (struct
GNUNET_MessageHeader),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_YES,
+ &transmit_start,
+ sh);
}
+
/**
- * Connect to the DV service
+ * Connect to the DV service.
*
- * @param cfg the configuration to use
- * @param receive_handler method call when on receipt from the service
- * @param receive_handler_cls closure for receive_handler
- *
- * @return handle to the DV service
+ * @param cfg configuration
+ * @param cls closure for callbacks
+ * @param connect_cb function to call on connects
+ * @param disconnect_cb function to call on disconnects
+ * @param message_cb function to call if we receive messages
+ * @return handle to access the service
*/
-struct GNUNET_DV_Handle *
-GNUNET_DV_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_DV_MessageReceivedHandler receive_handler,
- void *receive_handler_cls)
+struct GNUNET_DV_ServiceHandle *
+GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ void *cls,
+ GNUNET_DV_ConnectCallback connect_cb,
+ GNUNET_DV_DisconnectCallback disconnect_cb,
+ GNUNET_DV_MessageReceivedCallback message_cb)
{
- struct GNUNET_DV_Handle *handle;
- struct GNUNET_MessageHeader *start_message;
- struct StartContext *start_context;
+ struct GNUNET_DV_ServiceHandle *sh;
- handle = GNUNET_malloc (sizeof (struct GNUNET_DV_Handle));
+ sh = GNUNET_malloc (sizeof (struct GNUNET_DV_ServiceHandle));
+ sh->cfg = cfg;
+ sh->cls = cls;
+ sh->connect_cb = connect_cb;
+ sh->disconnect_cb = disconnect_cb;
+ sh->message_cb = message_cb;
+ sh->send_callbacks = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_YES);
+ reconnect (sh);
+ return sh;
+}
- handle->cfg = cfg;
- handle->pending_list = NULL;
- handle->current = NULL;
- handle->th = NULL;
- handle->client = GNUNET_CLIENT_connect ("dv", cfg);
- handle->receive_handler = receive_handler;
- handle->receive_cls = receive_handler_cls;
- if (handle->client == NULL)
- {
- GNUNET_free (handle);
- return NULL;
- }
-
- start_message = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader));
- start_message->size = htons (sizeof (struct GNUNET_MessageHeader));
- start_message->type = htons (GNUNET_MESSAGE_TYPE_DV_START);
-
- start_context = GNUNET_malloc (sizeof (struct StartContext));
- start_context->handle = handle;
- start_context->message = start_message;
- GNUNET_CLIENT_notify_transmit_ready (handle->client,
- sizeof (struct GNUNET_MessageHeader),
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 60),
- GNUNET_YES, &transmit_start,
- start_context);
-
- handle->send_callbacks = GNUNET_CONTAINER_multihashmap_create (100,
GNUNET_NO);
-
- return handle;
-}
-
/**
- * Disconnect from the DV service
+ * Disconnect from DV service.
*
- * @param handle the current handle to the service to disconnect
+ * @param sh service handle
*/
void
-GNUNET_DV_disconnect (struct GNUNET_DV_Handle *handle)
+GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
{
- struct PendingMessages *pos;
-
- GNUNET_assert (handle != NULL);
-
- if (handle->th != NULL) /* We have a live transmit request in the
Aether */
+ struct GNUNET_DV_TransmitHandle *pos;
+
+ if (NULL == sh)
+ return;
+ if (NULL != sh->th)
{
- GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
- handle->th = NULL;
+ GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
+ sh->th = NULL;
}
- if (handle->current != NULL) /* We are trying to send something now, clean
it up */
- GNUNET_free (handle->current);
- while (NULL != (pos = handle->pending_list)) /* Remove all pending sends
from the list */
+ while (NULL != (pos = sh->th_head))
{
- handle->pending_list = pos->next;
+ GNUNET_CONTAINER_DLL_remove (sh->th_head,
+ sh->th_tail,
+ pos);
GNUNET_free (pos);
}
- if (handle->client != NULL) /* Finally, disconnect from the service */
+ if (NULL != sh->client)
{
- GNUNET_CLIENT_disconnect (handle->client);
- handle->client = NULL;
+ GNUNET_CLIENT_disconnect (sh->client);
+ sh->client = NULL;
}
+ // FIXME: handle and/or free entries in 'send_callbacks'!
+ GNUNET_CONTAINER_multihashmap_destroy (sh->send_callbacks);
+ GNUNET_free (sh);
+}
- GNUNET_free (handle);
+
+/**
+ * Send a message via DV service.
+ *
+ * @param sh service handle
+ * @param target intended recpient
+ * @param msg message payload
+ * @param cb function to invoke when done
+ * @param cb_cls closure for 'cb'
+ * @return handle to cancel the operation
+ */
+struct GNUNET_DV_TransmitHandle *
+GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh,
+ const struct GNUNET_PeerIdentity *target,
+ const struct GNUNET_MessageHeader *msg,
+ GNUNET_DV_MessageSentCallback cb,
+ void *cb_cls)
+{
+ struct GNUNET_DV_TransmitHandle *th;
+
+ th = GNUNET_malloc (sizeof (struct GNUNET_DV_TransmitHandle) +
+ ntohs (msg->size));
+ th->sh = sh;
+ th->target = *target;
+ th->cb = cb;
+ th->cb_cls = cb_cls;
+ // FIXME: wrong, need to box 'msg' AND generate UID!
+ th->msg = (const struct GNUNET_MessageHeader *) &th[1];
+ memcpy (&th[1], msg, ntohs (msg->size));
+ GNUNET_CONTAINER_DLL_insert (sh->th_head,
+ sh->th_tail,
+ th);
+ start_transmit (sh);
+ return th;
}
-#endif
+/**
+ * Abort send operation (naturally, the message may have
+ * already been transmitted; this only stops the 'cb'
+ * from being called again).
+ *
+ * @param th send operation to cancel
+ */
+void
+GNUNET_DV_send_cancel (struct GNUNET_DV_TransmitHandle *th)
+{
+ struct GNUNET_DV_ServiceHandle *sh = th->sh;
+ int ret;
+
+ ret = GNUNET_CONTAINER_multihashmap_remove (sh->send_callbacks,
+ &th->target.hashPubKey,
+ th);
+ if (GNUNET_YES != ret)
+ GNUNET_CONTAINER_DLL_remove (sh->th_head,
+ sh->th_tail,
+ th);
+ GNUNET_free (th);
+}
+
+
/* end of dv_api.c */
Modified: gnunet/src/dv/gnunet-service-dv.c
===================================================================
--- gnunet/src/dv/gnunet-service-dv.c 2013-03-12 14:23:57 UTC (rev 26392)
+++ gnunet/src/dv/gnunet-service-dv.c 2013-03-12 19:32:02 UTC (rev 26393)
@@ -445,7 +445,7 @@
pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size);
received_msg = (struct GNUNET_DV_ReceivedMessage *) &pending_message[1];
received_msg->header.size = htons (size);
- received_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECV);
+ received_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DV_RECV);
received_msg->distance = htonl (distance);
received_msg->sender = *distant_neighbor;
memcpy (&received_msg[1], message, ntohs (message->size));
@@ -490,7 +490,7 @@
pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size);
ack_msg = (struct GNUNET_DV_AckMessage *) &pending_message[1];
ack_msg->header.size = htons (size);
- ack_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_ACK);
+ ack_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND_ACK);
ack_msg->uid = htonl (uid);
ack_msg->target = *target;
GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head,
@@ -556,1283 +556,7 @@
}
-#if 0
-// ////////////////////////////////////////////////////////////////////////
-
-
/**
- * Send a DV data message via DV.
- *
- * @param sender the original sender of the message
- * @param recipient the next hop recipient, may be our direct peer, maybe not
- * @param send_context the send context
- */
-static int
-send_message_via (const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_PeerIdentity *recipient,
- struct DV_SendContext *send_context)
-{
- p2p_dv_MESSAGE_Data *toSend;
- unsigned int msg_size;
- unsigned int recipient_id;
- unsigned int sender_id;
- struct DistantNeighbor *source;
- struct PendingMessage *pending_message;
- struct FindIDContext find_context;
-
- msg_size = send_context->message_size + sizeof (p2p_dv_MESSAGE_Data);
-
- find_context.dest = send_context->distant_peer;
- find_context.via = recipient;
- find_context.tid = 0;
- GNUNET_CONTAINER_multihashmap_get_multiple (extended_neighbors,
- &send_context->
- distant_peer->hashPubKey,
- &find_specific_id,
&find_context);
-
- if (find_context.tid == 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "%s: find_specific_id failed to find peer!\n", my_short_id);
- /* target unknown to us, drop! */
- return GNUNET_SYSERR;
- }
- recipient_id = find_context.tid;
-
- if (0 == (memcmp (&my_identity, sender, sizeof (struct
GNUNET_PeerIdentity))))
- {
- sender_id = 0;
- source =
- GNUNET_CONTAINER_multihashmap_get (extended_neighbors,
- &sender->hashPubKey);
- if (source != NULL)
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "%s: send_message_via found %s, myself in extended peer
list???\n",
- my_short_id, GNUNET_i2s (&source->identity));
- }
- else
- {
- source =
- GNUNET_CONTAINER_multihashmap_get (extended_neighbors,
- &sender->hashPubKey);
- if (source == NULL)
- {
- /* sender unknown to us, drop! */
- return GNUNET_SYSERR;
- }
- sender_id = source->our_id;
- }
-
- pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
- pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1];
- pending_message->send_result = send_context->send_result;
- memcpy (&pending_message->recipient, recipient,
- sizeof (struct GNUNET_PeerIdentity));
- pending_message->msg_size = msg_size;
- pending_message->importance = send_context->importance;
- pending_message->timeout = send_context->timeout;
- toSend = (p2p_dv_MESSAGE_Data *) pending_message->msg;
- toSend->header.size = htons (msg_size);
- toSend->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DATA);
- toSend->sender = htonl (sender_id);
- toSend->recipient = htonl (recipient_id);
-#if DEBUG_DV_MESSAGES
- toSend->uid = send_context->uid; /* Still sent around in network byte
order */
-#else
- toSend->uid = htonl (0);
-#endif
-
- memcpy (&toSend[1], send_context->message, send_context->message_size);
-
-#if DEBUG_DV
- memcpy (&shortname, GNUNET_i2s (send_context->distant_peer), 4);
- shortname[4] = '\0';
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Notifying core of send to destination `%s' via `%s' size
%u\n",
- "DV", &shortname, GNUNET_i2s (recipient), msg_size);
-#endif
-
- GNUNET_CONTAINER_DLL_insert_after (core_pending_head, core_pending_tail,
- core_pending_tail, pending_message);
-
- GNUNET_SCHEDULER_add_now (try_core_send, NULL);
-
- return GNUNET_YES;
-}
-
-/**
- * Given a FindLeastCostContext, and a set
- * of peers that match the target, return the cheapest.
- *
- * @param cls closure, a struct FindLeastCostContext
- * @param key the key identifying the target peer
- * @param value the target peer
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO to stop
- */
-static int
-find_least_cost_peer (void *cls, const struct GNUNET_HashCode * key, void
*value)
-{
- struct FindLeastCostContext *find_context = cls;
- struct DistantNeighbor *dn = value;
-
- if (dn->cost < find_context->least_cost)
- {
- find_context->target = dn;
- }
- if (dn->cost == DIRECT_NEIGHBOR_COST)
- return GNUNET_NO;
- return GNUNET_YES;
-}
-
-/**
- * Send a DV data message via DV.
- *
- * @param recipient the ultimate recipient of this message
- * @param sender the original sender of the message
- * @param specific_neighbor the specific neighbor to send this message via
- * @param message the packed message
- * @param message_size size of the message
- * @param importance what priority to send this message with
- * @param uid the unique identifier of this message (or 0 for none)
- * @param timeout how long to possibly delay sending this message
- */
-static int
-send_message (const struct GNUNET_PeerIdentity *recipient,
- const struct GNUNET_PeerIdentity *sender,
- const struct DistantNeighbor *specific_neighbor,
- const struct GNUNET_MessageHeader *message, size_t message_size,
- unsigned int importance, unsigned int uid,
- struct GNUNET_TIME_Relative timeout)
-{
- p2p_dv_MESSAGE_Data *toSend;
- unsigned int msg_size;
- unsigned int cost;
- unsigned int recipient_id;
- unsigned int sender_id;
- struct DistantNeighbor *target;
- struct DistantNeighbor *source;
- struct PendingMessage *pending_message;
- struct FindLeastCostContext find_least_ctx;
-
-#if DEBUG_DV_PEER_NUMBERS
- struct GNUNET_CRYPTO_HashAsciiEncoded encPeerFrom;
- struct GNUNET_CRYPTO_HashAsciiEncoded encPeerTo;
- struct GNUNET_CRYPTO_HashAsciiEncoded encPeerVia;
-#endif
- msg_size = message_size + sizeof (p2p_dv_MESSAGE_Data);
-
- find_least_ctx.least_cost = -1;
- find_least_ctx.target = NULL;
- /*
- * Need to find the least cost peer, lest the transport selection keep
- * picking the same DV route for the same destination which results
- * in messages looping forever. Relatively cheap, we don't iterate
- * over all known peers, just those that apply.
- */
- GNUNET_CONTAINER_multihashmap_get_multiple (extended_neighbors,
- &recipient->hashPubKey,
- &find_least_cost_peer,
- &find_least_ctx);
- target = find_least_ctx.target;
-
- if (target == NULL)
- {
- /* target unknown to us, drop! */
- return GNUNET_SYSERR;
- }
- recipient_id = target->referrer_id;
-
- source =
- GNUNET_CONTAINER_multihashmap_get (extended_neighbors,
- &sender->hashPubKey);
- if (source == NULL)
- {
- if (0 !=
- (memcmp (&my_identity, sender, sizeof (struct GNUNET_PeerIdentity))))
- {
- /* sender unknown to us, drop! */
- return GNUNET_SYSERR;
- }
- sender_id = 0; /* 0 == us */
- }
- else
- {
- /* find out the number that we use when we gossip about
- * the sender */
- sender_id = source->our_id;
- }
-
-#if DEBUG_DV_PEER_NUMBERS
- GNUNET_CRYPTO_hash_to_enc (&source->identity.hashPubKey, &encPeerFrom);
- GNUNET_CRYPTO_hash_to_enc (&target->referrer->identity.hashPubKey,
- &encPeerVia);
- encPeerFrom.encoding[4] = '\0';
- encPeerVia.encoding[4] = '\0';
-#endif
- if ((sender_id != 0) &&
- (0 ==
- memcmp (&source->identity, &target->referrer->identity,
- sizeof (struct GNUNET_PeerIdentity))))
- {
- return 0;
- }
-
- cost = target->cost;
- pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
- pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1];
- pending_message->send_result = NULL;
- pending_message->importance = importance;
- pending_message->timeout = timeout;
- memcpy (&pending_message->recipient, &target->referrer->identity,
- sizeof (struct GNUNET_PeerIdentity));
- pending_message->msg_size = msg_size;
- toSend = (p2p_dv_MESSAGE_Data *) pending_message->msg;
- toSend->header.size = htons (msg_size);
- toSend->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DATA);
- toSend->sender = htonl (sender_id);
- toSend->recipient = htonl (recipient_id);
-#if DEBUG_DV_MESSAGES
- toSend->uid = htonl (uid);
-#else
- toSend->uid = htonl (0);
-#endif
-
-#if DEBUG_DV_PEER_NUMBERS
- GNUNET_CRYPTO_hash_to_enc (&target->identity.hashPubKey, &encPeerTo);
- encPeerTo.encoding[4] = '\0';
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Sending DATA message. Sender id %u, source %s, destination
%s, via %s\n",
- GNUNET_i2s (&my_identity), sender_id, &encPeerFrom, &encPeerTo,
- &encPeerVia);
-#endif
- memcpy (&toSend[1], message, message_size);
- if ((source != NULL) && (source->pkey == NULL)) /* Test our hypothesis
about message failures! */
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "%s: Sending message, but anticipate recipient will not know
sender!!!\n\n\n",
- my_short_id);
- }
- GNUNET_CONTAINER_DLL_insert_after (core_pending_head, core_pending_tail,
- core_pending_tail, pending_message);
-#if DEBUG_DV
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Notifying core of send size %d to destination `%s'\n",
- "DV SEND MESSAGE", msg_size, GNUNET_i2s (recipient));
-#endif
-
- GNUNET_SCHEDULER_add_now (try_core_send, NULL);
- return (int) cost;
-}
-
-#if USE_PEER_ID
-struct CheckPeerContext
-{
- /**
- * Peer we found
- */
- struct DistantNeighbor *peer;
-
- /**
- * Sender id to search for
- */
- unsigned int sender_id;
-};
-
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-int
-checkPeerID (void *cls, const struct GNUNET_HashCode * key, void *value)
-{
- struct CheckPeerContext *ctx = cls;
- struct DistantNeighbor *distant = value;
-
- if (memcmp (key, &ctx->sender_id, sizeof (unsigned int)) == 0)
- {
- ctx->peer = distant;
- return GNUNET_NO;
- }
- return GNUNET_YES;
-
-}
-#endif
-
-
-/**
- * Handler for messages parsed out by the tokenizer from
- * DV DATA received for this peer.
- *
- * @param cls NULL
- * @param client the TokenizedMessageContext which contains message information
- * @param message the actual message
- */
-int
-tokenized_message_handler (void *cls, void *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct TokenizedMessageContext *ctx = client;
-
- GNUNET_break_op (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_GOSSIP);
- GNUNET_break_op (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_DATA);
- if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_GOSSIP) &&
- (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_DATA))
- {
-#if DEBUG_DV_MESSAGES
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Receives %s message for me, uid %u, size %d, type %d cost
%u from %s!\n",
- my_short_id, "DV DATA", ctx->uid, ntohs (message->size),
- ntohs (message->type), ctx->distant->cost,
- GNUNET_i2s (&ctx->distant->identity));
-#endif
- GNUNET_assert (memcmp
- (ctx->peer, &ctx->distant->identity,
- sizeof (struct GNUNET_PeerIdentity)) != 0);
- send_to_plugin (ctx->peer, message, ntohs (message->size),
- &ctx->distant->identity, ctx->distant->cost);
- }
- return GNUNET_OK;
-}
-
-#if DELAY_FORWARDS
-struct DelayedMessageContext
-{
- struct GNUNET_PeerIdentity dest;
- struct GNUNET_PeerIdentity sender;
- struct GNUNET_MessageHeader *message;
- size_t message_size;
- uint32_t uid;
-};
-
-void
-send_message_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct DelayedMessageContext *msg_ctx = cls;
-
- if (msg_ctx != NULL)
- {
- send_message (&msg_ctx->dest, &msg_ctx->sender, NULL, msg_ctx->message,
- msg_ctx->message_size, default_dv_priority, msg_ctx->uid,
- GNUNET_TIME_UNIT_FOREVER_REL);
- GNUNET_free (msg_ctx->message);
- GNUNET_free (msg_ctx);
- }
-}
-#endif
-
-/**
- * Find latency information in 'atsi'.
- *
- * @param atsi performance data
- * @param atsi_count number of entries in atsi
- * @return connection latency
- */
-static struct GNUNET_TIME_Relative
-get_atsi_latency (const struct GNUNET_ATS_Information *atsi,
- unsigned int atsi_count)
-{
- unsigned int i;
-
- for (i = 0; i < atsi_count; i++)
- if (ntohl (atsi[i].type) == GNUNET_ATS_QUALITY_NET_DELAY)
- return GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
- ntohl (atsi->value));
- GNUNET_break (0);
- /* how can we not have latency data? */
- return GNUNET_TIME_UNIT_SECONDS;
-}
-
-
-#if DEBUG_DV
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure (NULL)
- * @param key current key code
- * @param value value in the hash map (DistantNeighbor)
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-int
-print_neighbors (void *cls, const struct GNUNET_HashCode * key, void
*abs_value)
-{
- struct DistantNeighbor *distant_neighbor = abs_value;
- char my_shortname[5];
- char referrer_shortname[5];
-
- memcpy (&my_shortname, GNUNET_i2s (&my_identity), 4);
- my_shortname[4] = '\0';
- memcpy (&referrer_shortname,
- GNUNET_i2s (&distant_neighbor->referrer->identity), 4);
- referrer_shortname[4] = '\0';
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "`%s' %s: Peer `%s', distance %d, referrer `%s' pkey: %s\n",
- &my_shortname, "DV", GNUNET_i2s (&distant_neighbor->identity),
- distant_neighbor->cost, &referrer_shortname,
- distant_neighbor->pkey == NULL ? "no" : "yes");
- return GNUNET_YES;
-}
-#endif
-
-/**
- * Scheduled task which gossips about known direct peers to other connected
- * peers. Will run until called with reason shutdown.
- */
-static void
-neighbor_send_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct NeighborSendContext *send_context = cls;
-
-#if DEBUG_DV_GOSSIP_SEND
- char *encPeerAbout;
- char *encPeerTo;
-#endif
- struct DistantNeighbor *about;
- struct DirectNeighbor *to;
- struct FastGossipNeighborList *about_list;
-
- p2p_dv_MESSAGE_NeighborInfo *message;
- struct PendingMessage *pending_message;
-
- if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
- {
-#if DEBUG_DV_GOSSIP
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Called with reason shutdown, shutting down!\n",
- GNUNET_i2s (&my_identity));
-#endif
- return;
- }
-
- if (send_context->fast_gossip_list_head != NULL)
- {
- about_list = send_context->fast_gossip_list_head;
- about = about_list->about;
- GNUNET_CONTAINER_DLL_remove (send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- about_list);
- GNUNET_free (about_list);
- }
- else
- {
- /* FIXME: this may become a problem, because the heap walk has only one
internal "walker". This means
- * that if two neighbor_send_tasks are operating in lockstep (which is
quite possible, given default
- * values for all connected peers) there may be a serious bias as to which
peers get gossiped about!
- * Probably the *best* way to fix would be to have an opaque pointer to
the walk position passed as
- * part of the walk_get_next call. Then the heap would have to keep a
list of walks, or reset the walk
- * whenever a modification has been detected. Yuck either way. Perhaps
we could iterate over the heap
- * once to get a list of peers to gossip about and gossip them over
time... But then if one goes away
- * in the mean time that becomes nasty. For now we'll just assume that
the walking is done
- * asynchronously enough to avoid major problems (-;
- *
- * NOTE: probably fixed once we decided send rate based on allowed
bandwidth.
- */
- about = GNUNET_CONTAINER_heap_walk_get_next (neighbor_min_heap);
- }
- to = send_context->toNeighbor;
-
- if ((about != NULL) && (to != about->referrer /* split horizon */ ) &&
-#if SUPPORT_HIDING
- (about->hidden == GNUNET_NO) &&
-#endif
- (to != NULL) &&
- (0 !=
- memcmp (&about->identity, &to->identity,
- sizeof (struct GNUNET_PeerIdentity))) && (about->pkey != NULL))
- {
-#if DEBUG_DV_GOSSIP_SEND
- encPeerAbout = GNUNET_strdup (GNUNET_i2s (&about->identity));
- encPeerTo = GNUNET_strdup (GNUNET_i2s (&to->identity));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Sending info about peer %s id %u to directly connected
peer %s\n",
- GNUNET_i2s (&my_identity), encPeerAbout, about->our_id,
- encPeerTo);
- GNUNET_free (encPeerAbout);
- GNUNET_free (encPeerTo);
-#endif
- about->last_gossip = GNUNET_TIME_absolute_get ();
- pending_message =
- GNUNET_malloc (sizeof (struct PendingMessage) +
- sizeof (p2p_dv_MESSAGE_NeighborInfo));
- pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1];
- pending_message->importance = default_dv_priority;
- pending_message->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
- memcpy (&pending_message->recipient, &to->identity,
- sizeof (struct GNUNET_PeerIdentity));
- pending_message->msg_size = sizeof (p2p_dv_MESSAGE_NeighborInfo);
- message = (p2p_dv_MESSAGE_NeighborInfo *) pending_message->msg;
- message->header.size = htons (sizeof (p2p_dv_MESSAGE_NeighborInfo));
- message->header.type = htons (GNUNET_MESSAGE_TYPE_DV_GOSSIP);
- message->cost = htonl (about->cost);
- message->neighbor_id = htonl (about->our_id);
-
- memcpy (&message->pkey, about->pkey,
- sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
- memcpy (&message->neighbor, &about->identity,
- sizeof (struct GNUNET_PeerIdentity));
-
- GNUNET_CONTAINER_DLL_insert_after (core_pending_head, core_pending_tail,
- core_pending_tail, pending_message);
-
- GNUNET_SCHEDULER_add_now (try_core_send, NULL);
- /*if (core_transmit_handle == NULL)
- * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
GNUNET_YES, default_dv_priority, GNUNET_TIME_UNIT_FOREVER_REL, &to->identity,
sizeof(p2p_dv_MESSAGE_NeighborInfo), &core_transmit_notify, NULL); */
-
- }
-
- if (send_context->fast_gossip_list_head != NULL) /* If there are other
peers in the fast list, schedule right away */
- {
-#if DEBUG_DV_PEER_NUMBERS
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "DV SERVICE: still in fast send mode\n");
-#endif
- send_context->task =
- GNUNET_SCHEDULER_add_now (&neighbor_send_task, send_context);
- }
- else
- {
-#if DEBUG_DV_PEER_NUMBERS
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "DV SERVICE: entering slow send mode\n");
-#endif
- send_context->task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_DV_DEFAULT_SEND_INTERVAL,
- &neighbor_send_task, send_context);
- }
-
- return;
-}
-
-
-
-#if UNSIMPLER
-/**
- * Iterate over hash map entries for a distant neighbor,
- * if direct neighbor matches context call send message
- *
- * @param cls closure, a DV_SendContext
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-int
-send_iterator (void *cls, const struct GNUNET_HashCode * key, void *abs_value)
-{
- struct DV_SendContext *send_context = cls;
- struct DistantNeighbor *distant_neighbor = abs_value;
-
- if (memcmp (distant_neighbor->referrer, send_context->direct_peer, sizeof
(struct GNUNET_PeerIdentity)) == 0) /* They match, send and free */
- {
- send_message_via (&my_identity, distant_neighbor, send_context);
- return GNUNET_NO;
- }
- return GNUNET_YES;
-}
-#endif
-
-
-/** Forward declarations **/
-static int
-handle_dv_gossip_message (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi,
- unsigned int atsi_count);
-
-static int
-handle_dv_disconnect_message (void *cls, const struct GNUNET_PeerIdentity
*peer,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi,
- unsigned int atsi_count);
-/** End forward declarations **/
-
-
-/**
- * Free a DistantNeighbor node, including removing it
- * from the referer's list.
- */
-static void
-distant_neighbor_free (struct DistantNeighbor *referee)
-{
- struct DirectNeighbor *referrer;
-
- referrer = referee->referrer;
- if (referrer != NULL)
- {
- GNUNET_CONTAINER_DLL_remove (referrer->referee_head,
referrer->referee_tail,
- referee);
- }
- GNUNET_CONTAINER_heap_remove_node (referee->max_loc);
- GNUNET_CONTAINER_heap_remove_node (referee->min_loc);
- GNUNET_CONTAINER_multihashmap_remove_all (extended_neighbors,
- &referee->identity.hashPubKey);
- GNUNET_free_non_null (referee->pkey);
- GNUNET_free (referee);
-}
-
-/**
- * Free a DirectNeighbor node, including removing it
- * from the referer's list.
- */
-static void
-direct_neighbor_free (struct DirectNeighbor *direct)
-{
- struct NeighborSendContext *send_context;
- struct FastGossipNeighborList *about_list;
- struct FastGossipNeighborList *prev_about;
-
- send_context = direct->send_context;
-
- if (send_context->task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (send_context->task);
-
- about_list = send_context->fast_gossip_list_head;
- while (about_list != NULL)
- {
- GNUNET_CONTAINER_DLL_remove (send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- about_list);
- prev_about = about_list;
- about_list = about_list->next;
- GNUNET_free (prev_about);
- }
- GNUNET_free (send_context);
- GNUNET_free (direct);
-}
-
-/**
- * Multihashmap iterator for sending out disconnect messages
- * for a peer.
- *
- * @param cls the peer that was disconnected
- * @param key key value stored under
- * @param value the direct neighbor to send disconnect to
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO to stop
- */
-static int
-schedule_disconnect_messages (void *cls, const struct GNUNET_HashCode * key,
- void *value)
-{
- struct DisconnectContext *disconnect_context = cls;
- struct DirectNeighbor *disconnected = disconnect_context->direct;
- struct DirectNeighbor *notify = value;
- struct PendingMessage *pending_message;
- p2p_dv_MESSAGE_Disconnect *disconnect_message;
-
- if (memcmp
- (¬ify->identity, &disconnected->identity,
- sizeof (struct GNUNET_PeerIdentity)) == 0)
- return GNUNET_YES; /* Don't send disconnect message to peer that
disconnected! */
-
- pending_message =
- GNUNET_malloc (sizeof (struct PendingMessage) +
- sizeof (p2p_dv_MESSAGE_Disconnect));
- pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1];
- pending_message->importance = default_dv_priority;
- pending_message->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
- memcpy (&pending_message->recipient, ¬ify->identity,
- sizeof (struct GNUNET_PeerIdentity));
- pending_message->msg_size = sizeof (p2p_dv_MESSAGE_Disconnect);
- disconnect_message = (p2p_dv_MESSAGE_Disconnect *) pending_message->msg;
- disconnect_message->header.size = htons (sizeof (p2p_dv_MESSAGE_Disconnect));
- disconnect_message->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DISCONNECT);
- disconnect_message->peer_id = htonl (disconnect_context->distant->our_id);
-
- GNUNET_CONTAINER_DLL_insert_after (core_pending_head, core_pending_tail,
- core_pending_tail, pending_message);
-
- GNUNET_SCHEDULER_add_now (try_core_send, NULL);
- /*if (core_transmit_handle == NULL)
- * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
GNUNET_YES, default_dv_priority, GNUNET_TIME_UNIT_FOREVER_REL,
¬ify->identity, sizeof(p2p_dv_MESSAGE_Disconnect), &core_transmit_notify,
NULL); */
-
- return GNUNET_YES;
-}
-
-
-#if PKEY_NO_NEIGHBOR_ON_ADD
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-static int
-add_pkey_to_extended (void *cls, const struct GNUNET_HashCode * key, void
*abs_value)
-{
- struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pkey = cls;
- struct DistantNeighbor *distant_neighbor = abs_value;
-
- if (distant_neighbor->pkey == NULL)
- {
- distant_neighbor->pkey =
- GNUNET_malloc (sizeof (struct
GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
- memcpy (distant_neighbor->pkey, pkey,
- sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
- }
-
- return GNUNET_YES;
-}
-#endif
-
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-static int
-update_matching_neighbors (void *cls, const struct GNUNET_HashCode * key, void
*value)
-{
- struct NeighborUpdateInfo *update_info = cls;
- struct DistantNeighbor *distant_neighbor = value;
-
- if (update_info->referrer == distant_neighbor->referrer) /* Direct
neighbor matches, update it's info and return GNUNET_NO */
- {
- /* same referrer, cost change! */
- GNUNET_CONTAINER_heap_update_cost (neighbor_max_heap,
- update_info->neighbor->max_loc,
- update_info->cost);
- GNUNET_CONTAINER_heap_update_cost (neighbor_min_heap,
- update_info->neighbor->min_loc,
- update_info->cost);
- update_info->neighbor->last_activity = update_info->now;
- update_info->neighbor->cost = update_info->cost;
- update_info->neighbor->referrer_id = update_info->referrer_peer_id;
- return GNUNET_NO;
- }
-
- return GNUNET_YES;
-}
-
-
-/**
- * Iterate over all current direct peers, add DISTANT newly connected
- * peer to the fast gossip list for that peer so we get DV routing
- * information out as fast as possible!
- *
- * @param cls the newly connected neighbor we will gossip about
- * @param key the hashcode of the peer
- * @param value the direct neighbor we should gossip to
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
- */
-static int
-add_distant_all_direct_neighbors (void *cls, const struct GNUNET_HashCode *
key,
- void *value)
-{
- struct DirectNeighbor *direct = (struct DirectNeighbor *) value;
- struct DistantNeighbor *distant = (struct DistantNeighbor *) cls;
- struct NeighborSendContext *send_context = direct->send_context;
- struct FastGossipNeighborList *gossip_entry;
-
-#if DEBUG_DV
- char *encPeerAbout;
- char *encPeerTo;
-#endif
-
- if (distant == NULL)
- {
- return GNUNET_YES;
- }
-
- if (memcmp
- (&direct->identity, &distant->identity,
- sizeof (struct GNUNET_PeerIdentity)) == 0)
- {
- return GNUNET_YES; /* Don't gossip to a peer about itself! */
- }
-
-#if SUPPORT_HIDING
- if (distant->hidden == GNUNET_YES)
- return GNUNET_YES; /* This peer should not be gossipped about
(hidden) */
-#endif
- gossip_entry = GNUNET_malloc (sizeof (struct FastGossipNeighborList));
- gossip_entry->about = distant;
-
- GNUNET_CONTAINER_DLL_insert_after (send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- send_context->fast_gossip_list_tail,
- gossip_entry);
-#if DEBUG_DV
- encPeerAbout = GNUNET_strdup (GNUNET_i2s (&distant->identity));
- encPeerTo = GNUNET_strdup (GNUNET_i2s (&direct->identity));
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Fast send info about peer %s id %u for directly connected
peer %s\n",
- GNUNET_i2s (&my_identity), encPeerAbout, distant->our_id,
- encPeerTo);
- GNUNET_free (encPeerAbout);
- GNUNET_free (encPeerTo);
-#endif
- /*if (send_context->task != GNUNET_SCHEDULER_NO_TASK)
- * GNUNET_SCHEDULER_cancel(send_context->task); */
-
- send_context->task =
- GNUNET_SCHEDULER_add_now (&neighbor_send_task, send_context);
- return GNUNET_YES;
-}
-
-/**
- * Callback for hello address creation.
- *
- * @param cls closure, a struct HelloContext
- * @param max maximum number of bytes that can be written to buf
- * @param buf where to write the address information
- *
- * @return number of bytes written, 0 to signal the
- * end of the iteration.
- */
-static size_t
-generate_hello_address (void *cls, size_t max, void *buf)
-{
- struct HelloContext *hello_context = cls;
- struct GNUNET_HELLO_Address hello_address;
- char *addr_buffer;
- size_t offset;
- size_t size;
- size_t ret;
-
- if (hello_context->addresses_to_add == 0)
- return 0;
-
- /* Hello "address" will be concatenation of distant peer and direct peer
identities */
- size = 2 * sizeof (struct GNUNET_PeerIdentity);
- GNUNET_assert (max >= size);
-
- addr_buffer = GNUNET_malloc (size);
- offset = 0;
- /* Copy the distant peer identity to buffer */
- memcpy (addr_buffer, &hello_context->distant_peer,
- sizeof (struct GNUNET_PeerIdentity));
- offset += sizeof (struct GNUNET_PeerIdentity);
- /* Copy the direct peer identity to buffer */
- memcpy (&addr_buffer[offset], hello_context->direct_peer,
- sizeof (struct GNUNET_PeerIdentity));
- memset (&hello_address.peer, 0, sizeof (struct GNUNET_PeerIdentity));
- hello_address.address = addr_buffer;
- hello_address.transport_name = "dv";
- hello_address.address_length = size;
- ret =
- GNUNET_HELLO_add_address (&hello_address,
- GNUNET_TIME_relative_to_absolute
- (GNUNET_TIME_UNIT_HOURS), buf, max);
-
- hello_context->addresses_to_add--;
-
- GNUNET_free (addr_buffer);
- return ret;
-}
-
-
-/**
- * Handles when a peer is either added due to being newly connected
- * or having been gossiped about, also called when the cost for a neighbor
- * needs to be updated.
- *
- * @param peer identity of the peer whose info is being added/updated
- * @param pkey public key of the peer whose info is being added/updated
- * @param referrer_peer_id id to use when sending to 'peer'
- * @param referrer if this is a gossiped peer, who did we hear it from?
- * @param cost the cost of communicating with this peer via 'referrer'
- *
- * @return the added neighbor, the updated neighbor or NULL (neighbor
- * not added)
- */
-static struct DistantNeighbor *
-addUpdateNeighbor (const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pkey,
- unsigned int referrer_peer_id,
- struct DirectNeighbor *referrer, unsigned int cost)
-{
- struct DistantNeighbor *neighbor;
- struct DistantNeighbor *max;
- struct GNUNET_TIME_Absolute now;
- struct NeighborUpdateInfo *neighbor_update;
- struct HelloContext *hello_context;
- struct GNUNET_HELLO_Message *hello_msg;
- unsigned int our_id;
- char *addr1;
- char *addr2;
- int i;
-
-#if DEBUG_DV_PEER_NUMBERS
- char *encAbout;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s Received sender id (%u)!\n",
- "DV SERVICE", referrer_peer_id);
-#endif
-
- now = GNUNET_TIME_absolute_get ();
- neighbor =
- GNUNET_CONTAINER_multihashmap_get (extended_neighbors,
&peer->hashPubKey);
- neighbor_update = GNUNET_malloc (sizeof (struct NeighborUpdateInfo));
- neighbor_update->neighbor = neighbor;
- neighbor_update->cost = cost;
- neighbor_update->now = now;
- neighbor_update->referrer = referrer;
- neighbor_update->referrer_peer_id = referrer_peer_id;
-
- if (neighbor != NULL)
- {
-#if USE_PEER_ID
- memcpy (&our_id, &neighbor->identity, sizeof (unsigned int));
-#else
- our_id = neighbor->our_id;
-#endif
- }
- else
- {
-#if USE_PEER_ID
- memcpy (&our_id, peer, sizeof (unsigned int));
-#else
- our_id =
- GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
- RAND_MAX - 1) + 1;
-#endif
- }
-
- /* Either we do not know this peer, or we already do but via a different
immediate peer */
- if ((neighbor == NULL) ||
- (GNUNET_CONTAINER_multihashmap_get_multiple
- (extended_neighbors, &peer->hashPubKey, &update_matching_neighbors,
- neighbor_update) != GNUNET_SYSERR))
- {
-#if AT_MOST_ONE
- if ((neighbor != NULL) && (cost < neighbor->cost)) /* New cost is less
than old, remove old */
- {
- distant_neighbor_free (neighbor);
- }
- else if (neighbor != NULL) /* Only allow one DV connection to each peer */
- {
- return NULL;
- }
-#endif
- /* new neighbor! */
- if (cost > fisheye_depth)
- {
- /* too costly */
- GNUNET_free (neighbor_update);
- return NULL;
- }
-
-#if DEBUG_DV_PEER_NUMBERS
- encAbout = GNUNET_strdup (GNUNET_i2s (peer));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: %s Chose NEW id (%u) for peer %s!\n",
- GNUNET_i2s (&my_identity), "DV SERVICE", our_id, encAbout);
- GNUNET_free (encAbout);
-#endif
-
- if (max_table_size <=
- GNUNET_CONTAINER_multihashmap_size (extended_neighbors))
- {
- /* remove most expensive entry */
- max = GNUNET_CONTAINER_heap_peek (neighbor_max_heap);
- GNUNET_assert (max != NULL);
- if (cost > max->cost)
- {
- /* new entry most expensive, don't create */
- GNUNET_free (neighbor_update);
- return NULL;
- }
- if (max->cost > 1)
- {
- /* only free if this is not a direct connection;
- * we could theoretically have more direct
- * connections than DV entries allowed total! */
- distant_neighbor_free (max);
- }
- }
-
- neighbor = GNUNET_malloc (sizeof (struct DistantNeighbor));
- GNUNET_CONTAINER_DLL_insert (referrer->referee_head,
referrer->referee_tail,
- neighbor);
- neighbor->max_loc =
- GNUNET_CONTAINER_heap_insert (neighbor_max_heap, neighbor, cost);
- neighbor->min_loc =
- GNUNET_CONTAINER_heap_insert (neighbor_min_heap, neighbor, cost);
- neighbor->referrer = referrer;
- memcpy (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity));
- if (pkey != NULL) /* pkey will be null on direct neighbor
addition */
- {
- neighbor->pkey =
- GNUNET_malloc (sizeof
- (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
- memcpy (neighbor->pkey, pkey,
- sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
- }
- else
- neighbor->pkey = pkey;
-
- neighbor->last_activity = now;
- neighbor->cost = cost;
- neighbor->referrer_id = referrer_peer_id;
- neighbor->our_id = our_id;
- neighbor->hidden =
- (cost ==
- DIRECT_NEIGHBOR_COST)
- ? (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 4) ==
- 0) : GNUNET_NO;
-
- GNUNET_CONTAINER_multihashmap_put (extended_neighbors, &peer->hashPubKey,
- neighbor,
-
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- if (referrer_peer_id != 0)
- {
- for (i = 0; i < MAX_OUTSTANDING_MESSAGES; i++)
- {
- if (referrer->pending_messages[i].sender_id == referrer_peer_id)
/* We have a queued message from just learned about peer! */
- {
-#if DEBUG_DV_MESSAGES
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: learned about peer %llu from which we have a
previous unknown message, processing!\n",
- my_short_id, referrer_peer_id);
-#endif
- struct GNUNET_ATS_Information atsi[2];
-
- atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
- atsi[0].value = htonl (referrer->pending_messages[i].distance);
- atsi[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
- atsi[1].value =
- htonl ((uint32_t) referrer->pending_messages[i].
- latency.rel_value);
- handle_dv_data_message (NULL, &referrer->pending_messages[i].sender,
- referrer->pending_messages[i].message, atsi,
- 2);
- GNUNET_free (referrer->pending_messages[i].message);
- referrer->pending_messages[i].sender_id = 0;
- }
- }
- }
- if ((cost != DIRECT_NEIGHBOR_COST) && (neighbor->pkey != NULL))
- {
- /* Added neighbor, now send HELLO to transport */
- hello_context = GNUNET_malloc (sizeof (struct HelloContext));
- hello_context->direct_peer = &referrer->identity;
- memcpy (&hello_context->distant_peer, peer,
- sizeof (struct GNUNET_PeerIdentity));
- hello_context->addresses_to_add = 1;
- hello_msg =
- GNUNET_HELLO_create (pkey, &generate_hello_address, hello_context);
- GNUNET_assert (memcmp
- (hello_context->direct_peer, &hello_context->distant_peer,
- sizeof (struct GNUNET_PeerIdentity)) != 0);
- addr1 = GNUNET_strdup (GNUNET_i2s (hello_context->direct_peer));
- addr2 = GNUNET_strdup (GNUNET_i2s (&hello_context->distant_peer));
-#if DEBUG_DV
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: GIVING HELLO size %d for %s via %s to TRANSPORT\n",
- my_short_id, GNUNET_HELLO_size (hello_msg), addr2, addr1);
-#endif
- GNUNET_free (addr1);
- GNUNET_free (addr2);
- send_to_plugin (hello_context->direct_peer,
- GNUNET_HELLO_get_header (hello_msg),
- GNUNET_HELLO_size (hello_msg),
- &hello_context->distant_peer, cost);
- GNUNET_free (hello_context);
- GNUNET_free (hello_msg);
- }
-
- }
- else
- {
-#if DEBUG_DV_GOSSIP
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Already know peer %s distance %d, referrer id %d!\n",
"dv",
- GNUNET_i2s (peer), cost, referrer_peer_id);
-#endif
- }
-#if DEBUG_DV
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s: Size of extended_neighbors is
%d\n",
- "dv", GNUNET_CONTAINER_multihashmap_size (extended_neighbors));
-#endif
-
- GNUNET_free (neighbor_update);
- return neighbor;
-}
-
-
-/**
- * Core handler for dv disconnect messages. These will be used
- * by us to tell transport via the dv plugin that a peer can
- * no longer be contacted by us via a certain address. We should
- * then propagate these messages on, given that the distance to
- * the peer indicates we would have gossiped about it to others.
- *
- * @param cls closure
- * @param peer peer which sent the message (immediate sender)
- * @param message the message
- * @param atsi performance data
- * @param atsi_count number of entries in atsi
- */
-static int
-handle_dv_disconnect_message (void *cls, const struct GNUNET_PeerIdentity
*peer,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi,
- unsigned int atsi_count)
-{
- struct DirectNeighbor *referrer;
- struct DistantNeighbor *distant;
- p2p_dv_MESSAGE_Disconnect *enc_message =
- (p2p_dv_MESSAGE_Disconnect *) message;
-
- if (ntohs (message->size) < sizeof (p2p_dv_MESSAGE_Disconnect))
- {
- return GNUNET_SYSERR; /* invalid message */
- }
-
- referrer =
- GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey);
- if (referrer == NULL)
- return GNUNET_OK;
-
- distant = referrer->referee_head;
- while (distant != NULL)
- {
- if (distant->referrer_id == ntohl (enc_message->peer_id))
- {
- distant_neighbor_free (distant);
- distant = referrer->referee_head;
- }
- else
- distant = distant->next;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Iterate over all currently known peers, add them to the
- * fast gossip list for this peer so we get DV routing information
- * out as fast as possible!
- *
- * @param cls the direct neighbor we will gossip to
- * @param key the hashcode of the peer
- * @param value the distant neighbor we should add to the list
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
- */
-static int
-add_all_extended_peers (void *cls, const struct GNUNET_HashCode * key, void
*value)
-{
- struct NeighborSendContext *send_context = (struct NeighborSendContext *)
cls;
- struct DistantNeighbor *distant = (struct DistantNeighbor *) value;
- struct FastGossipNeighborList *gossip_entry;
-
- if (memcmp
- (&send_context->toNeighbor->identity, &distant->identity,
- sizeof (struct GNUNET_PeerIdentity)) == 0)
- return GNUNET_YES; /* Don't gossip to a peer about itself! */
-
-#if SUPPORT_HIDING
- if (distant->hidden == GNUNET_YES)
- return GNUNET_YES; /* This peer should not be gossipped about
(hidden) */
-#endif
- gossip_entry = GNUNET_malloc (sizeof (struct FastGossipNeighborList));
- gossip_entry->about = distant;
-
- GNUNET_CONTAINER_DLL_insert_after (send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- send_context->fast_gossip_list_tail,
- gossip_entry);
-
- return GNUNET_YES;
-}
-
-
-/**
- * Iterate over all current direct peers, add newly connected peer
- * to the fast gossip list for that peer so we get DV routing
- * information out as fast as possible!
- *
- * @param cls the newly connected neighbor we will gossip about
- * @param key the hashcode of the peer
- * @param value the direct neighbor we should gossip to
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
- */
-static int
-add_all_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void
*value)
-{
- struct DirectNeighbor *direct = (struct DirectNeighbor *) value;
- struct DirectNeighbor *to = (struct DirectNeighbor *) cls;
- struct DistantNeighbor *distant;
- struct NeighborSendContext *send_context = direct->send_context;
- struct FastGossipNeighborList *gossip_entry;
- char *direct_id;
-
-
- distant =
- GNUNET_CONTAINER_multihashmap_get (extended_neighbors,
- &to->identity.hashPubKey);
- if (distant == NULL)
- {
- return GNUNET_YES;
- }
-
- if (memcmp
- (&direct->identity, &to->identity,
- sizeof (struct GNUNET_PeerIdentity)) == 0)
- {
- return GNUNET_YES; /* Don't gossip to a peer about itself! */
- }
-
-#if SUPPORT_HIDING
- if (distant->hidden == GNUNET_YES)
- return GNUNET_YES; /* This peer should not be gossipped about
(hidden) */
-#endif
- direct_id = GNUNET_strdup (GNUNET_i2s (&direct->identity));
-#if DEBUG_DV_GOSSIP
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "%s: adding peer %s to fast send list for %s\n", my_short_id,
- GNUNET_i2s (&distant->identity), direct_id);
-#endif
- GNUNET_free (direct_id);
- gossip_entry = GNUNET_malloc (sizeof (struct FastGossipNeighborList));
- gossip_entry->about = distant;
-
- GNUNET_CONTAINER_DLL_insert_after (send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- send_context->fast_gossip_list_tail,
- gossip_entry);
- if (send_context->task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (send_context->task);
-
- send_context->task =
- GNUNET_SCHEDULER_add_now (&neighbor_send_task, send_context);
- //tc.reason = GNUNET_SCHEDULER_REASON_TIMEOUT;
- //neighbor_send_task(send_context, &tc);
- return GNUNET_YES;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-#endif
-
-
-
-/**
* Method called whenever a peer connects.
*
* @param cls closure
@@ -2168,7 +892,7 @@
GNUNET_MESSAGE_TYPE_DV_START,
sizeof (struct GNUNET_MessageHeader) },
{ &handle_dv_send_message, NULL,
- GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND,
+ GNUNET_MESSAGE_TYPE_DV_SEND,
0},
{NULL, NULL, 0, 0}
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r26393 - gnunet/src/dv,
gnunet <=