*/
struct GNUNET_TRANSPORT_TransmitHandle *ret;
- /**
- * Temporary transmit handle.
- */
- struct GNUNET_TRANSPORT_TransmitHandle *th;
-
/**
* Time to retry the send task.
*/
};
-// FIXME: replace with hash map!
/**
* Get the neighbour list entry for the given peer
*
neighbour_find (struct GNUNET_TRANSPORT_Handle *h,
const struct GNUNET_PeerIdentity *peer)
{
- if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains(h->neighbours, &peer->hashPubKey))
- return NULL;
-
return GNUNET_CONTAINER_multihashmap_get(h->neighbours, &peer->hashPubKey);
}
schedule_transmission (h);
}
+
/**
* Iterator over hash map entries, attempt to schedule
* a transmission to entries in the neighbour hashmap.
struct TryTransmitContext *try_transmit_ctx = cls;
struct GNUNET_TIME_Relative duration;
GNUNET_CONNECTION_TransmitReadyNotify notify;
+ struct GNUNET_TRANSPORT_TransmitHandle *th;
+ struct GNUNET_TIME_Absolute duration_abs;
if (n->transmit_stage != TS_QUEUED)
return GNUNET_YES; /* not eligible, keep iterating */
if (n->is_connected != GNUNET_YES)
return GNUNET_YES; /* keep iterating */
- try_transmit_ctx->th = &n->transmit_handle;
- GNUNET_break (n == try_transmit_ctx->th->neighbour);
+ th = &n->transmit_handle;
+ GNUNET_break (n == th->neighbour);
/* check outgoing quota */
duration = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker,
- try_transmit_ctx->th->notify_size - sizeof (struct OutboundMessage));
- struct GNUNET_TIME_Absolute duration_abs = GNUNET_TIME_relative_to_absolute (duration);
- if (try_transmit_ctx->th->timeout.abs_value < duration_abs.abs_value)
+ th->notify_size - sizeof (struct OutboundMessage));
+ duration_abs = GNUNET_TIME_relative_to_absolute (duration);
+ if (th->timeout.abs_value < duration_abs.abs_value)
{
/* signal timeout! */
#if DEBUG_TRANSPORT
duration.rel_value,
GNUNET_i2s (&n->id));
#endif
- if (try_transmit_ctx->th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK)
+ if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK)
{
- GNUNET_SCHEDULER_cancel (try_transmit_ctx->th->notify_delay_task);
- try_transmit_ctx->th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_SCHEDULER_cancel (th->notify_delay_task);
+ th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
n->transmit_stage = TS_NEW;
- if (NULL != (notify = try_transmit_ctx->th->notify))
+ if (NULL != (notify = th->notify))
{
- try_transmit_ctx->th->notify = NULL;
- GNUNET_assert (0 == notify (try_transmit_ctx->th->notify_cls, 0, NULL));
+ th->notify = NULL;
+ GNUNET_assert (0 == notify (th->notify_cls, 0, NULL));
}
return GNUNET_YES; /* keep iterating */
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Need more bandwidth (%u b/s allowed, %u b needed), delaying delivery to `%4s' by %llu ms\n",
(unsigned int) n->out_tracker.available_bytes_per_s__,
- (unsigned int) try_transmit_ctx->th->notify_size - sizeof (struct OutboundMessage),
+ (unsigned int) th->notify_size - sizeof (struct OutboundMessage),
GNUNET_i2s (&n->id),
- duration.rel_value);
+ (unsigned long long) duration.rel_value);
#endif
try_transmit_ctx->retry_time = GNUNET_TIME_relative_min (try_transmit_ctx->retry_time,
duration);
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Have %u bytes of bandwidth available for transmission to `%4s' right now\n",
- try_transmit_ctx->th->notify_size - sizeof (struct OutboundMessage),
+ th->notify_size - sizeof (struct OutboundMessage),
GNUNET_i2s (&n->id));
#endif
if ( (try_transmit_ctx->ret == NULL) ||
- (try_transmit_ctx->ret->priority < try_transmit_ctx->th->priority) )
- try_transmit_ctx->ret = try_transmit_ctx->th;
-
+ (try_transmit_ctx->ret->priority < th->priority) )
+ try_transmit_ctx->ret = th;
return GNUNET_YES;
}
+
/**
* Figure out which transmission to a peer can be done right now.
* If none can, schedule a task to call 'schedule_transmission'
static struct GNUNET_TRANSPORT_TransmitHandle *
schedule_peer_transmission (struct GNUNET_TRANSPORT_Handle *h)
{
-
struct TryTransmitContext try_transmit_ctx;
if (h->quota_task != GNUNET_SCHEDULER_NO_TASK)
GNUNET_SCHEDULER_cancel (h->quota_task);
h->quota_task = GNUNET_SCHEDULER_NO_TASK;
}
- memset(&try_transmit_ctx, 0, sizeof(struct TryTransmitContext));
+ try_transmit_ctx.h = h;
+ try_transmit_ctx.ret = NULL;
try_transmit_ctx.retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
- GNUNET_CONTAINER_multihashmap_iterate(h->neighbours, &try_schedule_transmission, &try_transmit_ctx);
-
+ GNUNET_CONTAINER_multihashmap_iterate(h->neighbours,
+ &try_schedule_transmission,
+ &try_transmit_ctx);
if (try_transmit_ctx.ret == NULL)
h->quota_task = GNUNET_SCHEDULER_add_delayed (try_transmit_ctx.retry_time,
"a_transmit_ready,
}
+/**
+ * FIXME: document
+ */
struct SetQuotaContext
{
+ /**
+ * FIXME: document
+ */
struct GNUNET_TRANSPORT_Handle *handle;
+ /**
+ * FIXME: document
+ */
struct GNUNET_PeerIdentity target;
+ /**
+ * FIXME: document
+ */
GNUNET_SCHEDULER_Task cont;
+ /**
+ * Closure for 'cont'.
+ */
void *cont_cls;
+ /**
+ * FIXME: document
+ */
struct GNUNET_TIME_Absolute timeout;
+ /**
+ * FIXME: document
+ */
struct GNUNET_BANDWIDTH_Value32NBO quota_in;
};
n->transmit_handle.notify = NULL;
}
*/
-
+ /* NATE: if the above is not needed, then clearly this assertion
+ should hold (I've checked the code and I'm pretty sure this is
+ true. -CG
+ FIXME: remove above comments once we've seen tests pass with the assert... */
+ GNUNET_assert (n->transmit_handle.notify_delay_task == GNUNET_SCHEDULER_NO_TASK);
GNUNET_assert (n->transmit_handle.notify == NULL);
h = n->h;
#if DEBUG_TRANSPORT
GNUNET_break (n->is_connected == GNUNET_NO);
GNUNET_break (n->transmit_stage == TS_NEW);
- GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(h->neighbours, &n->id.hashPubKey, n));
-
+ GNUNET_assert(GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove(h->neighbours,
+ &n->id.hashPubKey,
+ n));
GNUNET_free (n);
}
#endif
GNUNET_break (n->is_connected == GNUNET_YES);
n->is_connected = GNUNET_NO;
+ /* FIXME: this 'in_disconnect' flag is dubious; we should define
+ clearly what disconnect means for pending 'notify_transmit_ready'
+ requests; maybe a good approach is to REQUIRE clients to
+ call 'notify_transmit_ready_cancel' on pending requests on disconnect
+ and otherwise FAIL HARD with an assertion failure before
+ 'neighbour_free' right here (transmit_stage would be forced
+ to 'TS_NEW') */
n->in_disconnect = GNUNET_YES;
if (h->nd_cb != NULL)
h->nd_cb (h->cls, &n->id);
void *value)
{
struct NeighbourList *n = value;
+
#if DEBUG_TRANSPORT_DISCONNECT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Disconnecting due to reconnect being called\n");
return GNUNET_YES;
}
+
/**
* Try again to connect to transport service.
*
return;
}
/* Forget about all neighbours that we used to be connected to */
- GNUNET_CONTAINER_multihashmap_iterate(h->neighbours, &forget_neighbours, NULL);
+ GNUNET_CONTAINER_multihashmap_iterate(h->neighbours,
+ &forget_neighbours,
+ NULL);
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_TIME_UNIT_FOREVER_REL, &send_transport_request_connect, trcm);
}
+
/**
* Add neighbour to our list
*
return n;
}
+
/**
* Iterator over hash map entries, for deleting state of a neighbor.
*
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport disconnect called!\n");
#endif
+ /* FIXME: this flag is dubious, we should be able to do this
+ more cleanly; also, we should probably do 'disconnect'
+ callbacks for every connected peer here, i.e. by calling
+ the iterator with 'forget_neighbours' instead of 'delete_neighbours'.
+ */
+
handle->in_disconnect = GNUNET_YES;
- GNUNET_assert(GNUNET_SYSERR !=
- GNUNET_CONTAINER_multihashmap_iterate(handle->neighbours,
- &delete_neighbours,
- handle));
- GNUNET_CONTAINER_multihashmap_destroy(handle->neighbours);
+ GNUNET_assert (GNUNET_SYSERR !=
+ GNUNET_CONTAINER_multihashmap_iterate(handle->neighbours,
+ &delete_neighbours,
+ handle));
+ GNUNET_CONTAINER_multihashmap_destroy (handle->neighbours);
while (NULL != (hwl = handle->hwl_head))
{
struct NeighbourList *n;
struct GNUNET_PeerIdentity me;
uint16_t size;
+ uint32_t ats_count;
if (h->client == NULL)
{
}
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT:
- if (size != sizeof (struct ConnectInfoMessage))
+
+ if (size < sizeof (struct ConnectInfoMessage))
{
GNUNET_break (0);
break;
}
cim = (const struct ConnectInfoMessage *) msg;
+ ats_count = ntohl (cim->ats_count);
+ if (size != sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information))
+ {
+ GNUNET_break (0);
+ break;
+ }
+
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Receiving `%s' message for `%4s'.\n",
#endif
n = neighbour_find (h, &cim->id);
if (n == NULL)
- n = neighbour_add (h,
- &cim->id);
+ n = neighbour_add (h, &cim->id);
if (n == NULL)
- {
- GNUNET_break (0);
- return;
- }
+ return;
GNUNET_break (n->is_connected == GNUNET_NO);
- if (ntohl ((&cim->ats)[ntohl (cim->ats_count)].type) != GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR)
- {
- GNUNET_break (0);
- return;
- }
- fprintf(stderr,"transport_api GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT ats_count %u\n",ntohl (cim->ats_count));
n->is_connected = GNUNET_YES;
+ /* FIXME */
if (h->nc_cb != NULL)
- h->nc_cb (h->cls, &n->id,
- NULL,
- 0);
-
- /* FIX if (h->nc_cb != NULL)
h->nc_cb (h->cls, &n->id,
- &(cim->ats),
- ntohl (cim->ats_count));*/
+ &cim->ats,ats_count);
+ /* FIXEND */
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT:
if (size != sizeof (struct DisconnectInfoMessage))
}
im = (const struct InboundMessage *) msg;
GNUNET_break (0 == ntohl (im->reserved));
- GNUNET_assert(sizeof (struct InboundMessage) + ntohl(im->ats_count) * sizeof(struct GNUNET_TRANSPORT_ATS_Information) + sizeof (struct GNUNET_MessageHeader) <= size);
- imm = (const struct GNUNET_MessageHeader *) &((&im->ats)[ntohl(im->ats_count)+1]);
- if (ntohs (imm->size) + sizeof (struct InboundMessage) + ntohl(im->ats_count) * sizeof(struct GNUNET_TRANSPORT_ATS_Information) != size)
+ ats_count = ntohl(im->ats_count);
+ //imm = (const struct GNUNET_MessageHeader *) &im[1];
+ imm = (const struct GNUNET_MessageHeader *) &((&(im->ats))[ats_count+1]);
+
+ if (ntohs (imm->size) + sizeof (struct InboundMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) != size)
{
GNUNET_break (0);
break;
GNUNET_break (0);
break;
}
- if (ntohl ((&im->ats)[ntohl(im->ats_count)].type) != GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR)
- {
- GNUNET_break (0);
- return;
- }
- fprintf(stderr,"transport_api GNUNET_MESSAGE_TYPE_TRANSPORT_RECV ats_count %u\n",ntohl (im->ats_count));
+ /* FIXME: */
if (h->rec != NULL)
- h->rec (h->cls, &im->peer,
- imm,
- NULL,
- 0);
- /* FIX
- h->rec (h->cls, &im->peer,
- imm,
- &im->ats,
- ntohl (im->ats_count));*/
+ h->rec (h->cls, &im->peer, imm,
+ &im->ats, ats_count);
+ /* ENDFIX */
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
break;
case TS_QUEUED:
n->transmit_stage = TS_NEW;
- if (n->in_disconnect == GNUNET_NO)
+ if ( (n->in_disconnect == GNUNET_NO) &&
+ (n->is_connected == GNUNET_NO) )
neighbour_free (n);
break;
case TS_TRANSMITTED: