summaryrefslogtreecommitdiff
path: root/lib/gnutls_mbuffers.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-03-05 19:28:46 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-03-06 22:26:50 +0100
commitb6b52f6c19ef13337892be120d29f62526fbb15d (patch)
treefde54eaa8c1106f05fe193a6f047511f7b72d2c2 /lib/gnutls_mbuffers.c
parent789b253b7946c1c0136c4f795afa37ffc75fdd80 (diff)
downloadgnutls-b6b52f6c19ef13337892be120d29f62526fbb15d.tar.gz
Added intermediate handshake layer that will order handshake packets and drop duplicates.
Diffstat (limited to 'lib/gnutls_mbuffers.c')
-rw-r--r--lib/gnutls_mbuffers.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c
index a150bce927..2eff937b37 100644
--- a/lib/gnutls_mbuffers.c
+++ b/lib/gnutls_mbuffers.c
@@ -57,7 +57,7 @@ void
_mbuffer_head_init (mbuffer_head_st * buf)
{
buf->head = NULL;
- buf->tail = &buf->head;
+ buf->tail = NULL;
buf->length = 0;
buf->byte_length = 0;
@@ -94,8 +94,40 @@ _mbuffer_enqueue (mbuffer_head_st * buf, mbuffer_st * bufel)
buf->length++;
buf->byte_length += bufel->msg.size - bufel->mark;
- *(buf->tail) = bufel;
- buf->tail = &bufel->next;
+ bufel->prev = buf->tail;
+ if (buf->tail != NULL)
+ buf->tail->next = bufel;
+ else
+ buf->head = bufel;
+ buf->tail = bufel;
+}
+
+/* Remove a segment from the buffer.
+ *
+ * Cost: O(1)
+ *
+ * Returns the buffer following it.
+ */
+mbuffer_st *
+_mbuffer_dequeue (mbuffer_head_st * buf, mbuffer_st * bufel)
+{
+mbuffer_st* ret = bufel->next;
+
+ if (buf->tail == bufel) /* if last */
+ buf->tail = bufel->prev;
+
+ if (buf->head == bufel) /* if first */
+ buf->head = bufel->next;
+
+ if (bufel->prev)
+ bufel->prev->next = bufel->next;
+
+ buf->length--;
+ buf->byte_length -= bufel->msg.size - bufel->mark;
+
+ bufel->next = bufel->prev = NULL;
+
+ return ret;
}
/* Get a reference to the first segment of the buffer and
@@ -110,13 +142,18 @@ _mbuffer_head_pop_first (mbuffer_head_st * buf)
{
mbuffer_st *bufel = buf->head;
+ if (buf->head == NULL)
+ return NULL;
+
buf->head = bufel->next;
+ if (bufel->next)
+ bufel->next->prev = NULL;
buf->byte_length -= (bufel->msg.size - bufel->mark);
buf->length -= 1;
if (!buf->head)
- buf->tail = &buf->head;
+ buf->tail = NULL;
return bufel;
}
@@ -159,15 +196,18 @@ _mbuffer_head_get_next (mbuffer_st * cur, gnutls_datum_t * msg)
{
mbuffer_st *bufel = cur->next;
- if (bufel)
- {
- msg->data = bufel->msg.data + bufel->mark;
- msg->size = bufel->msg.size - bufel->mark;
- }
- else
+ if (msg)
{
- msg->data = NULL;
- msg->size = 0;
+ if (bufel)
+ {
+ msg->data = bufel->msg.data + bufel->mark;
+ msg->size = bufel->msg.size - bufel->mark;
+ }
+ else
+ {
+ msg->data = NULL;
+ msg->size = 0;
+ }
}
return bufel;
}
@@ -189,13 +229,15 @@ remove_front (mbuffer_head_st * buf)
bufel = buf->head;
buf->head = bufel->next;
+ if (bufel->next)
+ bufel->next->prev = NULL;
buf->byte_length -= (bufel->msg.size - bufel->mark);
buf->length -= 1;
gnutls_free (bufel);
if (!buf->head)
- buf->tail = &buf->head;
+ buf->tail = NULL;
}
/* Remove a specified number of bytes from the start of the buffer.
@@ -266,7 +308,7 @@ _mbuffer_alloc (size_t payload_size, size_t maximum_size)
return NULL;
}
- //payload points after the mbuffer_st structure
+ /* payload points after the mbuffer_st structure */
st->msg.data = (opaque *) st + sizeof (mbuffer_st);
st->msg.size = payload_size;
st->mark = 0;