[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r10320 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r10320 - gnunet/src/transport |
Date: |
Tue, 16 Feb 2010 10:25:37 +0100 |
Author: grothoff
Date: 2010-02-16 10:25:37 +0100 (Tue, 16 Feb 2010)
New Revision: 10320
Modified:
gnunet/src/transport/gnunet-service-transport.c
Log:
avoid linked list traversal, more code clean up
Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c 2010-02-16 09:25:11 UTC
(rev 10319)
+++ gnunet/src/transport/gnunet-service-transport.c 2010-02-16 09:25:37 UTC
(rev 10320)
@@ -45,6 +45,12 @@
#include "transport.h"
/**
+ * Should we do some additional checks (to validate behavior
+ * of clients)?
+ */
+#define EXTRA_CHECKS GNUNET_YES
+
+/**
* How many messages can we have pending for a given client process
* before we start to drop incoming messages? We typically should
* have only one client and so this would be the primary buffer for
@@ -164,24 +170,20 @@
struct GNUNET_TIME_Absolute timeout;
/**
- * Is this plugin currently connected? The first time we transmit
- * or send data to a peer via a particular plugin, we set this to
- * GNUNET_YES. If we later get an error (disconnect notification or
- * transmission failure), we set it back to GNUNET_NO. Each time
- * the value is set to GNUNET_YES, we increment the
- * "connect_attempts" counter. If that one reaches a particular
- * threshold, we consider the address to not be working properly at
- * this time and remove it from the eligible list.
+ * Are we currently connected via this address? The first time we
+ * successfully transmit or receive data to a peer via a particular
+ * address, we set this to GNUNET_YES. If we later get an error
+ * (disconnect notification, transmission failure, timeout), we set
+ * it back to GNUNET_NO.
*/
int connected;
/**
- * Is this plugin ready to transmit to the specific target?
- * GNUNET_NO if not. Initially, all plugins are marked ready. If a
- * transmission is in progress, "transmit_ready" is set to
- * GNUNET_NO.
+ * Is this plugin currently busy transmitting to the specific target?
+ * GNUNET_NO if not (initial, default state is GNUNET_NO). Internal
+ * messages do not count as 'in transmit'.
*/
- int transmit_ready;
+ int in_transmit;
/**
* Has this address been validated yet?
@@ -189,7 +191,9 @@
int validated;
/**
- * How often have we tried to connect using this plugin?
+ * How often have we tried to connect using this plugin? Used to
+ * discriminate against addresses that do not work well.
+ * FIXME: not yet used, but should be!
*/
unsigned int connect_attempts;
@@ -290,11 +294,16 @@
{
/**
- * This is a linked list.
+ * This is a doubly linked list.
*/
struct MessageQueue *next;
/**
+ * This is a doubly linked list.
+ */
+ struct MessageQueue *prev;
+
+ /**
* The message(s) we want to transmit, GNUNET_MessageHeader(s)
* stuck together in memory. Allocated at the end of this struct.
*/
@@ -368,12 +377,6 @@
*/
struct ForeignAddressList *addresses;
- /**
- * Is the plugin represented by this entry currently connected to
- * the respective peer?
- */
- int connected;
-
};
@@ -395,12 +398,18 @@
struct ReadyList *plugins;
/**
- * List of messages we would like to send to this peer;
+ * Head of list of messages we would like to send to this peer;
* must contain at most one message per client.
*/
- struct MessageQueue *messages;
+ struct MessageQueue *messages_head;
/**
+ * Tail of list of messages we would like to send to this peer; must
+ * contain at most one message per client.
+ */
+ struct MessageQueue *messages_tail;
+
+ /**
* Identity of this neighbor.
*/
struct GNUNET_PeerIdentity id;
@@ -429,9 +438,12 @@
* over multiple transports. This value reflects how long it took
* us to receive a response when SENDING via this particular
* transport/neighbor/address combination!
- * FIXME: why is this NBO?
+ *
+ * FIXME: we need to periodically send PINGs to update this
+ * latency (at least more often than the current "huge" (11h?)
+ * update interval).
*/
- struct GNUNET_TIME_RelativeNBO latency;
+ struct GNUNET_TIME_Relative latency;
/**
* How many bytes have we received since the "last_quota_update"
@@ -1023,25 +1035,25 @@
if (result == GNUNET_OK)
{
- mq->specific_address->timeout =
- GNUNET_TIME_relative_to_absolute
- (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
+ if (mq->specific_address != NULL)
+ {
+ mq->specific_address->timeout =
+ GNUNET_TIME_relative_to_absolute
+ (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
+ mq->specific_address->connected = GNUNET_YES;
+ }
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transmission to peer `%s' failed, marking connection as
down.\n",
GNUNET_i2s (target));
- mq->specific_address->connected = GNUNET_NO;
+ if (mq->specific_address != NULL)
+ mq->specific_address->connected = GNUNET_NO;
}
- if (!mq->internal_msg)
- {
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Setting transmit_ready on transport!\n");
-#endif
- mq->specific_address->transmit_ready = GNUNET_YES;
- }
+ if ( (! mq->internal_msg) &&
+ (mq->specific_address != NULL) )
+ mq->specific_address->in_transmit = GNUNET_NO;
if (mq->client != NULL)
{
@@ -1106,7 +1118,7 @@
if ( ( (best_address == NULL) ||
(addresses->connected == GNUNET_YES) ||
(best_address->connected == GNUNET_NO) ) &&
- (addresses->transmit_ready == GNUNET_YES) &&
+ (addresses->in_transmit == GNUNET_NO) &&
( (best_address == NULL) ||
(addresses->latency.value < best_address->latency.value)) )
best_address = addresses;
@@ -1142,11 +1154,11 @@
struct ReadyList *rl;
struct MessageQueue *mq;
- if (neighbor->messages == NULL)
+ if (neighbor->messages_head == NULL)
return; /* nothing to do */
min_latency = GNUNET_TIME_UNIT_FOREVER_REL;
rl = NULL;
- mq = neighbor->messages;
+ mq = neighbor->messages_head;
if (mq->specific_address == NULL)
mq->specific_address = find_ready_address(neighbor);
if (mq->specific_address == NULL)
@@ -1159,11 +1171,15 @@
#endif
return; /* nobody ready */
}
+ if (mq->specific_address->connected == GNUNET_NO)
+ mq->specific_address->connect_attempts++;
rl = mq->specific_address->ready_list;
- neighbor->messages = mq->next;
+ GNUNET_CONTAINER_DLL_remove (neighbor->messages_head,
+ neighbor->messages_tail,
+ mq);
mq->plugin = rl->plugin;
if (!mq->internal_msg)
- mq->specific_address->transmit_ready = GNUNET_NO;
+ mq->specific_address->in_transmit = GNUNET_YES;
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending message of size %u for `%4s' to `%s' via plugin `%s'\n",
@@ -1194,7 +1210,8 @@
* @param priority how important is the message
* @param message_buf message(s) to send GNUNET_MessageHeader(s)
* @param message_buf_size total size of all messages in message_buf
- * @param is_internal is this an internal message
+ * @param is_internal is this an internal message; these are pre-pended and
+ * also do not count for plugins being "ready" to transmit
* @param neighbor handle to the neighbor for transmission
*/
static void
@@ -1206,12 +1223,12 @@
int is_internal, struct NeighborList *neighbor)
{
struct MessageQueue *mq;
- struct MessageQueue *mqe;
+#if EXTRA_CHECKS
if (client != NULL)
{
/* check for duplicate submission */
- mq = neighbor->messages;
+ mq = neighbor->messages_head;
while (NULL != mq)
{
if (mq->client == client)
@@ -1224,6 +1241,7 @@
mq = mq->next;
}
}
+#endif
mq = GNUNET_malloc (sizeof (struct MessageQueue) + message_buf_size);
mq->specific_address = peer_address;
mq->client = client;
@@ -1234,30 +1252,15 @@
mq->internal_msg = is_internal;
mq->priority = priority;
- if (is_internal)
- {
- /* append at head */
- mq->next = neighbor->messages;
- neighbor->messages = mq;
- }
+ if (is_internal)
+ GNUNET_CONTAINER_DLL_insert (neighbor->messages_head,
+ neighbor->messages_tail,
+ mq);
else
- {
- /* find tail */
- mqe = neighbor->messages;
- if (mqe != NULL)
- while (mqe->next != NULL)
- mqe = mqe->next;
- if (mqe == NULL)
- {
- /* new head */
- neighbor->messages = mq;
- }
- else
- {
- /* append */
- mqe->next = mq;
- }
- }
+ GNUNET_CONTAINER_DLL_insert_after (neighbor->messages_head,
+ neighbor->messages_tail,
+ neighbor->messages_tail,
+ mq);
try_transmission_to_peer (neighbor);
}
@@ -1609,7 +1612,6 @@
ret->expires = GNUNET_TIME_relative_to_absolute
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
ret->latency = GNUNET_TIME_relative_get_forever();
- ret->transmit_ready = GNUNET_YES;
ret->timeout = GNUNET_TIME_relative_to_absolute
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
ret->ready_list = head;
@@ -1725,6 +1727,10 @@
fal->expires = GNUNET_TIME_relative_to_absolute
(HELLO_ADDRESS_EXPIRATION);
fal->validated = GNUNET_YES;
fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
+ if (n->latency.value == GNUNET_TIME_UNIT_FOREVER_REL.value)
+ n->latency = fal->latency;
+ else
+ n->latency.value = (fal->latency.value + n->latency.value) / 2;
}
/* clean up validation entry */
@@ -1854,6 +1860,7 @@
}
tp = tp->next;
}
+ n->latency = GNUNET_TIME_UNIT_FOREVER_REL;
n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
&neighbor_timeout_task, n);
@@ -2059,10 +2066,10 @@
"HELLO", hello_size,
"PING", sizeof (struct TransportPingMessage));
#endif
- transmit_to_peer(NULL, peer_address,
- GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- message_buf, tsize,
- GNUNET_YES, neighbor);
+ transmit_to_peer (NULL, peer_address,
+ GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+ message_buf, tsize,
+ GNUNET_YES, neighbor);
GNUNET_free(message_buf);
return GNUNET_OK;
}
@@ -2100,6 +2107,8 @@
#endif
fal = add_peer_address (n, tname, addr, addrlen);
}
+ if (fal == NULL)
+ return GNUNET_OK;
fal->expires = GNUNET_TIME_absolute_max (expiration,
fal->expires);
fal->validated = GNUNET_YES;
@@ -2320,8 +2329,7 @@
while (NULL != (rpos = n->plugins))
{
n->plugins = rpos->next;
- if (GNUNET_YES == rpos->connected)
- rpos->plugin->api->disconnect (rpos->plugin->api->cls, &n->id);
+ rpos->plugin->api->disconnect (rpos->plugin->api->cls, &n->id);
while (rpos->addresses != NULL)
{
@@ -2333,9 +2341,11 @@
}
/* free all messages on the queue */
- while (NULL != (mq = n->messages))
+ while (NULL != (mq = n->messages_head))
{
- n->messages = mq->next;
+ GNUNET_CONTAINER_DLL_remove (n->messages_head,
+ n->messages_tail,
+ mq);
GNUNET_assert (0 == memcmp(&mq->neighbor_id,
&n->id,
sizeof(struct GNUNET_PeerIdentity)));
@@ -2475,7 +2485,6 @@
if (message == NULL)
return; /* disconnect of peer already marked down */
n = setup_new_neighbor (peer);
-
}
service_context = n->plugins;
while ((service_context != NULL) && (plugin != service_context->plugin))
@@ -2489,8 +2498,6 @@
GNUNET_i2s (&n->id));
#endif
/* TODO: call stats */
- if (service_context != NULL)
- service_context->connected = GNUNET_NO;
disconnect_neighbor (n, GNUNET_YES);
return;
}
@@ -2498,15 +2505,11 @@
plugin->short_name,
sender_address,
sender_address_len);
- if (service_context != NULL)
+ if (peer_address != NULL)
{
- if (service_context->connected == GNUNET_NO)
+ if (peer_address->connected == GNUNET_NO)
{
- service_context->connected = GNUNET_YES;
- /* FIXME: What to do here? Should we use these as well,
- to specify some Address in the AddressList should be
- available? */
- peer_address->transmit_ready = GNUNET_YES;
+ peer_address->connected = GNUNET_YES;
peer_address->connect_attempts++;
}
peer_address->timeout
@@ -2557,7 +2560,7 @@
im = GNUNET_malloc (sizeof (struct InboundMessage) + msize);
im->header.size = htons (sizeof (struct InboundMessage) + msize);
im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
- im->latency = n->latency;
+ im->latency = GNUNET_TIME_relative_hton (n->latency);
im->peer = *peer;
memcpy (&im[1], message, msize);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r10320 - gnunet/src/transport,
gnunet <=