Added gnutls_record_is_async()
[gnutls:gnutls.git] / lib / gnutls_record.c
1 /*
2  * Copyright (C) 2000-2013 Free Software Foundation, Inc.
3  * Copyright (C) 2012,2013 Nikos Mavrogiannopoulos
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>
21  *
22  */
23
24 /* Functions that are record layer specific, are included in this file.
25  */
26
27 /* allocate this many bytes more when encrypting or decrypting, to
28  * compensate for broken backends such as cryptodev.
29  */
30 #define CIPHER_SLACK_SIZE 32
31
32 #include "gnutls_int.h"
33 #include "gnutls_errors.h"
34 #include "debug.h"
35 #include "gnutls_compress.h"
36 #include "gnutls_cipher.h"
37 #include "gnutls_buffers.h"
38 #include "gnutls_mbuffers.h"
39 #include "gnutls_handshake.h"
40 #include "gnutls_hash_int.h"
41 #include "gnutls_cipher_int.h"
42 #include "algorithms.h"
43 #include "gnutls_db.h"
44 #include "gnutls_auth.h"
45 #include "gnutls_num.h"
46 #include "gnutls_record.h"
47 #include "gnutls_datum.h"
48 #include "gnutls_constate.h"
49 #include "ext/max_record.h"
50 #include <ext/heartbeat.h>
51 #include <gnutls_state.h>
52 #include <gnutls_dtls.h>
53 #include <gnutls_dh.h>
54 #include <random.h>
55
56 struct tls_record_st {
57         uint16_t header_size;
58         uint8_t version[2];
59         uint64 sequence;        /* DTLS */
60         uint16_t length;
61         uint16_t packet_size;   /* header_size + length */
62         content_type_t type;
63         uint16_t epoch;         /* valid in DTLS only */
64         unsigned v2:1;          /* whether an SSLv2 client hello */
65         /* the data */
66 };
67
68 /**
69  * gnutls_record_disable_padding:  
70  * @session: is a #gnutls_session_t structure.
71  *
72  * Used to disabled padding in TLS 1.0 and above.  Normally you do not
73  * need to use this function, but there are buggy clients that
74  * complain if a server pads the encrypted data.  This of course will
75  * disable protection against statistical attacks on the data.
76  *
77  * This functions is defunt since 3.1.7. Random padding is disabled
78  * by default unless requested using gnutls_range_send_message().
79  *
80  **/
81 void gnutls_record_disable_padding(gnutls_session_t session)
82 {
83         return;
84 }
85
86 /**
87  * gnutls_record_set_max_empty_records:
88  * @session: is a #gnutls_session_t structure.
89  * @i: is the desired value of maximum empty records that can be accepted in a row.
90  *
91  * Used to set the maximum number of empty fragments that can be accepted
92  * in a row. Accepting many empty fragments is useful for receiving length-hidden
93  * content, where empty fragments filled with pad are sent to hide the real
94  * length of a message. However, a malicious peer could send empty fragments to
95  * mount a DoS attack, so as a safety measure, a maximum number of empty fragments
96  * is accepted by default. If you know your application must accept a given number
97  * of empty fragments in a row, you can use this function to set the desired value.
98  **/
99 void
100 gnutls_record_set_max_empty_records(gnutls_session_t session,
101                                     const unsigned int i)
102 {
103         session->internals.priorities.max_empty_records = i;
104 }
105
106 /**
107  * gnutls_transport_set_ptr:
108  * @session: is a #gnutls_session_t structure.
109  * @ptr: is the value.
110  *
111  * Used to set the first argument of the transport function (for push
112  * and pull callbacks). In berkeley style sockets this function will set the
113  * connection descriptor.
114  * 
115  **/
116 void
117 gnutls_transport_set_ptr(gnutls_session_t session,
118                          gnutls_transport_ptr_t ptr)
119 {
120         session->internals.transport_recv_ptr = ptr;
121         session->internals.transport_send_ptr = ptr;
122 }
123
124 /**
125  * gnutls_transport_set_ptr2:
126  * @session: is a #gnutls_session_t structure.
127  * @recv_ptr: is the value for the pull function
128  * @send_ptr: is the value for the push function
129  *
130  * Used to set the first argument of the transport function (for push
131  * and pull callbacks). In berkeley style sockets this function will set the
132  * connection descriptor.  With this function you can use two different
133  * pointers for receiving and sending.
134  **/
135 void
136 gnutls_transport_set_ptr2(gnutls_session_t session,
137                           gnutls_transport_ptr_t recv_ptr,
138                           gnutls_transport_ptr_t send_ptr)
139 {
140         session->internals.transport_send_ptr = send_ptr;
141         session->internals.transport_recv_ptr = recv_ptr;
142 }
143
144 /**
145  * gnutls_transport_set_int2:
146  * @session: is a #gnutls_session_t structure.
147  * @recv_int: is the value for the pull function
148  * @send_int: is the value for the push function
149  *
150  * Used to set the first argument of the transport function (for push
151  * and pull callbacks), when using the berkeley style sockets. 
152  * With this function you can set two different
153  * pointers for receiving and sending.
154  *
155  * Since: 3.1.9
156  **/
157 void
158 gnutls_transport_set_int2(gnutls_session_t session,
159                           int recv_int, int send_int)
160 {
161         session->internals.transport_send_ptr =
162             (gnutls_transport_ptr_t) (long) send_int;
163         session->internals.transport_recv_ptr =
164             (gnutls_transport_ptr_t) (long) recv_int;
165 }
166
167 #if 0
168 /* this will be a macro */
169 /**
170  * gnutls_transport_set_int:
171  * @session: is a #gnutls_session_t structure.
172  * @i: is the value.
173  *
174  * Used to set the first argument of the transport function (for push
175  * and pull callbacks) for berkeley style sockets.
176  *
177  * Since: 3.1.9
178  * 
179  **/
180 void gnutls_transport_set_int(gnutls_session_t session, int i)
181 {
182         session->internals.transport_recv_ptr =
183             (gnutls_transport_ptr_t) (long) i;
184         session->internals.transport_send_ptr =
185             (gnutls_transport_ptr_t) (long) i;
186 }
187 #endif
188
189 /**
190  * gnutls_transport_get_ptr:
191  * @session: is a #gnutls_session_t structure.
192  *
193  * Used to get the first argument of the transport function (like
194  * PUSH and PULL).  This must have been set using
195  * gnutls_transport_set_ptr().
196  *
197  * Returns: The first argument of the transport function.
198  **/
199 gnutls_transport_ptr_t gnutls_transport_get_ptr(gnutls_session_t session)
200 {
201         return session->internals.transport_recv_ptr;
202 }
203
204 /**
205  * gnutls_transport_get_ptr2:
206  * @session: is a #gnutls_session_t structure.
207  * @recv_ptr: will hold the value for the pull function
208  * @send_ptr: will hold the value for the push function
209  *
210  * Used to get the arguments of the transport functions (like PUSH
211  * and PULL).  These should have been set using
212  * gnutls_transport_set_ptr2().
213  **/
214 void
215 gnutls_transport_get_ptr2(gnutls_session_t session,
216                           gnutls_transport_ptr_t * recv_ptr,
217                           gnutls_transport_ptr_t * send_ptr)
218 {
219
220         *recv_ptr = session->internals.transport_recv_ptr;
221         *send_ptr = session->internals.transport_send_ptr;
222 }
223
224 /**
225  * gnutls_transport_get_int2:
226  * @session: is a #gnutls_session_t structure.
227  * @recv_int: will hold the value for the pull function
228  * @send_int: will hold the value for the push function
229  *
230  * Used to get the arguments of the transport functions (like PUSH
231  * and PULL).  These should have been set using
232  * gnutls_transport_set_int2().
233  *
234  * Since: 3.1.9
235  **/
236 void
237 gnutls_transport_get_int2(gnutls_session_t session,
238                           int *recv_int, int *send_int)
239 {
240
241         *recv_int = (long) session->internals.transport_recv_ptr;
242         *send_int = (long) session->internals.transport_send_ptr;
243 }
244
245 /**
246  * gnutls_transport_get_int:
247  * @session: is a #gnutls_session_t structure.
248  *
249  * Used to get the first argument of the transport function (like
250  * PUSH and PULL).  This must have been set using
251  * gnutls_transport_set_int().
252  *
253  * Returns: The first argument of the transport function.
254  *
255  * Since: 3.1.9
256  **/
257 int gnutls_transport_get_int(gnutls_session_t session)
258 {
259         return (long) session->internals.transport_recv_ptr;
260 }
261
262 /**
263  * gnutls_bye:
264  * @session: is a #gnutls_session_t structure.
265  * @how: is an integer
266  *
267  * Terminates the current TLS/SSL connection. The connection should
268  * have been initiated using gnutls_handshake().  @how should be one
269  * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
270  *
271  * In case of %GNUTLS_SHUT_RDWR the TLS session gets
272  * terminated and further receives and sends will be disallowed.  If
273  * the return value is zero you may continue using the underlying
274  * transport layer. %GNUTLS_SHUT_RDWR sends an alert containing a close
275  * request and waits for the peer to reply with the same message.
276  *
277  * In case of %GNUTLS_SHUT_WR the TLS session gets terminated
278  * and further sends will be disallowed. In order to reuse the
279  * connection you should wait for an EOF from the peer.
280  * %GNUTLS_SHUT_WR sends an alert containing a close request.
281  *
282  * Note that not all implementations will properly terminate a TLS
283  * connection.  Some of them, usually for performance reasons, will
284  * terminate only the underlying transport layer, and thus not
285  * distinguishing between a malicious party prematurely terminating 
286  * the connection and normal termination. 
287  *
288  * This function may also return %GNUTLS_E_AGAIN or
289  * %GNUTLS_E_INTERRUPTED; cf.  gnutls_record_get_direction().
290  *
291  * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
292  *   function documentation for entire semantics.
293  **/
294 int gnutls_bye(gnutls_session_t session, gnutls_close_request_t how)
295 {
296         int ret = 0;
297
298         switch (STATE) {
299         case STATE0:
300         case STATE60:
301                 ret = _gnutls_io_write_flush(session);
302                 STATE = STATE60;
303                 if (ret < 0) {
304                         gnutls_assert();
305                         return ret;
306                 }
307                 /* fallthrough */
308         case STATE61:
309                 ret =
310                     gnutls_alert_send(session, GNUTLS_AL_WARNING,
311                                       GNUTLS_A_CLOSE_NOTIFY);
312                 STATE = STATE61;
313                 if (ret < 0) {
314                         gnutls_assert();
315                         return ret;
316                 }
317
318         case STATE62:
319                 STATE = STATE62;
320                 if (how == GNUTLS_SHUT_RDWR) {
321                         do {
322                                 ret =
323                                     _gnutls_recv_int(session, GNUTLS_ALERT,
324                                                      -1, NULL, NULL, 0, NULL,
325                                                      session->internals.
326                                                      record_timeout_ms);
327                         }
328                         while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
329
330                         if (ret >= 0)
331                                 session->internals.may_not_read = 1;
332
333                         if (ret < 0) {
334                                 gnutls_assert();
335                                 return ret;
336                         }
337                 }
338                 STATE = STATE62;
339
340                 break;
341         default:
342                 gnutls_assert();
343                 return GNUTLS_E_INTERNAL_ERROR;
344         }
345
346         STATE = STATE0;
347
348         session->internals.may_not_write = 1;
349         return 0;
350 }
351
352 inline static void session_unresumable(gnutls_session_t session)
353 {
354         session->internals.resumable = RESUME_FALSE;
355 }
356
357 /* returns 0 if session is valid
358  */
359 inline static int session_is_valid(gnutls_session_t session)
360 {
361         if (session->internals.invalid_connection != 0)
362                 return GNUTLS_E_INVALID_SESSION;
363
364         return 0;
365 }
366
367 /* Copies the record version into the headers. The 
368  * version must have 2 bytes at least.
369  */
370 inline static void
371 copy_record_version(gnutls_session_t session,
372                     gnutls_handshake_description_t htype,
373                     uint8_t version[2])
374 {
375         const version_entry_st *lver;
376
377         if (session->internals.initial_negotiation_completed
378             || htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
379             || session->internals.default_record_version[0] == 0) {
380                 lver = get_version(session);
381
382                 version[0] = lver->major;
383                 version[1] = lver->minor;
384         } else {
385                 version[0] = session->internals.default_record_version[0];
386                 version[1] = session->internals.default_record_version[1];
387         }
388 }
389
390 /* Increments the sequence value
391  */
392 inline static int
393 sequence_increment(gnutls_session_t session, uint64 * value)
394 {
395         if (IS_DTLS(session)) {
396                 return _gnutls_uint48pp(value);
397         } else {
398                 return _gnutls_uint64pp(value);
399         }
400 }
401
402 /* This function behaves exactly like write(). The only difference is
403  * that it accepts, the gnutls_session_t and the content_type_t of data to
404  * send (if called by the user the Content is specific)
405  * It is intended to transfer data, under the current session.    
406  *
407  * @type: The content type to send
408  * @htype: If this is a handshake message then the handshake type
409  * @epoch_rel: %EPOCH_READ_* or %EPOCH_WRITE_*
410  * @data: the data to be sent
411  * @data_size: the size of the @data
412  * @min_pad: the minimum required padding
413  * @mflags: zero or %MBUFFER_FLUSH
414  *
415  * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
416  * This makes the function much easier to read, and more error resistant
417  * (there were cases were the old function could mess everything up).
418  * --nmav
419  *
420  * This function may accept a NULL pointer for data, and 0 for size, if
421  * and only if the previous send was interrupted for some reason.
422  *
423  */
424 ssize_t
425 _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type,
426                       gnutls_handshake_description_t htype,
427                       unsigned int epoch_rel, const void *_data,
428                       size_t data_size, size_t min_pad,
429                       unsigned int mflags)
430 {
431         mbuffer_st *bufel;
432         ssize_t cipher_size;
433         int retval, ret;
434         int send_data_size;
435         uint8_t *headers;
436         int header_size;
437         const uint8_t *data = _data;
438         record_parameters_st *record_params;
439         size_t max_send_size;
440         record_state_st *record_state;
441
442         ret = _gnutls_epoch_get(session, epoch_rel, &record_params);
443         if (ret < 0)
444                 return gnutls_assert_val(ret);
445
446         /* Safeguard against processing data with an incomplete cipher state. */
447         if (!record_params->initialized)
448                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
449
450         record_state = &record_params->write;
451
452         /* Do not allow null pointer if the send buffer is empty.
453          * If the previous send was interrupted then a null pointer is
454          * ok, and means to resume.
455          */
456         if (session->internals.record_send_buffer.byte_length == 0 &&
457             (data_size == 0 && _data == NULL)) {
458                 gnutls_assert();
459                 return GNUTLS_E_INVALID_REQUEST;
460         }
461
462         if (type != GNUTLS_ALERT)       /* alert messages are sent anyway */
463                 if (session_is_valid(session)
464                     || session->internals.may_not_write != 0) {
465                         gnutls_assert();
466                         return GNUTLS_E_INVALID_SESSION;
467                 }
468
469         max_send_size = max_user_send_size(session, record_params);
470
471         if (data_size > max_send_size) {
472                 if (IS_DTLS(session))
473                         return gnutls_assert_val(GNUTLS_E_LARGE_PACKET);
474
475                 send_data_size = max_send_size;
476         } else
477                 send_data_size = data_size;
478
479         /* Only encrypt if we don't have data to send 
480          * from the previous run. - probably interrupted.
481          */
482         if (mflags != 0
483             && session->internals.record_send_buffer.byte_length > 0) {
484                 ret = _gnutls_io_write_flush(session);
485                 if (ret > 0)
486                         cipher_size = ret;
487                 else
488                         cipher_size = 0;
489
490                 retval = session->internals.record_send_buffer_user_size;
491         } else {
492                 if (unlikely((send_data_size == 0 && min_pad == 0)))
493                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
494
495                 /* now proceed to packet encryption
496                  */
497                 cipher_size = MAX_RECORD_SEND_SIZE(session);
498
499                 bufel = _mbuffer_alloc_align16(cipher_size + CIPHER_SLACK_SIZE, 
500                         get_total_headers2(session, record_params));
501                 if (bufel == NULL)
502                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
503
504                 headers = _mbuffer_get_uhead_ptr(bufel);
505                 headers[0] = type;
506                 /* Use the default record version, if it is
507                  * set. */
508                 copy_record_version(session, htype, &headers[1]);
509                 /* Adjust header length and add sequence for DTLS */
510                 if (IS_DTLS(session))
511                         memcpy(&headers[3],
512                                &record_state->sequence_number.i, 8);
513
514                 _gnutls_record_log
515                     ("REC[%p]: Preparing Packet %s(%d) with length: %d and min pad: %d\n",
516                      session, _gnutls_packet2str(type), type,
517                      (int) data_size, (int) min_pad);
518
519                 header_size = RECORD_HEADER_SIZE(session);
520                 _mbuffer_set_udata_size(bufel, cipher_size);
521                 _mbuffer_set_uhead_size(bufel, header_size);
522
523                 ret =
524                     _gnutls_encrypt(session,
525                                     data, send_data_size, min_pad,
526                                     bufel, type, record_params);
527                 if (ret <= 0) {
528                         gnutls_assert();
529                         if (ret == 0)
530                                 ret = GNUTLS_E_ENCRYPTION_FAILED;
531                         gnutls_free(bufel);
532                         return ret;     /* error */
533                 }
534
535                 cipher_size = _mbuffer_get_udata_size(bufel);
536                 retval = send_data_size;
537                 session->internals.record_send_buffer_user_size =
538                     send_data_size;
539
540                 /* increase sequence number
541                  */
542                 if (sequence_increment
543                     (session, &record_state->sequence_number) != 0) {
544                         session_invalidate(session);
545                         gnutls_free(bufel);
546                         return
547                             gnutls_assert_val
548                             (GNUTLS_E_RECORD_LIMIT_REACHED);
549                 }
550
551                 ret = _gnutls_io_write_buffered(session, bufel, mflags);
552         }
553
554         if (ret != cipher_size) {
555                 /* If we have sent any data then just return
556                  * the error value. Do not invalidate the session.
557                  */
558                 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
559                         return gnutls_assert_val(ret);
560
561                 if (ret > 0)
562                         ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
563
564                 session_unresumable(session);
565                 session->internals.may_not_write = 1;
566                 return gnutls_assert_val(ret);
567         }
568
569         session->internals.record_send_buffer_user_size = 0;
570
571         _gnutls_record_log
572             ("REC[%p]: Sent Packet[%d] %s(%d) in epoch %d and length: %d\n",
573              session, (unsigned int)
574              _gnutls_uint64touint32(&record_state->sequence_number),
575              _gnutls_packet2str(type), type, (int) record_params->epoch,
576              (int) cipher_size);
577
578         return retval;
579 }
580
581 inline static int
582 check_recv_type(gnutls_session_t session, content_type_t recv_type)
583 {
584         switch (recv_type) {
585         case GNUTLS_CHANGE_CIPHER_SPEC:
586         case GNUTLS_ALERT:
587         case GNUTLS_HANDSHAKE:
588         case GNUTLS_HEARTBEAT:
589         case GNUTLS_APPLICATION_DATA:
590                 return 0;
591         default:
592                 gnutls_assert();
593                 _gnutls_audit_log(session,
594                                   "Received record packet of unknown type %u\n",
595                                   (unsigned int) recv_type);
596                 return GNUTLS_E_UNEXPECTED_PACKET;
597         }
598
599 }
600
601
602 /* Checks if there are pending data in the record buffers. If there are
603  * then it copies the data.
604  */
605 static int
606 check_buffers(gnutls_session_t session, content_type_t type,
607               uint8_t * data, int data_size, void *seq)
608 {
609         if ((type == GNUTLS_APPLICATION_DATA ||
610              type == GNUTLS_HANDSHAKE || type == GNUTLS_CHANGE_CIPHER_SPEC)
611             && _gnutls_record_buffer_get_size(session) > 0) {
612                 int ret;
613                 ret =
614                     _gnutls_record_buffer_get(type, session, data,
615                                               data_size, seq);
616                 if (ret < 0) {
617                         if (IS_DTLS(session)) {
618                                 if (ret == GNUTLS_E_UNEXPECTED_PACKET) {
619                                         ret = GNUTLS_E_AGAIN;
620                                 }
621                         }
622                         gnutls_assert();
623                         return ret;
624                 }
625
626                 return ret;
627         }
628
629         return 0;
630 }
631
632 /* Checks and retrieves any pending data in the application data record buffers.
633  */
634 static int
635 check_packet_buffers(gnutls_session_t session, content_type_t type,
636                      gnutls_packet_t *packet)
637 {
638         if (_gnutls_record_buffer_get_size(session) > 0) {
639                 int ret;
640                 ret =
641                     _gnutls_record_buffer_get_packet(type, session,
642                                                      packet);
643                 if (ret < 0) {
644                         if (IS_DTLS(session)) {
645                                 if (ret == GNUTLS_E_UNEXPECTED_PACKET) {
646                                         ret = GNUTLS_E_AGAIN;
647                                 }
648                         }
649                         gnutls_assert();
650                         return ret;
651                 }
652
653                 return ret;
654         }
655
656         *packet = NULL;
657         return 0;
658 }
659
660
661
662 /* Here we check if the advertized version is the one we
663  * negotiated in the handshake.
664  */
665 inline static int
666 record_check_version(gnutls_session_t session,
667                      gnutls_handshake_description_t htype,
668                      uint8_t version[2])
669 {
670         const version_entry_st *vers = get_version(session);
671         int diff = 0;
672
673         if (vers->major != version[0] || vers->minor != version[1])
674                 diff = 1;
675
676         if (!IS_DTLS(session)) {
677                 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO ||
678                     htype == GNUTLS_HANDSHAKE_SERVER_HELLO) {
679                         if (version[0] != 3) {
680                                 gnutls_assert();
681                                 _gnutls_record_log
682                                     ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
683                                      session, htype, version[0],
684                                      version[1]);
685                                 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
686                         }
687                 } else if (diff != 0) {
688                         /* Reject record packets that have a different version than the
689                          * one negotiated. Note that this version is not protected by any
690                          * mac. I don't really think that this check serves any purpose.
691                          */
692                         gnutls_assert();
693                         _gnutls_record_log
694                             ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
695                              session, htype, version[0], version[1]);
696
697                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
698                 }
699         } else {                /* DTLS */
700
701                 /* In DTLS the only information we have here is whether we
702                  * expect a handshake message or not.
703                  */
704                 if (htype == (gnutls_handshake_description_t) - 1) {
705                         if (diff) {
706                                 /* Reject record packets that have a different version than the
707                                  * one negotiated. Note that this version is not protected by any
708                                  * mac. I don't really think that this check serves any purpose.
709                                  */
710                                 gnutls_assert();
711                                 _gnutls_record_log
712                                     ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
713                                      session, htype, version[0],
714                                      version[1]);
715
716                                 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
717                         }
718                 } else if (vers->id > GNUTLS_DTLS1_0 && version[0] > 254) {
719                         gnutls_assert();
720                         _gnutls_record_log
721                             ("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n",
722                              session, htype, version[0], version[1]);
723                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
724                 } else if (vers->id == GNUTLS_DTLS0_9 && version[0] > 1) {
725                         gnutls_assert();
726                         _gnutls_record_log
727                             ("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n",
728                              session, htype, version[0], version[1]);
729                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
730                 }
731         }
732
733         return 0;
734 }
735
736 /* This function will check if the received record type is
737  * the one we actually expect and adds it to the proper
738  * buffer. The bufel will be deinitialized after calling
739  * this function, even if it fails.
740  */
741 static int
742 record_add_to_buffers(gnutls_session_t session,
743                       struct tls_record_st *recv, content_type_t type,
744                       gnutls_handshake_description_t htype,
745                       uint64 * seq, mbuffer_st * bufel)
746 {
747
748         int ret;
749
750         if ((recv->type == type)
751             && (type == GNUTLS_APPLICATION_DATA ||
752                 type == GNUTLS_CHANGE_CIPHER_SPEC ||
753                 type == GNUTLS_HANDSHAKE)) {
754                 _gnutls_record_buffer_put(session, type, seq, bufel);
755
756                 /* if we received application data as expected then we
757                  * deactivate the async timer */
758                 _dtls_async_timer_delete(session);
759         } else {
760                 /* if the expected type is different than the received 
761                  */
762                 switch (recv->type) {
763                 case GNUTLS_ALERT:
764                         if (bufel->msg.size < 2) {
765                                 ret =
766                                     gnutls_assert_val
767                                     (GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
768                                 goto unexpected_packet;
769                         }
770
771                         _gnutls_record_log
772                             ("REC[%p]: Alert[%d|%d] - %s - was received\n",
773                              session, bufel->msg.data[0],
774                              bufel->msg.data[1],
775                              gnutls_alert_get_name((int) bufel->msg.
776                                                    data[1]));
777
778                         session->internals.last_alert = bufel->msg.data[1];
779
780                         /* if close notify is received and
781                          * the alert is not fatal
782                          */
783                         if (bufel->msg.data[1] == GNUTLS_A_CLOSE_NOTIFY
784                             && bufel->msg.data[0] != GNUTLS_AL_FATAL) {
785                                 /* If we have been expecting for an alert do 
786                                  */
787                                 session->internals.read_eof = 1;
788                                 ret = GNUTLS_E_SESSION_EOF;
789                                 goto cleanup;
790                         } else {
791                                 /* if the alert is FATAL or WARNING
792                                  * return the apropriate message
793                                  */
794
795                                 gnutls_assert();
796                                 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
797                                 if (bufel->msg.data[0] == GNUTLS_AL_FATAL) {
798                                         session_unresumable(session);
799                                         session_invalidate(session);
800                                         ret =
801                                             gnutls_assert_val
802                                             (GNUTLS_E_FATAL_ALERT_RECEIVED);
803                                 }
804                                 goto cleanup;
805                         }
806                         break;
807
808                 case GNUTLS_CHANGE_CIPHER_SPEC:
809                         if (!(IS_DTLS(session))) {
810                                 ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
811                                 goto cleanup;
812                         }
813
814                         _gnutls_record_buffer_put(session, recv->type, seq,
815                                                   bufel);
816
817                         break;
818
819 #ifdef ENABLE_HEARTBEAT
820                 case GNUTLS_HEARTBEAT:
821                         ret = _gnutls_heartbeat_handle(session, bufel);
822                         goto cleanup;
823 #endif
824
825                 case GNUTLS_APPLICATION_DATA:
826                         if (session->internals.
827                             initial_negotiation_completed == 0) {
828                                 ret =
829                                     gnutls_assert_val
830                                     (GNUTLS_E_UNEXPECTED_PACKET);
831                                 goto unexpected_packet;
832                         }
833
834
835                         /* the got_application data is only returned
836                          * if expecting client hello (for rehandshake
837                          * reasons). Otherwise it is an unexpected packet
838                          */
839                         if (type == GNUTLS_ALERT
840                             || ((htype == GNUTLS_HANDSHAKE_SERVER_HELLO || htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
841                                 && type == GNUTLS_HANDSHAKE)) {
842                                 /* even if data is unexpected put it into the buffer */
843                                 _gnutls_record_buffer_put(session, recv->type,
844                                                           seq, bufel);
845                                 return
846                                     gnutls_assert_val
847                                     (GNUTLS_E_GOT_APPLICATION_DATA);
848                         } else {
849                                 ret =
850                                     gnutls_assert_val
851                                     (GNUTLS_E_UNEXPECTED_PACKET);
852                                 goto unexpected_packet;
853                         }
854
855                         break;
856
857                 case GNUTLS_HANDSHAKE:
858                         /* In DTLS we might receive a handshake replay from the peer to indicate
859                          * the our last TLS handshake messages were not received.
860                          */
861                         if (IS_DTLS(session)) {
862                                 if (type == GNUTLS_CHANGE_CIPHER_SPEC) {
863                                         ret =
864                                             gnutls_assert_val
865                                             (GNUTLS_E_UNEXPECTED_PACKET);
866                                         goto unexpected_packet;
867                                 }
868
869                                 if (_dtls_is_async(session)
870                                     && _dtls_async_timer_active(session)) {
871                                         if (session->security_parameters.
872                                             entity == GNUTLS_SERVER
873                                             && bufel->htype ==
874                                             GNUTLS_HANDSHAKE_CLIENT_HELLO)
875                                         {
876                                                 /* client requested rehandshake. Delete the timer */
877                                                 _dtls_async_timer_delete
878                                                     (session);
879                                         } else {
880                                                 session->internals.
881                                                     recv_state =
882                                                     RECV_STATE_DTLS_RETRANSMIT;
883                                                 ret =
884                                                     _dtls_retransmit
885                                                     (session);
886                                                 if (ret == 0) {
887                                                         session->internals.
888                                                             recv_state =
889                                                             RECV_STATE_0;
890                                                         ret =
891                                                             gnutls_assert_val
892                                                             (GNUTLS_E_AGAIN);
893                                                         goto unexpected_packet;
894                                                 }
895                                                 goto cleanup;
896                                         }
897                                 }
898                         }
899
900                         /* This is legal if HELLO_REQUEST is received - and we are a client.
901                          * If we are a server, a client may initiate a renegotiation at any time.
902                          */
903                         if (session->security_parameters.entity ==
904                             GNUTLS_SERVER
905                             && bufel->htype ==
906                             GNUTLS_HANDSHAKE_CLIENT_HELLO) {
907                                 gnutls_assert();
908                                 _gnutls_record_buffer_put(session,
909                                                               recv->type,
910                                                               seq, bufel);
911                                 return GNUTLS_E_REHANDSHAKE;
912                         }
913
914                         /* If we are already in a handshake then a Hello
915                          * Request is illegal. But here we don't really care
916                          * since this message will never make it up here.
917                          */
918
919                         /* So we accept it, if it is a Hello. If not, this will
920                          * fail and trigger flight retransmissions after some time. */
921                         ret =
922                             _gnutls_recv_hello_request(session,
923                                                        bufel->msg.data,
924                                                        bufel->msg.size);
925                         goto unexpected_packet;
926
927                         break;
928                 default:
929
930                         _gnutls_record_log
931                             ("REC[%p]: Received unexpected packet %d (%s) expecting %d (%s)\n",
932                              session, recv->type,
933                              _gnutls_packet2str(recv->type), type,
934                              _gnutls_packet2str(type));
935
936                         gnutls_assert();
937                         ret = GNUTLS_E_UNEXPECTED_PACKET;
938                         goto unexpected_packet;
939                 }
940         }
941
942         return 0;
943
944       unexpected_packet:
945         if (IS_DTLS(session) && ret != GNUTLS_E_REHANDSHAKE) {
946                 _mbuffer_xfree(&bufel);
947                 RETURN_DTLS_EAGAIN_OR_TIMEOUT(session, ret);
948         }
949
950       cleanup:
951         _mbuffer_xfree(&bufel);
952         return ret;
953
954 }
955
956
957 /* Checks the record headers and returns the length, version and
958  * content type.
959  */
960 static void
961 record_read_headers(gnutls_session_t session,
962                     uint8_t headers[MAX_RECORD_HEADER_SIZE],
963                     content_type_t type,
964                     gnutls_handshake_description_t htype,
965                     struct tls_record_st *record)
966 {
967
968         /* Read the first two bytes to determine if this is a 
969          * version 2 message 
970          */
971
972         if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
973             && type == GNUTLS_HANDSHAKE && headers[0] > 127
974             && !(IS_DTLS(session))) {
975
976                 /* if msb set and expecting handshake message
977                  * it should be SSL 2 hello 
978                  */
979                 record->version[0] = 3; /* assume SSL 3.0 */
980                 record->version[1] = 0;
981
982                 record->length = (((headers[0] & 0x7f) << 8)) | headers[1];
983
984                 /* SSL 2.0 headers */
985                 record->header_size = record->packet_size = 2;
986                 record->type = GNUTLS_HANDSHAKE;        /* we accept only v2 client hello
987                                                          */
988
989                 /* in order to assist the handshake protocol.
990                  * V2 compatibility is a mess.
991                  */
992                 record->v2 = 1;
993                 record->epoch = 0;
994                 memset(&record->sequence, 0, sizeof(record->sequence));
995
996                 _gnutls_record_log
997                     ("REC[%p]: SSL 2.0 %s packet received. Length: %d\n",
998                      session, _gnutls_packet2str(record->type),
999                      record->length);
1000
1001         } else {
1002                 /* dtls version 1.0 and TLS version 1.x */
1003                 record->v2 = 0;
1004
1005                 record->type = headers[0];
1006                 record->version[0] = headers[1];
1007                 record->version[1] = headers[2];
1008
1009                 if (IS_DTLS(session)) {
1010                         memcpy(record->sequence.i, &headers[3], 8);
1011                         record->length = _gnutls_read_uint16(&headers[11]);
1012                         record->epoch =
1013                             _gnutls_read_uint16(record->sequence.i);
1014                 } else {
1015                         memset(&record->sequence, 0,
1016                                sizeof(record->sequence));
1017                         record->length = _gnutls_read_uint16(&headers[3]);
1018                         record->epoch = 0;
1019                 }
1020
1021                 _gnutls_record_log
1022                     ("REC[%p]: SSL %d.%d %s packet received. Epoch %d, length: %d\n",
1023                      session, (int) record->version[0],
1024                      (int) record->version[1],
1025                      _gnutls_packet2str(record->type), (int) record->epoch,
1026                      record->length);
1027
1028         }
1029
1030         record->packet_size += record->length;
1031 }
1032
1033
1034 static int recv_headers(gnutls_session_t session, 
1035                         record_parameters_st *record_params,
1036                         content_type_t type,
1037                         gnutls_handshake_description_t htype,
1038                         struct tls_record_st *record, unsigned int *ms)
1039 {
1040         int ret;
1041         gnutls_datum_t raw;     /* raw headers */
1042         /* Read the headers.
1043          */
1044         record->header_size = record->packet_size =
1045             RECORD_HEADER_SIZE(session);
1046
1047         ret =
1048             _gnutls_io_read_buffered(session, record->header_size, -1, ms);
1049         if (ret != record->header_size) {
1050                 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
1051                         return ret;
1052
1053                 if (ret > 0)
1054                         ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1055                 else if (ret == 0)
1056                         ret = GNUTLS_E_PREMATURE_TERMINATION;
1057
1058                 return gnutls_assert_val(ret);
1059         }
1060
1061         ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer, 
1062                 get_total_headers2(session, record_params));
1063         if (ret < 0)
1064                 return gnutls_assert_val(ret);
1065
1066         _mbuffer_head_get_first(&session->internals.record_recv_buffer,
1067                                 &raw);
1068         if (raw.size < RECORD_HEADER_SIZE(session))
1069                 return
1070                     gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1071
1072         record_read_headers(session, raw.data, type, htype, record);
1073
1074         /* Check if the DTLS epoch is valid */
1075         if (IS_DTLS(session)) {
1076                 if (_gnutls_epoch_is_valid(session, record->epoch) == 0) {
1077                         _gnutls_audit_log(session,
1078                                           "Discarded message[%u] with invalid epoch %u.\n",
1079                                           (unsigned int)
1080                                           _gnutls_uint64touint32(&record->
1081                                                                  sequence),
1082                                           (unsigned int) record->sequence.
1083                                           i[0] * 256 +
1084                                           (unsigned int) record->sequence.
1085                                           i[1]);
1086                         gnutls_assert();
1087                         /* doesn't matter, just a fatal error */
1088                         return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1089                 }
1090         }
1091
1092         /* Here we check if the Type of the received packet is
1093          * ok. 
1094          */
1095         if ((ret = check_recv_type(session, record->type)) < 0)
1096                 return gnutls_assert_val(ret);
1097
1098         /* Here we check if the advertized version is the one we
1099          * negotiated in the handshake.
1100          */
1101         if ((ret =
1102              record_check_version(session, htype, record->version)) < 0)
1103                 return gnutls_assert_val(ret);
1104
1105         if (record->length > max_record_recv_size(session)) {
1106                 _gnutls_audit_log
1107                     (session, "Received packet with illegal length: %u\n",
1108                      (unsigned int) record->length);
1109                 return
1110                     gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1111         }
1112
1113         _gnutls_record_log
1114             ("REC[%p]: Expected Packet %s(%d)\n", session,
1115              _gnutls_packet2str(type), type);
1116         _gnutls_record_log
1117             ("REC[%p]: Received Packet %s(%d) with length: %d\n", session,
1118              _gnutls_packet2str(record->type), record->type,
1119              record->length);
1120
1121
1122         return 0;
1123 }
1124
1125 /* @ms: is the number of milliseconds to wait for data. Use zero for indefinite.
1126  *
1127  * This will receive record layer packets and add them to 
1128  * application_data_buffer and handshake_data_buffer.
1129  *
1130  * If the htype is not -1 then handshake timeouts
1131  * will be enforced.
1132  */
1133 ssize_t
1134 _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type,
1135                         gnutls_handshake_description_t htype,
1136                         unsigned int ms)
1137 {
1138         uint64 *packet_sequence;
1139         gnutls_datum_t ciphertext;
1140         mbuffer_st *bufel = NULL, *decrypted = NULL;
1141         gnutls_datum_t t;
1142         int ret;
1143         unsigned int empty_fragments = 0;
1144         record_parameters_st *record_params;
1145         record_state_st *record_state;
1146         struct tls_record_st record;
1147
1148       begin:
1149
1150         if (empty_fragments >
1151             session->internals.priorities.max_empty_records) {
1152                 gnutls_assert();
1153                 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
1154         }
1155
1156         if (session->internals.read_eof != 0) {
1157                 /* if we have already read an EOF
1158                  */
1159                 return 0;
1160         } else if (session_is_valid(session) != 0
1161                    || session->internals.may_not_read != 0)
1162                 return gnutls_assert_val(GNUTLS_E_INVALID_SESSION);
1163
1164         /* get the record state parameters */
1165         ret =
1166             _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
1167         if (ret < 0)
1168                 return gnutls_assert_val(ret);
1169
1170         /* Safeguard against processing data with an incomplete cipher state. */
1171         if (!record_params->initialized)
1172                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1173
1174         record_state = &record_params->read;
1175
1176         /* receive headers */
1177         ret = recv_headers(session, record_params, type, htype, &record, &ms);
1178         if (ret < 0) {
1179                 ret = gnutls_assert_val_fatal(ret);
1180                 goto recv_error;
1181         }
1182
1183         if (IS_DTLS(session))
1184                 packet_sequence = &record.sequence;
1185         else
1186                 packet_sequence = &record_state->sequence_number;
1187
1188         /* Read the packet data and insert it to record_recv_buffer.
1189          */
1190         ret =
1191             _gnutls_io_read_buffered(session, record.packet_size,
1192                                      record.type, &ms);
1193         if (ret != record.packet_size) {
1194                 gnutls_assert();
1195                 goto recv_error;
1196         }
1197
1198         /* ok now we are sure that we have read all the data - so
1199          * move on !
1200          */
1201         ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer, 
1202                 get_total_headers2(session, record_params));
1203         if (ret < 0)
1204                 return gnutls_assert_val(ret);
1205
1206         bufel =
1207             _mbuffer_head_get_first(&session->internals.record_recv_buffer,
1208                                     NULL);
1209         if (bufel == NULL)
1210                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1211
1212         /* We allocate the maximum possible to allow few compressed bytes to expand to a
1213          * full record. Moreover we add space for any pad and the MAC (in case
1214          * they are encrypted).
1215          */
1216         ret = max_decrypted_size(session) + MAX_PAD_SIZE + MAX_HASH_SIZE;
1217         decrypted = _mbuffer_alloc_align16(ret, 0);
1218         if (decrypted == NULL)
1219                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1220
1221         _mbuffer_set_udata_size(decrypted, ret);
1222         ciphertext.data =
1223             (uint8_t *) _mbuffer_get_udata_ptr(bufel) + record.header_size;
1224         ciphertext.size = record.length;
1225
1226         /* decrypt the data we got. 
1227          */
1228         t.data = _mbuffer_get_udata_ptr(decrypted);
1229         t.size = _mbuffer_get_udata_size(decrypted);
1230         ret =
1231             _gnutls_decrypt(session, &ciphertext, &t,
1232                             record.type, record_params, packet_sequence);
1233         if (ret >= 0)
1234                 _mbuffer_set_udata_size(decrypted, ret);
1235
1236         _mbuffer_head_remove_bytes(&session->internals.record_recv_buffer,
1237                                    record.header_size + record.length);
1238         if (ret < 0) {
1239                 gnutls_assert();
1240                 _gnutls_audit_log(session,
1241                                   "Discarded message[%u] due to invalid decryption\n",
1242                                   (unsigned int)
1243                                   _gnutls_uint64touint32(packet_sequence));
1244                 goto sanity_check_error;
1245         }
1246
1247         /* check for duplicates. We check after the message
1248          * is processed and authenticated to avoid someone
1249          * messing with our windows.
1250          */
1251         if (IS_DTLS(session)
1252             && session->internals.no_replay_protection == 0) {
1253                 ret = _dtls_record_check(record_params, packet_sequence);
1254                 if (ret < 0) {
1255                         _gnutls_record_log
1256                             ("REC[%p]: Discarded duplicate message[%u.%u]: %s\n",
1257                              session,
1258                              (unsigned int) record.sequence.i[0] * 256 +
1259                              (unsigned int) record.sequence.i[1],
1260                              (unsigned int)
1261                              _gnutls_uint64touint32(packet_sequence),
1262                              _gnutls_packet2str(record.type));
1263                         goto sanity_check_error;
1264                 }
1265                 _gnutls_record_log
1266                     ("REC[%p]: Decrypted Packet[%u.%u] %s(%d) with length: %d\n",
1267                      session,
1268                      (unsigned int) record.sequence.i[0] * 256 +
1269                      (unsigned int) record.sequence.i[1],
1270                      (unsigned int)
1271                      _gnutls_uint64touint32(packet_sequence),
1272                      _gnutls_packet2str(record.type), record.type,
1273                      (int) _mbuffer_get_udata_size(decrypted));
1274         } else {
1275                 _gnutls_record_log
1276                     ("REC[%p]: Decrypted Packet[%u] %s(%d) with length: %d\n",
1277                      session,
1278                      (unsigned int)
1279                      _gnutls_uint64touint32(packet_sequence),
1280                      _gnutls_packet2str(record.type), record.type,
1281                      (int) _mbuffer_get_udata_size(decrypted));
1282         }
1283
1284         /* increase sequence number 
1285          */
1286         if (!IS_DTLS(session)
1287             && sequence_increment(session,
1288                                   &record_state->sequence_number) != 0) {
1289                 session_invalidate(session);
1290                 gnutls_assert();
1291                 ret = GNUTLS_E_RECORD_LIMIT_REACHED;
1292                 goto sanity_check_error;
1293         }
1294
1295 /* (originally for) TLS 1.0 CBC protection. 
1296  * Actually this code is called if we just received
1297  * an empty packet. An empty TLS packet is usually
1298  * sent to protect some vulnerabilities in the CBC mode.
1299  * In that case we go to the beginning and start reading
1300  * the next packet.
1301  */
1302         if (_mbuffer_get_udata_size(decrypted) == 0) {
1303                 _mbuffer_xfree(&decrypted);
1304                 empty_fragments++;
1305                 goto begin;
1306         }
1307
1308         if (record.v2) {
1309                 decrypted->htype = GNUTLS_HANDSHAKE_CLIENT_HELLO_V2;
1310         } else {
1311                 uint8_t *p = _mbuffer_get_udata_ptr(decrypted);
1312                 decrypted->htype = p[0];
1313         }
1314
1315         ret =
1316             record_add_to_buffers(session, &record, type, htype,
1317                                   packet_sequence, decrypted);
1318
1319         /* decrypted is now either deinitialized or buffered somewhere else */
1320
1321         if (ret < 0)
1322                 return gnutls_assert_val(ret);
1323
1324         return ret;
1325
1326       discard:
1327         session->internals.dtls.packets_dropped++;
1328
1329         /* discard the whole received fragment. */
1330         bufel =
1331             _mbuffer_head_pop_first(&session->internals.
1332                                     record_recv_buffer);
1333         _mbuffer_xfree(&bufel);
1334         return gnutls_assert_val(GNUTLS_E_AGAIN);
1335
1336       sanity_check_error:
1337         if (IS_DTLS(session)) {
1338                 session->internals.dtls.packets_dropped++;
1339                 ret = gnutls_assert_val(GNUTLS_E_AGAIN);
1340                 goto cleanup;
1341         }
1342
1343         session_unresumable(session);
1344         session_invalidate(session);
1345
1346       cleanup:
1347         _mbuffer_xfree(&decrypted);
1348         return ret;
1349
1350       recv_error:
1351         if (ret < 0
1352             && (gnutls_error_is_fatal(ret) == 0
1353                 || ret == GNUTLS_E_TIMEDOUT))
1354                 return ret;
1355
1356         if (type == GNUTLS_ALERT) {     /* we were expecting close notify */
1357                 session_invalidate(session);
1358                 gnutls_assert();
1359                 return 0;
1360         }
1361
1362         if (IS_DTLS(session) && (ret == GNUTLS_E_DECRYPTION_FAILED ||
1363                 ret == GNUTLS_E_UNSUPPORTED_VERSION_PACKET ||
1364                 ret == GNUTLS_E_UNEXPECTED_PACKET_LENGTH ||
1365                 ret == GNUTLS_E_UNEXPECTED_PACKET ||
1366                 ret == GNUTLS_E_ERROR_IN_FINISHED_PACKET ||
1367                 ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)) {
1368                 goto discard;
1369         }
1370
1371         session_invalidate(session);
1372         session_unresumable(session);
1373
1374         if (ret == 0)
1375                 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1376         else
1377                 return ret;
1378 }
1379
1380 /* This function behaves exactly like read(). The only difference is
1381  * that it accepts the gnutls_session_t and the content_type_t of data to
1382  * receive (if called by the user the Content is Userdata only)
1383  * It is intended to receive data, under the current session.
1384  *
1385  * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
1386  */
1387 ssize_t
1388 _gnutls_recv_int(gnutls_session_t session, content_type_t type,
1389                  gnutls_handshake_description_t htype,
1390                  gnutls_packet_t *packet,
1391                  uint8_t * data, size_t data_size, void *seq,
1392                  unsigned int ms)
1393 {
1394         int ret;
1395
1396         if (packet == NULL && (type != GNUTLS_ALERT && type != GNUTLS_HEARTBEAT)
1397             && (data_size == 0 || data == NULL))
1398                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1399
1400         if (session->internals.read_eof != 0) {
1401                 /* if we have already read an EOF
1402                  */
1403                 return 0;
1404         } else if (session_is_valid(session) != 0
1405                    || session->internals.may_not_read != 0) {
1406                 gnutls_assert();
1407                 return GNUTLS_E_INVALID_SESSION;
1408         }
1409
1410         switch (session->internals.recv_state) {
1411         case RECV_STATE_DTLS_RETRANSMIT:
1412                 ret = _dtls_retransmit(session);
1413                 if (ret < 0)
1414                         return gnutls_assert_val(ret);
1415
1416                 session->internals.recv_state = RECV_STATE_0;
1417         case RECV_STATE_0:
1418
1419                 _dtls_async_timer_check(session);
1420
1421                 if (packet == NULL) {
1422                         /* If we have enough data in the cache do not bother receiving
1423                          * a new packet. (in order to flush the cache)
1424                          */
1425                         ret = check_buffers(session, type, data, data_size, seq);
1426                         if (ret != 0)
1427                                 return ret;
1428
1429                         ret = _gnutls_recv_in_buffers(session, type, htype, ms);
1430                         if (ret < 0 && ret != GNUTLS_E_SESSION_EOF)
1431                                 return gnutls_assert_val(ret);
1432
1433                         return check_buffers(session, type, data, data_size, seq);
1434                 } else {
1435                         ret = check_packet_buffers(session, type, packet);
1436                         if (ret != 0)
1437                                 return ret;
1438
1439                         ret = _gnutls_recv_in_buffers(session, type, -1, ms);
1440                         if (ret < 0 && ret != GNUTLS_E_SESSION_EOF)
1441                                 return gnutls_assert_val(ret);
1442
1443                         return check_packet_buffers(session, type, packet);
1444                 }
1445         default:
1446                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1447         }
1448 }
1449
1450 /**
1451  * gnutls_packet_get:
1452  * @packet: is a #gnutls_packet_t structure.
1453  * @data: will contain the data present in the @packet structure (may be %NULL)
1454  * @sequence: the 8-bytes of the packet sequence number (may be %NULL)
1455  *
1456  * This function returns the data and sequence number associated with
1457  * the received packet.
1458  *
1459  * Since: 3.3.5
1460  **/
1461
1462 void gnutls_packet_get(gnutls_packet_t packet, gnutls_datum_t *data, unsigned char *sequence)
1463 {
1464         if (unlikely(packet == NULL)) {
1465                 gnutls_assert();
1466                 if (data) {
1467                         data->data = NULL;
1468                         data->size = 0;
1469                 }
1470         }
1471
1472         if (sequence) {
1473                 memcpy(sequence, packet->record_sequence.i, 8);
1474         }
1475
1476         if (data) {
1477                 data->size = packet->msg.size - packet->mark;
1478                 data->data = packet->msg.data + packet->mark;
1479         }
1480 }
1481
1482 /**
1483  * gnutls_packet_deinit:
1484  * @packet: is a pointer to a #gnutls_packet_st structure.
1485  *
1486  * This function will deinitialize all data associated with
1487  * the received packet.
1488  *
1489  * Since: 3.3.5
1490  **/
1491 void gnutls_packet_deinit(gnutls_packet_t packet)
1492 {
1493         gnutls_free(packet);
1494 }
1495
1496 /**
1497  * gnutls_record_discard_queued:
1498  * @session: is a #gnutls_session_t structure.
1499  *
1500  * This function discards all queued to be sent packets in a DTLS session.
1501  * These are the packets queued after an interrupted gnutls_record_send().
1502  *
1503  * Returns: The number of bytes discarded.
1504  *
1505  * Since: 3.4.0
1506  **/
1507 size_t
1508 gnutls_record_discard_queued(gnutls_session_t session)
1509 {
1510         size_t ret = session->internals.record_send_buffer.byte_length;
1511         _mbuffer_head_clear(&session->internals.record_send_buffer);
1512         return ret;
1513 }
1514
1515 /**
1516  * gnutls_record_is_async:
1517  * @session: is a #gnutls_session_t structure.
1518  *
1519  * This will indicate whether the DTLS session is in asynchronous mode,
1520  * i.e., handshake data may still be received and retransmitted. During
1521  * that time gnutls_record_send() and gnutls_record_recv() must be only be
1522  * used in the same process or thread (see gnutls_record_send() for more information).
1523  *
1524  * In a TLS session this function always returns zero.
1525  *
1526  * Returns: Non-zero if the session is in async mode, or zero otherwise.
1527  *
1528  * Since: 3.4.0
1529  **/
1530 unsigned
1531 gnutls_record_is_async(gnutls_session_t session)
1532 {
1533         if (IS_DTLS(session) && _dtls_is_async(session) && _dtls_async_timer_active(session))
1534                 return 1;
1535         return 0;
1536 }
1537
1538 /**
1539  * gnutls_record_recv_packet:
1540  * @session: is a #gnutls_session_t structure.
1541  * @packet: the structure that will hold the packet data
1542  *
1543  * This is a lower-level function than gnutls_record_recv() and allows
1544  * to directly receive the whole decrypted packet. That avoids a
1545  * memory copy, and is mostly applicable to applications seeking high
1546  * performance.
1547  *
1548  * The received packet is accessed using gnutls_packet_get() and 
1549  * must be deinitialized using gnutls_packet_deinit(). The returned
1550  * packet will be %NULL if the return value is zero (EOF).
1551  *
1552  * Returns: The number of bytes received and zero on EOF (for stream
1553  * connections).  A negative error code is returned in case of an error.  
1554  *
1555  * Since: 3.3.5
1556  **/
1557 ssize_t
1558 gnutls_record_recv_packet(gnutls_session_t session, 
1559                           gnutls_packet_t *packet)
1560 {
1561         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, packet,
1562                                 NULL, 0, NULL,
1563                                 session->internals.record_timeout_ms);
1564 }
1565
1566 /**
1567  * gnutls_record_send:
1568  * @session: is a #gnutls_session_t structure.
1569  * @data: contains the data to send
1570  * @data_size: is the length of the data
1571  *
1572  * This function has the similar semantics with send().  The only
1573  * difference is that it accepts a GnuTLS session, and uses different
1574  * error codes.
1575  * Note that if the send buffer is full, send() will block this
1576  * function.  See the send() documentation for more information.  
1577  *
1578  * You can replace the default push function which is send(), by using
1579  * gnutls_transport_set_push_function().
1580  *
1581  * If the EINTR is returned by the internal push function 
1582  * then %GNUTLS_E_INTERRUPTED will be returned. If
1583  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1584  * call this function again, with the exact same parameters; alternatively
1585  * you could provide a %NULL pointer for data, and 0 for
1586  * size. cf. gnutls_record_get_direction(). 
1587  *
1588  * Note that in DTLS this function will return the %GNUTLS_E_LARGE_PACKET
1589  * error code if the send data exceed the data MTU value - as returned
1590  * by gnutls_dtls_get_data_mtu(). The errno value EMSGSIZE
1591  * also maps to %GNUTLS_E_LARGE_PACKET. 
1592  * Note that since 3.2.13 this function can be called under cork in DTLS
1593  * mode, and will refuse to send data over the MTU size by returning
1594  * %GNUTLS_E_LARGE_PACKET.
1595  *
1596  * This function can be used in parallel with gnutls_record_recv() in a
1597  * multi-thread or multi-process scenario if TLS is in use, or in DTLS
1598  * when gnutls_record_is_async() returns zero (that will happen few seconds after
1599  * the handshake is terminated). In all cases, each process or thread must
1600  * be restricted to use one of the send or recv functions.
1601  *
1602  * Returns: The number of bytes sent, or a negative error code.  The
1603  *   number of bytes sent might be less than @data_size.  The maximum
1604  *   number of bytes this function can send in a single call depends
1605  *   on the negotiated maximum record size.
1606  **/
1607 ssize_t
1608 gnutls_record_send(gnutls_session_t session, const void *data,
1609                    size_t data_size)
1610 {
1611         if (session->internals.record_flush_mode == RECORD_FLUSH) {
1612                 return _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
1613                                         -1, EPOCH_WRITE_CURRENT, data,
1614                                         data_size, MBUFFER_FLUSH);
1615         } else {                /* GNUTLS_CORKED */
1616
1617                 int ret;
1618
1619                 if (IS_DTLS(session)) {
1620                         if (data_size + session->internals.record_presend_buffer.length >
1621                                 gnutls_dtls_get_data_mtu(session)) {
1622                                 return gnutls_assert_val(GNUTLS_E_LARGE_PACKET);
1623                         }
1624                 }
1625
1626                 ret =
1627                     _gnutls_buffer_append_data(&session->internals.
1628                                                record_presend_buffer, data,
1629                                                data_size);
1630                 if (ret < 0)
1631                         return gnutls_assert_val(ret);
1632
1633                 return data_size;
1634         }
1635 }
1636
1637 /**
1638  * gnutls_record_cork:
1639  * @session: is a #gnutls_session_t structure.
1640  *
1641  * If called, gnutls_record_send() will no longer send any records.
1642  * Any sent records will be cached until gnutls_record_uncork() is called.
1643  *
1644  * This function is safe to use with DTLS after GnuTLS 3.3.0.
1645  *
1646  * Since: 3.1.9
1647  **/
1648 void gnutls_record_cork(gnutls_session_t session)
1649 {
1650         session->internals.record_flush_mode = RECORD_CORKED;
1651 }
1652
1653 /**
1654  * gnutls_record_uncork:
1655  * @session: is a #gnutls_session_t structure.
1656  * @flags: Could be zero or %GNUTLS_RECORD_WAIT
1657  *
1658  * This resets the effect of gnutls_record_cork(), and flushes any pending
1659  * data. If the %GNUTLS_RECORD_WAIT flag is specified then this
1660  * function will block until the data is sent or a fatal error
1661  * occurs (i.e., the function will retry on %GNUTLS_E_AGAIN and
1662  * %GNUTLS_E_INTERRUPTED).
1663  *
1664  * If the flag %GNUTLS_RECORD_WAIT is not specified and the function
1665  * is interrupted then the %GNUTLS_E_AGAIN or %GNUTLS_E_INTERRUPTED
1666  * errors will be returned. To obtain the data left in the corked
1667  * buffer use gnutls_record_check_corked().
1668  *
1669  * Returns: On success the number of transmitted data is returned, or 
1670  * otherwise a negative error code. 
1671  *
1672  * Since: 3.1.9
1673  **/
1674 int gnutls_record_uncork(gnutls_session_t session, unsigned int flags)
1675 {
1676         int ret;
1677         ssize_t total = 0;
1678
1679         if (session->internals.record_flush_mode == RECORD_FLUSH)
1680                 return 0;       /* nothing to be done */
1681
1682         session->internals.record_flush_mode = RECORD_FLUSH;
1683
1684         while (session->internals.record_presend_buffer.length > 0) {
1685                 if (flags == GNUTLS_RECORD_WAIT) {
1686                         do {
1687                                 ret =
1688                                     gnutls_record_send(session,
1689                                                        session->internals.
1690                                                        record_presend_buffer.
1691                                                        data,
1692                                                        session->internals.
1693                                                        record_presend_buffer.
1694                                                        length);
1695                         }
1696                         while (ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
1697                 } else {
1698                         ret =
1699                             gnutls_record_send(session,
1700                                                session->internals.
1701                                                record_presend_buffer.data,
1702                                                session->internals.
1703                                                record_presend_buffer.
1704                                                length);
1705                 }
1706                 if (ret < 0)
1707                         goto fail;
1708
1709                 session->internals.record_presend_buffer.data += ret;
1710                 session->internals.record_presend_buffer.length -= ret;
1711                 total += ret;
1712         }
1713
1714         return total;
1715
1716       fail:
1717         session->internals.record_flush_mode = RECORD_CORKED;
1718         return ret;
1719 }
1720
1721 /**
1722  * gnutls_record_recv:
1723  * @session: is a #gnutls_session_t structure.
1724  * @data: the buffer that the data will be read into
1725  * @data_size: the number of requested bytes
1726  *
1727  * This function has the similar semantics with recv().  The only
1728  * difference is that it accepts a GnuTLS session, and uses different
1729  * error codes.
1730  * In the special case that a server requests a renegotiation, the
1731  * client may receive an error code of %GNUTLS_E_REHANDSHAKE.  This
1732  * message may be simply ignored, replied with an alert
1733  * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1734  * depending on the client's will.
1735  * If %EINTR is returned by the internal push function (the default
1736  * is recv()) then %GNUTLS_E_INTERRUPTED will be returned.  If
1737  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1738  * call this function again to get the data.  See also
1739  * gnutls_record_get_direction().
1740  * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1741  * initiated a handshake. In that case the server can only initiate a
1742  * handshake or terminate the connection.
1743  *
1744  * Returns: The number of bytes received and zero on EOF (for stream
1745  * connections).  A negative error code is returned in case of an error.  
1746  * The number of bytes received might be less than the requested @data_size.
1747  **/
1748 ssize_t
1749 gnutls_record_recv(gnutls_session_t session, void *data, size_t data_size)
1750 {
1751         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, NULL,
1752                                 data, data_size, NULL,
1753                                 session->internals.record_timeout_ms);
1754 }
1755
1756 /**
1757  * gnutls_record_recv_seq:
1758  * @session: is a #gnutls_session_t structure.
1759  * @data: the buffer that the data will be read into
1760  * @data_size: the number of requested bytes
1761  * @seq: is the packet's 64-bit sequence number. Should have space for 8 bytes.
1762  *
1763  * This function is the same as gnutls_record_recv(), except that
1764  * it returns in addition to data, the sequence number of the data.
1765  * This is useful in DTLS where record packets might be received
1766  * out-of-order. The returned 8-byte sequence number is an
1767  * integer in big-endian format and should be
1768  * treated as a unique message identification. 
1769  *
1770  * Returns: The number of bytes received and zero on EOF.  A negative
1771  *   error code is returned in case of an error.  The number of bytes
1772  *   received might be less than @data_size.
1773  *
1774  * Since: 3.0
1775  **/
1776 ssize_t
1777 gnutls_record_recv_seq(gnutls_session_t session, void *data,
1778                        size_t data_size, unsigned char *seq)
1779 {
1780         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, NULL,
1781                                 data, data_size, seq,
1782                                 session->internals.record_timeout_ms);
1783 }
1784
1785 /**
1786  * gnutls_record_set_timeout:
1787  * @session: is a #gnutls_session_t structure.
1788  * @ms: is a timeout value in milliseconds
1789  *
1790  * This function sets the receive timeout for the record layer
1791  * to the provided value. Use an @ms value of zero to disable
1792  * timeout (the default).
1793  *
1794  * Since: 3.1.7
1795  **/
1796 void gnutls_record_set_timeout(gnutls_session_t session, unsigned int ms)
1797 {
1798         session->internals.record_timeout_ms = ms;
1799 }