{
struct ReadyList *head = neighbor->plugins;
struct PeerAddressList *addresses;
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Relative min_latency = GNUNET_TIME_relative_get_forever();
+ struct PeerAddressList *best_address;
+
+ best_address = NULL;
while (head != NULL)
{
addresses = head->addresses;
- while ((addresses != NULL) &&
- ((addresses->connected != GNUNET_YES) ||
- (addresses->transmit_ready != GNUNET_YES)))
- {
- addresses = addresses->next;
- }
- if (addresses != NULL)
+ while (addresses != NULL)
{
+ if ((addresses->timeout.value < now.value) && (addresses->connected == GNUNET_YES))
+ {
#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Found ready address, connected is %d\n",
- addresses->connected);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Marking long-time inactive connection to `%4s' as down.\n",
+ GNUNET_i2s (&addresses->ready_list->neighbor->id));
#endif
- return addresses;
+ addresses->connected = GNUNET_NO;
+ }
+ addresses = addresses->next;
}
-
- head = head->next;
- }
- return NULL;
-
-#if 0 /* Do some checks to keep everything sane, return lowest latency connection */
- while (pos != NULL)
- {
- /* set plugins that are inactive for a long time back to disconnected */
- if ((pos->timeout.value < now.value) && (pos->connected == GNUNET_YES))
+ addresses = head->addresses;
+ while (addresses != NULL)
{
+ if ((addresses->connected == GNUNET_YES) &&
+ (addresses->transmit_ready == GNUNET_YES) &&
+ ((addresses->latency.value < min_latency.value) || (best_address == NULL)))
+ {
#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Marking long-time inactive connection to `%4s' as down.\n",
- GNUNET_i2s (&neighbor->id));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found address with latency %llu, setting as best found yet!\n",
+ addresses->latency.value);
#endif
- pos->connected = GNUNET_NO;
+ best_address = addresses;
+ }
+ addresses = addresses->next;
}
- if (GNUNET_YES == pos->transmit_ready)
- {
+ head = head->next;
+ }
#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Found transmit_ready flag...\n");
-#endif
- }
- if (((GNUNET_YES == pos->transmit_ready) ||
- (mq->internal_msg)) &&
- (pos->connect_attempts < MAX_CONNECT_RETRY) &&
- ((rl == NULL) || (min_latency.value > pos->latency.value)))
- {
- rl = pos;
- min_latency = pos->latency;
- }
- pos = pos->next;
+ if (best_address != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Best address found has latency of %llu!\n",
+ best_address->latency.value);
}
#endif
+ return best_address;
+
}
/**
* The peer specified by the given neighbor has timed-out or a plugin
* has disconnected. We may either need to do nothing (other plugins
* still up), or trigger a full disconnect and clean up. This
- * function updates our state and do the necessary notifications.
+ * function updates our state and does the necessary notifications.
* Also notifies our clients that the neighbor is now officially
* gone.
*
* disconnect?
*/
static void
-disconnect_neighbor (struct NeighborList *n, int check)
+disconnect_neighbor (struct NeighborList *current_handle, int check)
{
struct ReadyList *rpos;
struct NeighborList *npos;
struct NeighborList *nprev;
+ struct NeighborList *n;
struct MessageQueue *mq;
struct PeerAddressList *peer_addresses;
+ if (neighbors == NULL)
+ return; /* We don't have any neighbors, so client has an already removed handle! */
+
+ npos = neighbors;
+ while ((npos != NULL) && (current_handle != npos))
+ npos = npos->next;
+
+ if (npos == NULL)
+ return; /* Couldn't find neighbor in existing list, must have been already removed! */
+ else
+ n = npos;
+
if (GNUNET_YES == check)
{
rpos = n->plugins;
const struct GNUNET_MessageHeader *message)
{
const struct TryConnectMessage *tcm;
-
+ struct NeighborList *neighbor;
tcm = (const struct TryConnectMessage *) message;
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received `%s' request from client %p asking to connect to `%4s'\n",
"TRY_CONNECT", client, GNUNET_i2s (&tcm->peer));
#endif
- if (NULL == find_neighbor (&tcm->peer))
+ neighbor = find_neighbor(&tcm->peer);
+
+ if (neighbor == NULL)
setup_new_neighbor (&tcm->peer);
-#if DEBUG_TRANSPORT
else
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Client asked to connect to `%4s', but connection already exists\n",
- "TRY_CONNECT", GNUNET_i2s (&tcm->peer));
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Client asked to connect to `%4s', but connection already exists\n",
+ "TRY_CONNECT", GNUNET_i2s (&tcm->peer));
#endif
+ transmit_to_peer (NULL, NULL, 0,
+ (const char *) our_hello, GNUNET_HELLO_size(our_hello),
+ GNUNET_YES, neighbor);
+ notify_clients_connect (&tcm->peer, GNUNET_TIME_UNIT_FOREVER_REL);
+ }
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
#include "gnunet_transport_service.h"
#include "transport.h"
-#define VERBOSE GNUNET_YES
+#define VERBOSE GNUNET_NO
#define VERBOSE_ARM GNUNET_NO
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ok is (%d)!\n",
ok);
- GNUNET_assert (ok == 7);
- OKPP;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from peer (%p)!\n",
ntohs(message->type), cls);
+ GNUNET_assert (ok == 7);
+ OKPP;
+
GNUNET_assert (MTYPE == ntohs (message->type));
GNUNET_assert (sizeof (struct GNUNET_MessageHeader) ==
ntohs (message->size));
message, &me->id));
GNUNET_TRANSPORT_offer_hello (p1.th, message);
+
+ /*sleep(10);*/ /* Make sure we are not falling prey to the "favorable timing" bug...
+
+ /* both HELLOs exchanged, get ready to test transmission! */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Finished exchanging HELLOs, now waiting for transmission!\n");
- /* both HELLOs exchanged, get ready to test transmission! */
GNUNET_TRANSPORT_notify_transmit_ready (p1.th,
- &p2.id,
- 256, 0, TIMEOUT, ¬ify_ready,
- &p1);
+ &p2.id,
+ 256, 0, TIMEOUT, ¬ify_ready,
+ &p1);
}
-
static void
exchange_hello (void *cls,
const struct GNUNET_MessageHeader *message)
#include "gnunet_time_lib.h"
#include "gnunet_transport_service.h"
-#define DEBUG_TRANSPORT GNUNET_YES
+#define DEBUG_TRANSPORT GNUNET_NO
/**
* For how long do we allow unused bandwidth
struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
struct TryConnectMessage *tcm;
struct GNUNET_TRANSPORT_Handle *h;
+ struct NeighbourList *n;
GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK);
h = th->handle;
+
+ n = find_neighbour(h, &tcm->peer);
+
+ if (n != NULL)
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Asked to TRY_CONNECT to already connected peer!\n");
+#endif
+ return GNUNET_YES;
+ }
+
+
if (buf == NULL)
{
#if DEBUG_TRANSPORT
h->connect_wait_head = next;
else
prev->next = next;
-// if (GNUNET_YES == n->received_ack)
-// {
+#if ACK
+ if (GNUNET_YES == n->received_ack)
+ {
+#endif
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Found pending request for `%4s' will trigger it now.\n",
pos->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
schedule_request (pos);
-// }
+#if ACK
+ }
+#endif
break;
}
struct NeighbourList *n;
struct GNUNET_PeerIdentity me;
struct GNUNET_TRANSPORT_TransmitHandle *th;
+
+ struct GNUNET_TRANSPORT_TransmitHandle *prev;
+ struct GNUNET_TRANSPORT_TransmitHandle *pos;
+ struct GNUNET_TRANSPORT_TransmitHandle *next;
uint16_t size;
if ((msg == NULL) || (h->client == NULL))
"Receiving `%s' message for `%4s'.\n",
"CONNECT", GNUNET_i2s (&cim->id));
#endif
- add_neighbour (h,
- ntohl (cim->quota_out),
- GNUNET_TIME_relative_ntoh (cim->latency), ntohs(cim->distance), &cim->id);
+ if (find_neighbour(h, &cim->id) == NULL)
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Don't know neighbor, adding!\n");
+#endif
+ add_neighbour (h,
+ ntohl (cim->quota_out),
+ GNUNET_TIME_relative_ntoh (cim->latency), ntohs(cim->distance), &cim->id);
+ }
+ else
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Do know neighbor, scheduling transmission!\n");
+#endif
+ n = find_neighbour(h, &cim->id);
+ n->received_ack = GNUNET_YES;
+ if (NULL != n->transmit_handle)
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer connected, scheduling delayed message for delivery now.\n");
+#endif
+ schedule_request (n->transmit_handle);
+ }
+ else
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transmit handle is null... Checking for pending stuff(?)\n");
+#endif
+ prev = NULL;
+ pos = h->connect_wait_head;
+ while (pos != NULL)
+ {
+ next = pos->next;
+ if (0 == memcmp (&cim->id,
+ &pos->target, sizeof (struct GNUNET_PeerIdentity)))
+ {
+ pos->neighbour = n;
+ GNUNET_assert (NULL == n->transmit_handle);
+ n->transmit_handle = pos;
+ if (prev == NULL)
+ h->connect_wait_head = next;
+ else
+ prev->next = next;
+#if ACK
+ if (GNUNET_YES == n->received_ack)
+ {
+#endif
+ #if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found pending request for `%4s' will trigger it now.\n",
+ GNUNET_i2s (&pos->target));
+ #endif
+ if (pos->notify_delay_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (h->sched, pos->notify_delay_task);
+ pos->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ schedule_request (pos);
+#if ACK
+ }
+#endif
+
+ break;
+ }
+ prev = pos;
+ pos = next;
+ }
+ }
+ }
+
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT:
if (size != sizeof (struct DisconnectInfoMessage))
#endif
GNUNET_assert (NULL == n->transmit_handle);
n->transmit_handle = th;
- if (GNUNET_YES != n->received_ack)
+ if (GNUNET_YES != n->transmit_ok)
{
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,