gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-265-ga7af4ce


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-265-ga7af4ce
Date: Wed, 02 Mar 2011 17:46:04 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=a7af4cea9df35e4088e4153f2c102facc1098a74

The branch, master has been updated
       via  a7af4cea9df35e4088e4153f2c102facc1098a74 (commit)
       via  847d31f298635bed453855b5c303f235e6bf3bde (commit)
       via  12d6098d3471b6acb49716f4313ae8b8312931e5 (commit)
       via  5d1ef73207befe4d46e6666dda5a698faa7f7ab9 (commit)
       via  601b2229fb79467961e713ea636ce0c6fedd3c73 (commit)
       via  a0608d1ba6c682b42d52242592272b2a79c02ff3 (commit)
      from  31c85c662e370730d7410826b47d65f83259cfcf (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a7af4cea9df35e4088e4153f2c102facc1098a74
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Mar 2 18:45:30 2011 +0100

    Allow providing no password for PKCS #12 structure generation. Reported by 
Daniel Kahn Gillmor.

commit 847d31f298635bed453855b5c303f235e6bf3bde
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Mar 2 18:42:48 2011 +0100

    consistently print all interactive questions to stderr. Reported by Daniel 
Kahn Gillmor.

commit 12d6098d3471b6acb49716f4313ae8b8312931e5
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Feb 26 13:16:33 2011 +0100

    combined all the record buffers in one.

commit 5d1ef73207befe4d46e6666dda5a698faa7f7ab9
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Feb 26 11:27:13 2011 +0100

    internal buffering for record and handshake data changed from 
gnutls_buffers to gnutls_mbuffers.

commit 601b2229fb79467961e713ea636ce0c6fedd3c73
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Feb 26 09:34:35 2011 +0100

    Removed last pieces of inner application.

commit a0608d1ba6c682b42d52242592272b2a79c02ff3
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Feb 26 09:33:16 2011 +0100

    some cleanups

-----------------------------------------------------------------------

Summary of changes:
 lib/debug.c                     |    3 -
 lib/gnutls_buffers.c            |  198 +++++++---------------
 lib/gnutls_buffers.h            |   19 ++-
 lib/gnutls_dtls.c               |    8 +-
 lib/gnutls_int.h                |   38 ++--
 lib/gnutls_mbuffers.c           |   62 +++++--
 lib/gnutls_mbuffers.h           |   14 +-
 lib/gnutls_record.c             |  348 +++++++++++++++++----------------------
 lib/gnutls_record.h             |    2 +
 lib/gnutls_state.c              |   20 +--
 lib/includes/gnutls/gnutls.h.in |    2 -
 src/certtool-cfg.c              |    2 +-
 src/certtool.c                  |    7 +
 13 files changed, 319 insertions(+), 404 deletions(-)

diff --git a/lib/debug.c b/lib/debug.c
index 92b70d9..f5eb466 100644
--- a/lib/debug.c
+++ b/lib/debug.c
@@ -58,9 +58,6 @@ _gnutls_packet2str (content_type_t packet)
       return "Handshake";
     case GNUTLS_APPLICATION_DATA:
       return "Application Data";
-    case GNUTLS_INNER_APPLICATION:
-      return "Inner Application";
-
     default:
       return "Unknown Packet";
     }
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 33c6c66..a43e883 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -72,68 +72,20 @@
  * HANDSHAKE DATA.
  */
 int
-_gnutls_record_buffer_put (content_type_t type,
-                           gnutls_session_t session, opaque * data,
-                           size_t length)
+_gnutls_record_buffer_put (gnutls_session_t session,
+  content_type_t type, uint64* seq, mbuffer_st* bufel)
 {
-  gnutls_buffer_st *buf;
 
-  if (length == 0)
-    return 0;
+  bufel->type = type;
+  memcpy(&bufel->record_sequence, seq, sizeof(*seq));
 
-  switch (type)
-    {
-    case GNUTLS_APPLICATION_DATA:
-      buf = &session->internals.application_data_buffer;
-      _gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    case GNUTLS_HANDSHAKE:
-      buf = &session->internals.handshake_data_buffer;
-      _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    case GNUTLS_INNER_APPLICATION:
-      buf = &session->internals.ia_data_buffer;
-      _gnutls_buffers_log ("BUF[IA]: Inserted %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  if (_gnutls_buffer_append_data (buf, data, length) < 0)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
+  _mbuffer_enqueue(&session->internals.record_buffer, bufel);
+  _gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
+                       (int) bufel->msg.size, (int) type);
 
   return 0;
 }
 
-int
-_gnutls_record_buffer_get_size (content_type_t type, gnutls_session_t session)
-{
-  switch (type)
-    {
-    case GNUTLS_APPLICATION_DATA:
-      return session->internals.application_data_buffer.length;
-
-    case GNUTLS_HANDSHAKE:
-      return session->internals.handshake_data_buffer.length;
-
-    case GNUTLS_INNER_APPLICATION:
-      return session->internals.ia_data_buffer.length;
-
-    default:
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-}
-
 /**
  * gnutls_record_check_pending:
  * @session: is a #gnutls_session_t structure.
@@ -158,44 +110,33 @@ gnutls_record_check_pending (gnutls_session_t session)
 int
 _gnutls_record_buffer_get (content_type_t type,
                            gnutls_session_t session, opaque * data,
-                           size_t length)
+                           size_t length, opaque seq[8])
 {
+gnutls_datum_t msg;
+mbuffer_st* bufel;
+
   if (length == 0 || data == NULL)
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  switch (type)
-    {
-    case GNUTLS_APPLICATION_DATA:
-      _gnutls_buffer_pop_data (&session->internals.application_data_buffer,
-                               data, &length);
-      _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    case GNUTLS_HANDSHAKE:
-      _gnutls_buffer_pop_data (&session->internals.handshake_data_buffer,
-                               data, &length);
-      _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    case GNUTLS_INNER_APPLICATION:
-
-      _gnutls_buffer_pop_data (&session->internals.ia_data_buffer, data,
-                               &length);
-      _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
-                           (int) length, (int) type);
-      break;
-
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
+  bufel = _mbuffer_head_get_first(&session->internals.record_buffer, &msg);
+  if (bufel == NULL)
+    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+  if (type != bufel->type)
+    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
 
+  if (msg.size <= length)
+    length = msg.size;
 
+  if (seq)
+    memcpy(seq, bufel->record_sequence.i, 8);
+
+  memcpy(data, msg.data, length);
+  _mbuffer_head_remove_bytes(&session->internals.record_buffer, length);
+  
   return length;
 }
 
@@ -222,23 +163,24 @@ _gnutls_dgram_read (gnutls_session_t session, mbuffer_st 
**bufel,
 {
   ssize_t i, ret;
   char *ptr;
+  size_t max_size = _gnutls_get_max_decrypted_data(session);
+  size_t recv_size = MAX_RECV_SIZE(session);
   gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
 
-  if (!bufel)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
+  if (recv_size > max_size)
+    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
-  ptr = gnutls_malloc(MAX_RECV_SIZE(session));
-  if (ptr == NULL)
+  *bufel = _mbuffer_alloc (0, _gnutls_get_max_decrypted_data(session));
+  if (*bufel == NULL)
     return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
 
+  ptr = (*bufel)->msg.data;
+
   session->internals.direction = 0;
 
   reset_errno (session);
 
-  i = pull_func (fd, ptr, MAX_RECV_SIZE(session));
+  i = pull_func (fd, ptr, recv_size);
 
   if (i < 0)
     {
@@ -249,49 +191,42 @@ _gnutls_dgram_read (gnutls_session_t session, mbuffer_st 
**bufel,
 
       if (err == EAGAIN)
         {
-         ret = GNUTLS_E_AGAIN;
-         goto cleanup;
+          ret = GNUTLS_E_AGAIN;
+          goto cleanup;
         }
       else if (err == EINTR)
         {
-         ret = GNUTLS_E_INTERRUPTED;
-         goto cleanup;
+          ret = GNUTLS_E_INTERRUPTED;
+          goto cleanup;
         }
       else
-       {
-         gnutls_assert ();
-         ret = GNUTLS_E_PULL_ERROR;
-         goto cleanup;
-       }
+        {
+          gnutls_assert ();
+          ret = GNUTLS_E_PULL_ERROR;
+          goto cleanup;
+        }
     }
   else
     {
       _gnutls_read_log ("READ: Got %d bytes from %p\n", (int) i, fd);
-      if (i == 0) {
-       /* If we get here, we likely have a stream socket.
-        * FIXME: this probably breaks DCCP. */
-       gnutls_assert ();
-       ret = GNUTLS_E_INTERNAL_ERROR;
-       goto cleanup;
-      }
-
-      *bufel = _mbuffer_alloc (0, i);
-      if (!*bufel)
-       {
-         gnutls_assert ();
-         ret = GNUTLS_E_MEMORY_ERROR;
-         goto cleanup;
-       }
-
-      _mbuffer_append_data (*bufel, ptr, i);
+      if (i == 0) 
+        {
+          /* If we get here, we likely have a stream socket.
+           * FIXME: this probably breaks DCCP. */
+          gnutls_assert ();
+          ret = GNUTLS_E_INTERNAL_ERROR;
+          goto cleanup;
+        }
+
+      _mbuffer_set_udata_size (*bufel, i);
     }
 
   _gnutls_read_log ("READ: read %d bytes from %p\n", (int) i, fd);
   
-  ret = i;
+  return i;
   
 cleanup:
-  gnutls_free(ptr);
+  _mbuffer_xfree(bufel);
   return ret;
 }
 
@@ -301,16 +236,11 @@ _gnutls_stream_read (gnutls_session_t session, mbuffer_st 
**bufel,
 {
   size_t left;
   ssize_t i = 0;
+  size_t max_size = _gnutls_get_max_decrypted_data(session);
   char *ptr;
   gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
 
-  if (!bufel)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
-
-  *bufel = _mbuffer_alloc (0, size);
+  *bufel = _mbuffer_alloc (0, GMAX(max_size, size));
   if (!*bufel)
     {
       gnutls_assert ();
@@ -732,8 +662,8 @@ _gnutls_io_write_flush (gnutls_session_t session)
   _gnutls_write_log ("WRITE FLUSH: %d bytes in buffer.\n",
                      (int) send_buffer->byte_length);
 
-  for (cur = _mbuffer_get_first (send_buffer, &msg);
-       cur != NULL; cur = _mbuffer_get_next (cur, &msg))
+  for (cur = _mbuffer_head_get_first (send_buffer, &msg);
+       cur != NULL; cur = _mbuffer_head_get_next (cur, &msg))
     {
       iovec[i].iov_base = msg.data;
       iovec[i++].iov_len = msg.size;
@@ -750,7 +680,7 @@ _gnutls_io_write_flush (gnutls_session_t session)
   ret = _gnutls_writev (session, iovec, i);
   if (ret >= 0)
     {
-      _mbuffer_remove_bytes (send_buffer, ret);
+      _mbuffer_head_remove_bytes (send_buffer, ret);
       _gnutls_write_log ("WRITE: wrote %d bytes, %d bytes left.\n",
                          ret, (int) send_buffer->byte_length);
 
@@ -828,8 +758,8 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session)
   if (IS_DTLS(session))
     return _dtls_transmit(session);
 
-  for (cur = _mbuffer_get_first (send_buffer, &msg);
-       cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg))
+  for (cur = _mbuffer_head_get_first (send_buffer, &msg);
+       cur != NULL; cur = _mbuffer_head_get_first (send_buffer, &msg))
     {
       epoch = cur->epoch;
 
@@ -842,7 +772,7 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session)
         {
           total += ret;
           
-          ret = _mbuffer_remove_bytes (send_buffer, ret);
+          ret = _mbuffer_head_remove_bytes (send_buffer, ret);
           if (ret == 1)
             _gnutls_epoch_refcount_dec(session, epoch);
 
@@ -878,7 +808,7 @@ _gnutls_handshake_io_cache_int (gnutls_session_t session,
 
   if (IS_DTLS(session))
     {
-      bufel->sequence = session->internals.dtls.hsk_write_seq-1;
+      bufel->handshake_sequence = session->internals.dtls.hsk_write_seq-1;
     }
   
   send_buffer =
diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h
index 6e1b901..2cb42f3 100644
--- a/lib/gnutls_buffers.h
+++ b/lib/gnutls_buffers.h
@@ -27,14 +27,19 @@
 
 #define MBUFFER_FLUSH 1
 
-int _gnutls_record_buffer_put (content_type_t type,
-                               gnutls_session_t session, opaque * data,
-                               size_t length);
-int _gnutls_record_buffer_get_size (content_type_t type,
-                                    gnutls_session_t session);
+int
+_gnutls_record_buffer_put (gnutls_session_t session,
+  content_type_t type, uint64* seq, mbuffer_st* bufel);
+
+inline static int
+_gnutls_record_buffer_get_size (content_type_t type, gnutls_session_t session)
+{
+  return session->internals.record_buffer.byte_length;
+}
+
 int _gnutls_record_buffer_get (content_type_t type,
                                gnutls_session_t session, opaque * data,
-                               size_t length);
+                               size_t length, opaque seq[8]);
 ssize_t _gnutls_io_read_buffered (gnutls_session_t, size_t n, content_type_t);
 int _gnutls_io_clear_peeked_data (gnutls_session_t session);
 
@@ -50,7 +55,7 @@ int _gnutls_handshake_buffer_get_ptr (gnutls_session_t 
session,
                                       opaque ** data_ptr, size_t * length);
 
 #define _gnutls_handshake_io_buffer_clear( session) \
-        _mbuffer_clear( &session->internals.handshake_send_buffer); \
+        _mbuffer_head_clear( &session->internals.handshake_send_buffer); \
         _gnutls_buffer_clear( &session->internals.handshake_recv_buffer);
 
 ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c
index a1cbcf1..30ecfc5 100644
--- a/lib/gnutls_dtls.c
+++ b/lib/gnutls_dtls.c
@@ -52,7 +52,7 @@ transmit_message (gnutls_session_t session,
     {
       _gnutls_dtls_log ("DTLS[%p]: Sending Packet[%u] fragment %s(%d) with "
                        "length: %u, offset: %u, fragment length: %u\n",
-                       session, bufel->sequence,
+                       session, bufel->handshake_sequence,
                        _gnutls_handshake2str (bufel->htype),
                        bufel->htype, data_size, offset, frag_len);
 
@@ -79,7 +79,7 @@ transmit_message (gnutls_session_t session,
   _gnutls_write_uint24 (data_size, &mtu_data[1]);
 
   /* Handshake sequence */
-  _gnutls_write_uint16 (bufel->sequence, &mtu_data[4]);
+  _gnutls_write_uint16 (bufel->handshake_sequence, &mtu_data[4]);
 
   /* Chop up and send handshake message into mtu-size pieces. */
   for (offset=0; offset <= data_size; offset += mtu)
@@ -100,7 +100,7 @@ transmit_message (gnutls_session_t session,
 
       _gnutls_dtls_log ("DTLS[%p]: Sending Packet[%u] fragment %s(%d) with "
                        "length: %u, offset: %u, fragment length: %u\n",
-                       session, bufel->sequence,
+                       session, bufel->handshake_sequence,
                        _gnutls_handshake2str (bufel->htype),
                        bufel->htype, data_size, offset, frag_len);
 
@@ -215,7 +215,7 @@ int ret;
 
 cleanup:
   drop_usage_count(session);
-  _mbuffer_clear(send_buffer);
+  _mbuffer_head_clear(send_buffer);
 
   /* SENDING -> WAITING state transition */
   return ret;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 5632414..26c4afd 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -71,6 +71,8 @@ typedef struct
 #define DEBUG
 */
 
+#define GMAX(x,y) ((x>y)?(x):(y))
+
 /* The size of a handshake message should not
  * be larger than this value.
  */
@@ -127,12 +129,6 @@ typedef struct
   } gnutls_ext_parse_type_t;
 
 
-/* The initial size of the receive
- * buffer size. This will grow if larger
- * packets are received.
- */
-#define INITIAL_RECV_BUFFER_SIZE 256
-
 /* the default for TCP */
 #define DEFAULT_LOWAT 0
 
@@ -230,7 +226,6 @@ typedef enum extensions_t
   GNUTLS_EXTENSION_SRP = 12,
   GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS = 13,
   GNUTLS_EXTENSION_SESSION_TICKET = 35,
-  GNUTLS_EXTENSION_INNER_APPLICATION = 37703,
   GNUTLS_EXTENSION_SAFE_RENEGOTIATION = 65281   /* aka: 0xff01 */
 } extensions_t;
 
@@ -245,7 +240,6 @@ typedef enum content_type_t
 {
   GNUTLS_CHANGE_CIPHER_SPEC = 20, GNUTLS_ALERT,
   GNUTLS_HANDSHAKE, GNUTLS_APPLICATION_DATA,
-  GNUTLS_INNER_APPLICATION = 24
 } content_type_t;
 
 
@@ -265,16 +259,27 @@ typedef struct mbuffer_st
   size_t mark;
   unsigned int user_mark;       /* only used during fill in */
   size_t maximum_size;
-  
+
+  /* Filled in by record layer on recv:
+   * type, record_sequence
+   */
+
+  /* Filled in by handshake layer on send:
+   * type, epoch, htype, handshake_sequence
+   */
+
   /* record layer content type */
   content_type_t type;
 
+  /* record layer sequence */
+  uint64 record_sequence;
+
   /* Record layer epoch of message */
   uint16_t epoch;
 
   /* Handshake layer type and sequence of message */
   gnutls_handshake_description_t htype;
-  uint16_t sequence;
+  uint16_t handshake_sequence;
 } mbuffer_st;
 
 typedef struct mbuffer_head_st
@@ -589,7 +594,9 @@ typedef union
 
 typedef struct
 {
-  gnutls_buffer_st application_data_buffer;     /* holds data to be delivered 
to application layer */
+  /* holds all the data received by the record layer */
+  mbuffer_head_st record_buffer; 
+
   gnutls_buffer_st handshake_hash_buffer;       /* used to keep the last 
received handshake 
                                                  * message */
   union
@@ -607,8 +614,6 @@ typedef struct
   } handshake_mac_handle;
   int handshake_mac_handle_init;        /* 1 when the previous union and type 
were initialized */
 
-  gnutls_buffer_st handshake_data_buffer;       /* this is a buffer that holds 
the current handshake message */
-  gnutls_buffer_st ia_data_buffer;      /* holds inner application data 
(TLS/IA) */
   int resumable:1;              /* TRUE or FALSE - if we can resume that 
session */
   handshake_state_t handshake_state;    /* holds
                                          * a number which indicates where
@@ -654,7 +659,7 @@ typedef struct
   /* this buffer holds a record packet -mostly used for
    * non blocking IO.
    */
-  mbuffer_head_st record_recv_buffer;
+  mbuffer_head_st record_recv_buffer;   /* buffer holding the record that is 
currently being received */
   mbuffer_head_st record_send_buffer;   /* holds cached data
                                          * for the gnutls_io_write_buffered()
                                          * function.
@@ -783,11 +788,6 @@ typedef struct
    */
   internal_params_st params;
 
-  /* This buffer is used by the record recv functions,
-   * as a temporary store buffer.
-   */
-  gnutls_datum_t recv_buffer;
-
   /* To avoid using global variables, and especially on Windows where
    * the application may use a different errno variable than GnuTLS,
    * it is possible to use gnutls_transport_set_errno to set a
diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c
index e58a3c3..a150bce 100644
--- a/lib/gnutls_mbuffers.c
+++ b/lib/gnutls_mbuffers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Free Software Foundation
+ * Copyright (C) 2009,2011 Free Software Foundation
  *
  * Author: Jonathan Bastien-Filiatrault
  *
@@ -54,7 +54,7 @@
  * Cost: O(1)
  */
 void
-_mbuffer_init (mbuffer_head_st * buf)
+_mbuffer_head_init (mbuffer_head_st * buf)
 {
   buf->head = NULL;
   buf->tail = &buf->head;
@@ -69,7 +69,7 @@ _mbuffer_init (mbuffer_head_st * buf)
  * n: Number of segments currently in the buffer.
  */
 void
-_mbuffer_clear (mbuffer_head_st * buf)
+_mbuffer_head_clear (mbuffer_head_st * buf)
 {
   mbuffer_st *bufel, *next;
 
@@ -79,7 +79,7 @@ _mbuffer_clear (mbuffer_head_st * buf)
       gnutls_free (bufel);
     }
 
-  _mbuffer_init (buf);
+  _mbuffer_head_init (buf);
 }
 
 /* Append a segment to the end of this buffer.
@@ -98,6 +98,29 @@ _mbuffer_enqueue (mbuffer_head_st * buf, mbuffer_st * bufel)
   buf->tail = &bufel->next;
 }
 
+/* Get a reference to the first segment of the buffer and
+ * remove it from the list.
+ *
+ * Used to start iteration.
+ *
+ * Cost: O(1)
+ */
+mbuffer_st *
+_mbuffer_head_pop_first (mbuffer_head_st * buf)
+{
+  mbuffer_st *bufel = buf->head;
+
+  buf->head = bufel->next;
+
+  buf->byte_length -= (bufel->msg.size - bufel->mark);
+  buf->length -= 1;
+
+  if (!buf->head)
+    buf->tail = &buf->head;
+    
+  return bufel;
+}
+
 /* Get a reference to the first segment of the buffer and its data.
  *
  * Used to start iteration or to peek at the data.
@@ -105,19 +128,22 @@ _mbuffer_enqueue (mbuffer_head_st * buf, mbuffer_st * 
bufel)
  * Cost: O(1)
  */
 mbuffer_st *
-_mbuffer_get_first (mbuffer_head_st * buf, gnutls_datum_t * msg)
+_mbuffer_head_get_first (mbuffer_head_st * buf, gnutls_datum_t * msg)
 {
   mbuffer_st *bufel = buf->head;
 
-  if (bufel)
+  if (msg)
     {
-      msg->data = bufel->msg.data + bufel->mark;
-      msg->size = bufel->msg.size - bufel->mark;
-    }
-  else
-    {
-      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;
 }
@@ -129,7 +155,7 @@ _mbuffer_get_first (mbuffer_head_st * buf, gnutls_datum_t * 
msg)
  * Cost: O(1)
  */
 mbuffer_st *
-_mbuffer_get_next (mbuffer_st * cur, gnutls_datum_t * msg)
+_mbuffer_head_get_next (mbuffer_st * cur, gnutls_datum_t * msg)
 {
   mbuffer_st *bufel = cur->next;
 
@@ -183,7 +209,7 @@ remove_front (mbuffer_head_st * buf)
  * n: Number of segments needed to remove the specified amount of data.
  */
 int
-_mbuffer_remove_bytes (mbuffer_head_st * buf, size_t bytes)
+_mbuffer_head_remove_bytes (mbuffer_head_st * buf, size_t bytes)
 {
   size_t left = bytes;
   mbuffer_st *bufel, *next;
@@ -304,14 +330,14 @@ _mbuffer_linearize (mbuffer_head_st * buf)
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  for (cur = _mbuffer_get_first (buf, &msg);
-       msg.data != NULL; cur = _mbuffer_get_next (cur, &msg))
+  for (cur = _mbuffer_head_get_first (buf, &msg);
+       msg.data != NULL; cur = _mbuffer_head_get_next (cur, &msg))
     {
       memcpy (&bufel->msg.data[pos], msg.data, cur->msg.size);
       pos += cur->msg.size;
     }
 
-  _mbuffer_clear (buf);
+  _mbuffer_head_clear (buf);
   _mbuffer_enqueue (buf, bufel);
 
   return 0;
diff --git a/lib/gnutls_mbuffers.h b/lib/gnutls_mbuffers.h
index 571e467..96df86e 100644
--- a/lib/gnutls_mbuffers.h
+++ b/lib/gnutls_mbuffers.h
@@ -28,14 +28,17 @@
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
 
-void _mbuffer_init (mbuffer_head_st * buf);
-void _mbuffer_clear (mbuffer_head_st * buf);
+void _mbuffer_head_init (mbuffer_head_st * buf);
+void _mbuffer_head_clear (mbuffer_head_st * buf);
 void _mbuffer_enqueue (mbuffer_head_st * buf, mbuffer_st * bufel);
-int _mbuffer_remove_bytes (mbuffer_head_st * buf, size_t bytes);
+int _mbuffer_head_remove_bytes (mbuffer_head_st * buf, size_t bytes);
 mbuffer_st *_mbuffer_alloc (size_t payload_size, size_t maximum_size);
 
-mbuffer_st *_mbuffer_get_first (mbuffer_head_st * buf, gnutls_datum_t * msg);
-mbuffer_st *_mbuffer_get_next (mbuffer_st * cur, gnutls_datum_t * msg);
+mbuffer_st *_mbuffer_head_get_first (mbuffer_head_st * buf, gnutls_datum_t * 
msg);
+mbuffer_st *_mbuffer_head_get_next (mbuffer_st * cur, gnutls_datum_t * msg);
+
+mbuffer_st *
+_mbuffer_head_pop_first (mbuffer_head_st * buf);
 
 /* This is dangerous since it will replace bufel with a new
  * one.
@@ -52,6 +55,7 @@ inline static void
 _mbuffer_set_udata (mbuffer_st * bufel, void *data, size_t data_size)
 {
   memcpy (bufel->msg.data + bufel->user_mark, data, data_size);
+  bufel->msg.size = data_size + bufel->user_mark;
 }
 
 inline static void *
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 5f93fc5..68d1548 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -520,7 +520,6 @@ check_recv_type (content_type_t recv_type)
     case GNUTLS_ALERT:
     case GNUTLS_HANDSHAKE:
     case GNUTLS_APPLICATION_DATA:
-    case GNUTLS_INNER_APPLICATION:
       return 0;
     default:
       gnutls_assert ();
@@ -536,15 +535,15 @@ check_recv_type (content_type_t recv_type)
  */
 static int
 check_buffers (gnutls_session_t session, content_type_t type,
-               opaque * data, int data_size)
+               opaque * data, int data_size, void* seq)
 {
   if ((type == GNUTLS_APPLICATION_DATA ||
        type == GNUTLS_HANDSHAKE ||
-       type == GNUTLS_INNER_APPLICATION)
+       type == GNUTLS_CHANGE_CIPHER_SPEC)
       && _gnutls_record_buffer_get_size (type, session) > 0)
     {
       int ret, ret2;
-      ret = _gnutls_record_buffer_get (type, session, data, data_size);
+      ret = _gnutls_record_buffer_get (type, session, data, data_size, seq);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -609,62 +608,72 @@ record_check_version (gnutls_session_t session,
 
 /* This function will check if the received record type is
  * the one we actually expect and adds it to the proper
- * buffer.
+ * buffer. The bufel will be deinitialized after calling
+ * this function, even if it fails.
  */
 static int
 record_add_to_buffers (gnutls_session_t session,
                    content_type_t recv_type, content_type_t type,
-                   gnutls_handshake_description_t htype, opaque * data,
-                   int data_size)
+                   gnutls_handshake_description_t htype, 
+                   uint64* seq,
+                   mbuffer_st* bufel)
 {
 
   int ret;
 
   if ((recv_type == type)
       && (type == GNUTLS_APPLICATION_DATA ||
-          type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
+          type == GNUTLS_CHANGE_CIPHER_SPEC ||
+          type == GNUTLS_HANDSHAKE))
     {
-      _gnutls_record_buffer_put (type, session, (void *) data, data_size);
+      _gnutls_record_buffer_put (session, type, seq, bufel);
     }
   else
     {
+      /* if the expected type is different than the received 
+       */
       switch (recv_type)
         {
         case GNUTLS_ALERT:
+          if (bufel->msg.size < 2)
+            {
+              ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
+              goto cleanup;
+            }
 
           _gnutls_record_log
             ("REC[%p]: Alert[%d|%d] - %s - was received\n", session,
-             data[0], data[1], gnutls_alert_get_name ((int) data[1]));
+             bufel->msg.data[0], bufel->msg.data[1], gnutls_alert_get_name 
((int) bufel->msg.data[1]));
 
-          session->internals.last_alert = data[1];
+          session->internals.last_alert = bufel->msg.data[1];
 
           /* if close notify is received and
            * the alert is not fatal
            */
-          if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
+          if (bufel->msg.data[1] == GNUTLS_A_CLOSE_NOTIFY && 
bufel->msg.data[0] != GNUTLS_AL_FATAL)
             {
               /* If we have been expecting for an alert do 
                */
               session->internals.read_eof = 1;
-              return GNUTLS_E_INT_RET_0;        /* EOF */
+              ret = GNUTLS_E_INT_RET_0;        /* EOF */
+              goto cleanup;
             }
           else
             {
-
               /* if the alert is FATAL or WARNING
                * return the apropriate message
                */
 
               gnutls_assert ();
               ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
-              if (data[0] == GNUTLS_AL_FATAL)
+              if (bufel->msg.data[0] == GNUTLS_AL_FATAL)
                 {
                   session_unresumable (session);
                   session_invalidate (session);
                   ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
                 }
 
-              return ret;
+              goto cleanup;
             }
           break;
 
@@ -679,11 +688,11 @@ record_add_to_buffers (gnutls_session_t session,
         case GNUTLS_APPLICATION_DATA:
           /* even if data is unexpected put it into the buffer */
           if ((ret =
-               _gnutls_record_buffer_put (recv_type, session,
-                                          (void *) data, data_size)) < 0)
+               _gnutls_record_buffer_put (session, recv_type, seq,
+                                          bufel)) < 0)
             {
               gnutls_assert ();
-              return ret;
+              goto cleanup;
             }
 
           /* the got_application data is only returned
@@ -692,11 +701,15 @@ record_add_to_buffers (gnutls_session_t session,
            */
           if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
                                        && type == GNUTLS_HANDSHAKE))
-            return GNUTLS_E_GOT_APPLICATION_DATA;
+            {
+              ret = GNUTLS_E_GOT_APPLICATION_DATA;
+              goto cleanup;
+            }
           else
             {
               gnutls_assert ();
-              return GNUTLS_E_UNEXPECTED_PACKET;
+              ret = GNUTLS_E_UNEXPECTED_PACKET;
+              goto cleanup;
             }
 
           break;
@@ -708,12 +721,11 @@ record_add_to_buffers (gnutls_session_t session,
             {
               gnutls_assert ();
               ret =
-                _gnutls_record_buffer_put (recv_type, session, (void *) data,
-                                           data_size);
+                _gnutls_record_buffer_put (session, recv_type, seq, bufel);
               if (ret < 0)
                 {
                   gnutls_assert ();
-                  return ret;
+                  goto cleanup;
                 }
               return GNUTLS_E_REHANDSHAKE;
             }
@@ -724,21 +736,10 @@ record_add_to_buffers (gnutls_session_t session,
            */
 
           /* So we accept it */
-          return _gnutls_recv_hello_request (session, data, data_size);
+          ret = _gnutls_recv_hello_request (session, bufel->msg.data, 
bufel->msg.size);
+          goto cleanup;
 
           break;
-        case GNUTLS_INNER_APPLICATION:
-          /* even if data is unexpected put it into the buffer */
-          if ((ret = _gnutls_record_buffer_put (recv_type, session,
-                                                (void *) data,
-                                                data_size)) < 0)
-            {
-              gnutls_assert ();
-              return ret;
-            }
-          gnutls_assert ();
-          return GNUTLS_E_UNEXPECTED_PACKET;
-          break;
         default:
 
           _gnutls_record_log
@@ -746,57 +747,30 @@ record_add_to_buffers (gnutls_session_t session,
              session, recv_type, type);
 
           gnutls_assert ();
-          return GNUTLS_E_INTERNAL_ERROR;
+          ret = GNUTLS_E_INTERNAL_ERROR;
+          goto cleanup;
         }
     }
 
   return 0;
 
-}
+cleanup:
+  _mbuffer_xfree(&bufel);
+  return ret;
 
+}
 
-/* This function will return the internal (per session) temporary
- * recv buffer. If the buffer was not initialized before it will
- * also initialize it.
- */
-inline static int
-get_temp_recv_buffer (gnutls_session_t session, gnutls_datum_t * tmp)
+int _gnutls_get_max_decrypted_data(gnutls_session_t session)
 {
-  size_t max_record_size;
+int ret;
 
   if (gnutls_compression_get (session) != GNUTLS_COMP_NULL ||
       session->internals.priorities.allow_large_records != 0)
-    max_record_size = MAX_RECORD_RECV_SIZE(session) + EXTRA_COMP_SIZE;
+    ret = MAX_RECORD_RECV_SIZE(session) + EXTRA_COMP_SIZE;
   else
-    max_record_size = MAX_RECORD_RECV_SIZE(session);
-
-  /* We allocate MAX_RECORD_RECV_SIZE length
-   * because we cannot predict the output data by the record
-   * packet length (due to compression).
-   */
-
-  if (max_record_size > session->internals.recv_buffer.size ||
-      session->internals.recv_buffer.data == NULL)
-    {
-
-      /* Initialize the internal buffer.
-       */
-      session->internals.recv_buffer.data =
-        gnutls_realloc (session->internals.recv_buffer.data, max_record_size);
-
-      if (session->internals.recv_buffer.data == NULL)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_MEMORY_ERROR;
-        }
-
-      session->internals.recv_buffer.size = max_record_size;
-    }
+    ret = MAX_RECORD_RECV_SIZE(session);
 
-  tmp->data = session->internals.recv_buffer.data;
-  tmp->size = session->internals.recv_buffer.size;
-
-  return 0;
+  return ret;
 }
 
 struct tls_record_st {
@@ -807,7 +781,6 @@ struct tls_record_st {
   uint16_t packet_size; /* header_size + length */
   content_type_t type;
   /* the data */
-  gnutls_datum_t data;
 };
 
 /* Checks the record headers and returns the length, version and
@@ -875,6 +848,7 @@ static int recv_headers( gnutls_session_t session, 
content_type_t type,
   gnutls_handshake_description_t htype, struct tls_record_st* record)
 {
 int ret;
+gnutls_datum_t raw; /* raw headers */
   /* Read the headers.
    */
   record->header_size = record->packet_size = RECORD_HEADER_SIZE(session);
@@ -893,9 +867,9 @@ int ret;
       return ret;
     }
 
-  _mbuffer_get_first (&session->internals.record_recv_buffer, &record->data);
+  _mbuffer_head_get_first (&session->internals.record_recv_buffer, &raw);
 
-  record_read_headers (session, record->data.data, type, htype, record);
+  record_read_headers (session, raw.data, type, htype, record);
 
   /* Check if the DTLS epoch is valid */
   if (IS_DTLS(session)) 
@@ -952,34 +926,22 @@ int ret;
 
 #define MAX_EMPTY_PACKETS_SEQUENCE 4
 
-/* This function behaves exactly like read(). The only difference is
- * that it accepts the gnutls_session_t and the content_type_t of data to
- * receive (if called by the user the Content is Userdata only)
- * It is intended to receive data, under the current session.
- *
- * The gnutls_handshake_description_t was introduced to support SSL V2.0 
client hellos.
+/* This will receive record layer packets and add them to 
+ * application_data_buffer and handshake_data_buffer.
  */
-ssize_t
-_gnutls_recv_int (gnutls_session_t session, content_type_t type,
-                  gnutls_handshake_description_t htype,
-                  opaque * data, size_t data_size, void* seq)
+static ssize_t
+_gnutls_recv_in_buffers (gnutls_session_t session, content_type_t type,
+                  gnutls_handshake_description_t htype)
 {
   uint64 *packet_sequence;
   uint8_t *ciphertext;
-  int ret, ret2;
+  mbuffer_st* bufel = NULL;
+  int ret;
   int empty_packet = 0;
-  gnutls_datum_t decrypted;
   record_parameters_st *record_params;
   record_state_st *record_state;
   struct tls_record_st record;
 
-  memset(&record, 0, sizeof(record));
-
-  if (type != GNUTLS_ALERT && (data_size == 0 || data == NULL))
-    {
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
 begin:
 
   if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
@@ -988,6 +950,8 @@ begin:
       return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
     }
 
+  memset(&record, 0, sizeof(record));
+
   if (session->internals.read_eof != 0)
     {
       /* if we have already read an EOF
@@ -1001,20 +965,6 @@ begin:
       return GNUTLS_E_INVALID_SESSION;
     }
 
-  /* If we have enough data in the cache do not bother receiving
-   * a new packet. (in order to flush the cache)
-   */
-  ret = check_buffers (session, type, data, data_size);
-  if (ret != 0)
-    return ret;
-
-  ret = recv_headers(session, type, htype, &record);
-  if (ret < 0)
-    {
-      gnutls_assert();
-      goto recv_error;
-    }
-
   /* get the record state parameters */
   ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
   if (ret < 0)
@@ -1026,15 +976,19 @@ begin:
 
   record_state = &record_params->read;
 
-  /* Check if the DTLS epoch is valid */
+  /* receive headers */
+  ret = recv_headers(session, type, htype, &record);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto recv_error;
+    }
+
   if (IS_DTLS(session)) 
     packet_sequence = &record.sequence;
   else
     packet_sequence = &record_state->sequence_number;
 
-  if (seq)
-    memcpy(seq, packet_sequence, 8);
-
   /* Read the packet data and insert it to record_recv_buffer.
    */
   ret =
@@ -1055,22 +1009,15 @@ begin:
       gnutls_assert ();
       return ret;
     }
-  _mbuffer_get_first (&session->internals.record_recv_buffer, &record.data);
-  ciphertext = &record.data.data[record.header_size];
-
-  ret = get_temp_recv_buffer (session, &decrypted);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
+  bufel = _mbuffer_head_pop_first (&session->internals.record_recv_buffer);
+  ciphertext = &bufel->msg.data[record.header_size];
 
   /* decrypt the data we got. 
    */
   ret =
-    _gnutls_decrypt (session, ciphertext, record.length, decrypted.data, 
decrypted.size,
+    _gnutls_decrypt (session, ciphertext, record.length, bufel->msg.data, 
bufel->maximum_size,
                     record.type, record_params, packet_sequence);
-  decrypted.size = ret;
+  bufel->msg.size = ret;
 
   if (ret < 0)
     {
@@ -1078,9 +1025,8 @@ begin:
       goto sanity_check_error;
     }
 
-  /* remove the decrypted packet from buffers */
-  _mbuffer_remove_bytes (&session->internals.record_recv_buffer,
-                         record.packet_size);
+  /* bufel now holds the decrypted data
+   */
 
   /* check for duplicates. We check after the message
    * is processed and authenticated to avoid someone
@@ -1093,33 +1039,14 @@ begin:
         {
           _gnutls_audit_log("Discarded duplicate message[%u]\n",
             (unsigned int) _gnutls_uint64touint32 (packet_sequence));
-          goto discard2;
-        }
-    }
-
-  /* Check if this is a CHANGE_CIPHER_SPEC
-   */
-  if (type == GNUTLS_CHANGE_CIPHER_SPEC && type == record.type)
-    {
-
-      _gnutls_record_log
-        ("REC[%p]: ChangeCipherSpec Packet was received\n", session);
-
-      if ((size_t) decrypted.size != data_size)
-        {                       /* data_size should be 1 */
-          gnutls_assert ();
-          ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
           goto sanity_check_error;
         }
-      data[0] = decrypted.data[0];
-      
-      return 1;
     }
 
   _gnutls_record_log
     ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
      (int) _gnutls_uint64touint32 (packet_sequence),
-     _gnutls_packet2str (record.type), record.type, decrypted.size);
+     _gnutls_packet2str (record.type), record.type, bufel->msg.size);
 
   /* increase sequence number 
    */
@@ -1127,50 +1054,8 @@ begin:
     {
       session_invalidate (session);
       gnutls_assert ();
-      return GNUTLS_E_RECORD_LIMIT_REACHED;
-    }
-
-  ret =
-    record_add_to_buffers (session, record.type, type, htype, decrypted.data, 
decrypted.size);
-  if (ret < 0)
-    {
-      if (ret == GNUTLS_E_INT_RET_0)
-        return 0;
-      gnutls_assert ();
-      return ret;
-    }
-
-  /* Get Application data from buffer 
-   */
-  if ((record.type == type) &&
-      (type == GNUTLS_APPLICATION_DATA ||
-       type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
-    {
-
-      ret = _gnutls_record_buffer_get (type, session, data, data_size);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      /* if the buffer just got empty 
-       */
-      if (_gnutls_record_buffer_get_size (type, session) == 0)
-        {
-          if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
-            {
-              gnutls_assert ();
-              return ret2;
-            }
-        }
-    }
-  else
-    {
-      gnutls_assert ();
-      return GNUTLS_E_UNEXPECTED_PACKET;
-      /* we didn't get what we wanted to 
-       */
+      ret = GNUTLS_E_RECORD_LIMIT_REACHED;
+      goto sanity_check_error;
     }
 
 /* (originally for) TLS 1.0 CBC protection. 
@@ -1180,18 +1065,34 @@ begin:
  * In that case we go to the beginning and start reading
  * the next packet.
  */
-  if (ret == 0)
+  if (bufel->msg.size == 0)
     {
+      _mbuffer_xfree(&bufel);
       empty_packet++;
       goto begin;
     }
 
+  ret =
+    record_add_to_buffers (session, record.type, type, htype, 
+      packet_sequence, bufel);
+
+  /* bufel is now either deinitialized or buffered somewhere else */
+
+  if (ret < 0)
+    {
+      if (ret == GNUTLS_E_INT_RET_0)
+        {
+          return 0;
+        }
+      gnutls_assert ();
+      return ret;
+    }
+
   return ret;
 
 discard:
-  _mbuffer_remove_bytes (&session->internals.record_recv_buffer,
-                         record.packet_size);
-discard2:
+  bufel = _mbuffer_head_pop_first(&session->internals.record_recv_buffer);
+  _mbuffer_xfree(&bufel);
   return GNUTLS_E_AGAIN;
 
 sanity_check_error:
@@ -1199,10 +1100,15 @@ sanity_check_error:
     {
       _gnutls_audit_log("Discarded message[%u] due to invalid decryption\n", 
             (unsigned int)_gnutls_uint64touint32 (packet_sequence));
-      goto discard2;
+      ret = GNUTLS_E_AGAIN;
+      goto cleanup;
     }
+
   session_unresumable (session);
   session_invalidate (session);
+
+cleanup:
+  _mbuffer_xfree(&bufel);
   return ret;
 
 recv_error:
@@ -1228,6 +1134,52 @@ recv_error:
     return ret;
 }
 
+/* This function behaves exactly like read(). The only difference is
+ * that it accepts the gnutls_session_t and the content_type_t of data to
+ * receive (if called by the user the Content is Userdata only)
+ * It is intended to receive data, under the current session.
+ *
+ * The gnutls_handshake_description_t was introduced to support SSL V2.0 
client hellos.
+ */
+ssize_t
+_gnutls_recv_int (gnutls_session_t session, content_type_t type,
+                  gnutls_handshake_description_t htype,
+                  opaque * data, size_t data_size, void* seq)
+{
+  int ret;
+
+  if (type != GNUTLS_ALERT && (data_size == 0 || data == NULL))
+    {
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (session->internals.read_eof != 0)
+    {
+      /* if we have already read an EOF
+       */
+      return 0;
+    }
+  else if (session_is_valid (session) != 0
+           || session->internals.may_not_read != 0)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_SESSION;
+    }
+
+  /* If we have enough data in the cache do not bother receiving
+   * a new packet. (in order to flush the cache)
+   */
+  ret = check_buffers (session, type, data, data_size, seq);
+  if (ret != 0)
+    return ret;
+
+  ret = _gnutls_recv_in_buffers(session, type, htype);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  return check_buffers (session, type, data, data_size, seq);
+}
+
 
 /**
  * gnutls_record_send:
diff --git a/lib/gnutls_record.h b/lib/gnutls_record.h
index f413471..d1099ea 100644
--- a/lib/gnutls_record.h
+++ b/lib/gnutls_record.h
@@ -37,4 +37,6 @@ ssize_t _gnutls_recv_int (gnutls_session_t session, 
content_type_t type,
                           gnutls_handshake_description_t, opaque * data,
                           size_t sizeofdata, void* seq);
 
+int _gnutls_get_max_decrypted_data(gnutls_session_t session);
+
 #endif
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index e21b8e5..e22dada 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -268,8 +268,6 @@ _gnutls_handshake_internal_state_clear (gnutls_session_t 
session)
 {
   _gnutls_handshake_internal_state_init (session);
 
-  _gnutls_free_datum (&session->internals.recv_buffer);
-
   deinit_internal_params (session);
   
   _gnutls_epoch_gc(session);
@@ -318,15 +316,13 @@ gnutls_init (gnutls_session_t * session, 
gnutls_connection_end_t con_end)
   (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
 
   /* Initialize buffers */
-  _gnutls_buffer_init (&(*session)->internals.application_data_buffer);
-  _gnutls_buffer_init (&(*session)->internals.handshake_data_buffer);
   _gnutls_buffer_init (&(*session)->internals.handshake_hash_buffer);
-  _gnutls_buffer_init (&(*session)->internals.ia_data_buffer);
 
-  _mbuffer_init (&(*session)->internals.record_send_buffer);
-  _mbuffer_init (&(*session)->internals.record_recv_buffer);
+  _mbuffer_head_init (&(*session)->internals.record_buffer);
+  _mbuffer_head_init (&(*session)->internals.record_send_buffer);
+  _mbuffer_head_init (&(*session)->internals.record_recv_buffer);
 
-  _mbuffer_init (&(*session)->internals.handshake_send_buffer);
+  _mbuffer_head_init (&(*session)->internals.handshake_send_buffer);
   _gnutls_buffer_init (&(*session)->internals.handshake_recv_buffer);
 
   (*session)->key = gnutls_calloc (1, sizeof (struct gnutls_key_st));
@@ -456,12 +452,10 @@ gnutls_deinit (gnutls_session_t session)
         session->record_parameters[i] = NULL;
       }
 
-  _gnutls_buffer_clear (&session->internals.ia_data_buffer);
   _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
-  _gnutls_buffer_clear (&session->internals.handshake_data_buffer);
-  _gnutls_buffer_clear (&session->internals.application_data_buffer);
-  _mbuffer_clear (&session->internals.record_recv_buffer);
-  _mbuffer_clear (&session->internals.record_send_buffer);
+  _mbuffer_head_clear (&session->internals.record_buffer);
+  _mbuffer_head_clear (&session->internals.record_recv_buffer);
+  _mbuffer_head_clear (&session->internals.record_send_buffer);
 
   gnutls_credentials_clear (session);
   _gnutls_selected_certs_deinit (session);
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 5e26fd2..6363df9 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -345,8 +345,6 @@ extern "C"
    *   recognized.
    * @GNUTLS_A_UNKNOWN_PSK_IDENTITY: The SRP/PSK username is missing
    *   or not known.
-   * @GNUTLS_A_INNER_APPLICATION_FAILURE: Inner application
-   *   negotiation failed.
    *
    * Enumeration of different TLS alerts.
    */
diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c
index 7203816..5811498 100644
--- a/src/certtool-cfg.c
+++ b/src/certtool-cfg.c
@@ -251,7 +251,7 @@ read_int_with_default (const char *input_str, int def)
   char *endptr;
   long l;
 
-  printf (input_str, def);
+  fprintf (stderr, input_str, def);
   in = readline ("");
   if (in == NULL)
     {
diff --git a/src/certtool.c b/src/certtool.c
index ebd1d8e..520b781 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -2372,6 +2372,13 @@ generate_pkcs12 (common_info_st * cinfo)
     pass = info.pass;
   else
     pass = get_pass ();
+    
+  if (pass == NULL)
+    {
+      fprintf(stderr, "No password given for PKCS #12. Assuming null 
password...\n");
+      pass = "";
+    }
+    
 
   for (i = 0; i < ncrts; i++)
     {


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]