[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r16637 - gnunet/src/mesh
From: |
gnunet |
Subject: |
[GNUnet-SVN] r16637 - gnunet/src/mesh |
Date: |
Tue, 30 Aug 2011 14:34:27 +0200 |
Author: grothoff
Date: 2011-08-30 14:34:27 +0200 (Tue, 30 Aug 2011)
New Revision: 16637
Modified:
gnunet/src/mesh/mesh_api_new.c
Log:
encapsulate payload, keep target/priority/etc.
Modified: gnunet/src/mesh/mesh_api_new.c
===================================================================
--- gnunet/src/mesh/mesh_api_new.c 2011-08-30 12:23:34 UTC (rev 16636)
+++ gnunet/src/mesh/mesh_api_new.c 2011-08-30 12:34:27 UTC (rev 16637)
@@ -60,14 +60,17 @@
/**
* Transmission queue to the service
*/
-struct GNUNET_MESH_queue
+struct GNUNET_MESH_TransmitHandle
{
/**
* Double Linked list
*/
- struct GNUNET_MESH_queue *next;
+ struct GNUNET_MESH_TransmitHandle *next;
- struct GNUNET_MESH_queue *prev;
+ /**
+ * Double Linked list
+ */
+ struct GNUNET_MESH_TransmitHandle *prev;
/**
* Data itself, currently points to the end of this struct if
@@ -77,8 +80,15 @@
const struct GNUNET_MessageHeader *data;
/**
+ * Tunnel this message is sent over (may be NULL for control messages).
+ */
+ struct GNUNET_MESH_Tunnel *tunnel;
+
+ /**
* Callback to obtain the message to transmit, or NULL if we
- * got the message in 'data'.
+ * got the message in 'data'. Notice that messages built
+ * by 'notify' need to be encapsulated with information about
+ * the 'target'.
*/
GNUNET_CONNECTION_TransmitReadyNotify notify;
@@ -88,6 +98,26 @@
void *notify_cls;
/**
+ * Priority of the message. The queue is sorted by priority,
+ * control messages have the maximum priority (UINT32_MAX).
+ */
+ uint32_t priority;
+
+ /**
+ * How long is this message valid. Once the timeout has been
+ * reached, the message must no longer be sent. If this
+ * is a message with a 'notify' callback set, the 'notify'
+ * function should be called with 'buf' NULL and size 0.
+ */
+ struct GNUNET_TIME_Absolute timeout;
+
+ /**
+ * Target of the message, 0 for broadcast. This field
+ * is only valid if 'notify' is non-NULL.
+ */
+ GNUNET_PEER_Id target;
+
+ /**
* Size of 'data' -- or the desired size of 'notify' if 'data' is NULL.
*/
size_t size;
@@ -141,8 +171,8 @@
/**
* Messages to send to the service
*/
- struct GNUNET_MESH_queue *queue_head;
- struct GNUNET_MESH_queue *queue_tail;
+ struct GNUNET_MESH_TransmitHandle *queue_head;
+ struct GNUNET_MESH_TransmitHandle *queue_tail;
/**
* tid of the next tunnel to create (to avoid reusing IDs often)
@@ -215,11 +245,6 @@
unsigned int npeers;
};
-struct GNUNET_MESH_TransmitHandle
-{
- struct GNUNET_MESH_Tunnel *t;
- struct GNUNET_MESH_queue *q;
-};
/******************************************************************************/
/*********************** AUXILIARY FUNCTIONS
*************************/
@@ -250,11 +275,11 @@
* Get the length of the transmission queue
* @param h mesh handle whose queue is to be measured
*/
-static uint32_t
+static unsigned int
get_queue_length (struct GNUNET_MESH_Handle *h)
{
- struct GNUNET_MESH_queue *q;
- uint32_t i;
+ struct GNUNET_MESH_TransmitHandle *q;
+ unsigned int i;
/* count */
for (q = h->queue_head, i = 0; NULL != q; q = q->next, i++) ;
@@ -481,7 +506,7 @@
send_raw (void *cls, size_t size, void *buf)
{
struct GNUNET_MESH_Handle *h = cls;
- struct GNUNET_MESH_queue *q;
+ struct GNUNET_MESH_TransmitHandle *q;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Send packet() Buffer %u\n",
size);
h->th = NULL;
@@ -506,9 +531,58 @@
ntohs (q->data->type));
if (NULL == q->data)
{
- // FIXME: need to encapsulate message with information about
- // the target (if data message -- or use wrapper for callback...)
- size = q->notify (q->notify_cls, size, buf);
+ GNUNET_assert (NULL != q->notify);
+ if (q->target == 0)
+ {
+ /* multicast */
+ struct GNUNET_MESH_Multicast mc;
+ char *cbuf;
+
+ GNUNET_assert (size >= sizeof (mc) + q->size);
+ cbuf = buf;
+ q->size = q->notify (q->notify_cls,
+ size - sizeof (mc),
+ &cbuf[sizeof(mc)]);
+ if (q->size == 0)
+ {
+ size = 0;
+ }
+ else
+ {
+ mc.header.size = htons (sizeof (mc) + q->size);
+ mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
+ mc.tid = htonl (q->tunnel->tid);
+ memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /*
myself */
+ memcpy (buf, &mc, sizeof (mc));
+ size = q->size + sizeof (mc);
+ }
+ }
+ else
+ {
+ /* unicast */
+ struct GNUNET_MESH_Unicast uc;
+ char *cbuf;
+
+ GNUNET_assert (size >= sizeof (uc) + q->size);
+ cbuf = buf;
+ q->size = q->notify (q->notify_cls,
+ size - sizeof (uc),
+ &cbuf[sizeof(uc)]);
+ if (q->size == 0)
+ {
+ size = 0;
+ }
+ else
+ {
+ uc.header.size = htons (sizeof (uc) + q->size);
+ uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ uc.tid = htonl (q->tunnel->tid);
+ memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /*
myself */
+ GNUNET_PEER_resolve (q->target, &uc.destination);
+ memcpy (buf, &uc, sizeof (uc));
+ size = q->size + sizeof (uc);
+ }
+ }
}
else
{
@@ -538,7 +612,28 @@
return size;
}
+
/**
+ * Add a transmit handle to the transmission queue (by priority).
+ * Also manage timeout.
+ *
+ * @param h mesh handle with the queue head and tail
+ * @param q handle to add
+ */
+static void
+queue_transmit_handle (struct GNUNET_MESH_Handle *h,
+ struct GNUNET_MESH_TransmitHandle *q)
+{
+ struct GNUNET_MESH_TransmitHandle *p;
+
+ p = h->queue_head;
+ while ( (NULL != p) && (q->priority < p->priority) )
+ p = p->next;
+ GNUNET_CONTAINER_DLL_insert_after (h->queue_head, h->queue_tail, p->prev, q);
+}
+
+
+/**
* Auxiliary function to send a packet to the service
* Takes care of creating a new queue element and calling the tmt_rdy function
* if necessary.
@@ -549,15 +644,17 @@
send_packet (struct GNUNET_MESH_Handle *h,
const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_MESH_queue *q;
+ struct GNUNET_MESH_TransmitHandle *q;
size_t msize;
msize = ntohs (msg->size);
- q = GNUNET_malloc (sizeof (struct GNUNET_MESH_queue) + msize);
+ q = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle) + msize);
+ q->priority = UINT32_MAX;
+ q->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
q->size = msize;
q->data = (void*) &q[1];
memcpy (&q[1], msg, msize);
- GNUNET_CONTAINER_DLL_insert_tail (h->queue_head, h->queue_tail, q);
+ queue_transmit_handle (h, q);
if (NULL != h->th)
return;
h->th =
@@ -877,26 +974,21 @@
GNUNET_CONNECTION_TransmitReadyNotify
notify,
void *notify_cls)
{
- struct GNUNET_MESH_TransmitHandle *handle;
- struct GNUNET_MESH_queue *q;
+ struct GNUNET_MESH_TransmitHandle *q;
if (get_queue_length (tunnel->mesh) >= tunnel->mesh->max_queue_size)
return NULL; /* queue full */
- // FIXME: priority, maxdelay, target! (keep in 'handle')
- handle = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
- handle->t = tunnel;
- handle->q = q = GNUNET_malloc (sizeof (struct GNUNET_MESH_queue));
+ q = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
+ q->tunnel = tunnel;
+ q->priority = priority;
+ q->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
+ q->target = GNUNET_PEER_intern (target);
q->size = notify_size;
q->notify = notify;
q->notify_cls = notify_cls;
- // FIXME: insert by priority!?
- // FIXME: distinguish between control messages (MESH_LOCAL_CONNECT) and data
- // messages?
- GNUNET_CONTAINER_DLL_insert_tail (tunnel->mesh->queue_head,
- tunnel->mesh->queue_tail, q);
-
- return handle;
+ queue_transmit_handle (tunnel->mesh, q);
+ return q;
}
@@ -908,10 +1000,9 @@
void
GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle
*th)
{
- GNUNET_CONTAINER_DLL_remove (th->t->mesh->queue_head,
th->t->mesh->queue_tail,
- th->q);
- // TODO remove from dataless queue
- GNUNET_free (th->q);
+ GNUNET_CONTAINER_DLL_remove (th->tunnel->mesh->queue_head,
+ th->tunnel->mesh->queue_tail,
+ th);
GNUNET_free (th);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r16637 - gnunet/src/mesh,
gnunet <=