From: Jonathan Bastien-Filiatrault Date: Thu, 6 Aug 2009 20:37:15 +0000 (-0400) Subject: Add gnutls_mbuffers.{c,h} with some basic mbuffer operations. X-Git-Tag: gnutls_2_11_3~335 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=95dd15a0b2bf4daff8f0bffa9903f71990d0156d;p=thirdparty%2Fgnutls.git Add gnutls_mbuffers.{c,h} with some basic mbuffer operations. --- diff --git a/lib/Makefile.am b/lib/Makefile.am index e90702c350..8c88dd72db 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -82,7 +82,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c \ auth_dh_common.c gnutls_helper.c gnutls_supplemental.c \ crypto.c random.c pk-libgcrypt.c mpi-libgcrypt.c cryptodev.c \ rnd-libgcrypt.c cipher-libgcrypt.c mac-libgcrypt.c ext_signature.c \ - crypto-api.c ext_safe_renegotiation.c + crypto-api.c ext_safe_renegotiation.c gnutls_mbuffers.c if ENABLE_OPRFI COBJECTS += $(OPRFI_COBJECTS) diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 3d23f94b04..3a733c4fe1 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -209,6 +209,28 @@ typedef enum HANDSHAKE_MAC_TYPE_12 } handshake_mac_type_t; +/* Message buffers (mbuffers) structures */ + +typedef struct mbuffer_st +{ + struct mbuffer_st *next; + + gnutls_datum_t msg; + /* msg->size - mark = number of bytes left to process in this + message. Mark should only be non-zero when this buffer is the + head of the queue. */ + size_t mark; +} mbuffer_st; + +typedef struct mbuffer_head_st +{ + mbuffer_st *head; + mbuffer_st **tail; + + unsigned int length; + size_t byte_length; +} mbuffer_head_st; + /* Store & Retrieve functions defines: */ diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c new file mode 100644 index 0000000000..b2db65b1d7 --- /dev/null +++ b/lib/gnutls_mbuffers.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2009 Free Software Foundation + * + * Author: Jonathan Bastien-Filiatrault + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +#include "gnutls_mbuffers.h" +#include "gnutls_errors.h" + +/* Here be mbuffers */ + +void +_gnutls_mbuffer_init (mbuffer_head_st *buf) +{ + buf->head = NULL; + buf->tail = &buf->head; + + buf->length = 0; + buf->byte_length = 0; +} + +void +_gnutls_mbuffer_clear (mbuffer_head_st *buf) +{ + mbuffer_st *bufel, *next; + + for(bufel = buf->head; bufel != NULL; bufel = next) + { + next = bufel->next; + gnutls_free(bufel->msg.data); + gnutls_free(bufel); + } + + _gnutls_mbuffer_init (buf); +} + +int +_gnutls_mbuffer_enqueue (mbuffer_head_st *buf, gnutls_datum_t msg) +{ + mbuffer_st *bufel = gnutls_malloc (sizeof (mbuffer_st)); + + if (bufel == NULL) + { + gnutls_assert (); + return GNUTLS_E_MEMORY_ERROR; + } + + bufel->next = NULL; + bufel->mark = 0; + + bufel->msg = msg; + + buf->length++; + buf->byte_length += msg.size; + + *(buf->tail) = bufel; + buf->tail = &bufel->next; + + return 0; +} + +int +_gnutls_mbuffer_enqueue_copy (mbuffer_head_st *buf, gnutls_datum_t msg) +{ + gnutls_datum_t msg_copy; + + msg_copy.data = gnutls_malloc (msg.size); + + if (msg_copy.data == NULL) + { + gnutls_assert (); + return GNUTLS_E_MEMORY_ERROR; + } + + msg_copy.size = msg.size; + memcpy (msg_copy.data, msg.data, msg_copy.size); + + return _gnutls_mbuffer_enqueue (buf, msg_copy); +} + +void +_gnutls_mbuffer_get_head (mbuffer_head_st *buf, gnutls_datum_t *msg) +{ + mbuffer_st *bufel; + + if (buf->head) + { + bufel = buf->head; + msg->data = bufel->msg.data + bufel->mark; + msg->size = bufel->msg.size - bufel->mark; + } + else + { + msg->data = NULL; + msg->size = 0; + } +} + +static inline void +remove_front (mbuffer_head_st *buf) +{ + mbuffer_st *bufel; + + if(!buf->head) + return; + + bufel = buf->head; + buf->head = bufel->next; + + buf->byte_length -= (bufel->msg.size - bufel->mark); + buf->length -= 1; + gnutls_free(bufel->msg.data); + gnutls_free(bufel); + + if (!buf->head) + buf->tail = &buf->head; +} + +int +_gnutls_mbuffer_remove_bytes (mbuffer_head_st *buf, size_t bytes) +{ + size_t left = bytes; + mbuffer_st *bufel, *next; + + if (bytes > buf->byte_length) + return -1; + + for (bufel = buf->head; bufel != NULL && left > 0; bufel = next) + { + next = bufel->next; + + if(left >= (bufel->msg.size - bufel->mark)) + { + left -= (bufel->msg.size - bufel->mark); + remove_front(buf); + } + else + { + bufel->mark += left; + buf->byte_length -= left; + left = 0; + } + } + + return 0; +} diff --git a/lib/gnutls_mbuffers.h b/lib/gnutls_mbuffers.h new file mode 100644 index 0000000000..69a4b95546 --- /dev/null +++ b/lib/gnutls_mbuffers.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Free Software Foundation + * + * Author: Jonathan Bastien-Filiatrault + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +#ifndef GNUTLS_MBUFFERS_H +# define GNUTLS_MBUFFERS_H + +#include "gnutls_int.h" + +void _gnutls_mbuffer_init (mbuffer_head_st *buf); +void _gnutls_mbuffer_clear (mbuffer_head_st *buf); +int _gnutls_mbuffer_enqueue (mbuffer_head_st *buf, gnutls_datum_t msg); +int _gnutls_mbuffer_enqueue_copy (mbuffer_head_st *buf, gnutls_datum_t msg); +void _gnutls_mbuffer_get_head (mbuffer_head_st *buf, gnutls_datum_t *msg); +int _gnutls_mbuffer_remove_bytes (mbuffer_head_st *buf, size_t bytes); + +#endif