28
28
#include "gnutls_int.h"
29
29
#include "gnutls_errors.h"
30
30
#include "gnutls_num.h"
31
#include <gnutls_extensions.h>
31
32
#include <ext_max_record.h>
34
static int _gnutls_max_record_recv_params (gnutls_session_t session,
37
static int _gnutls_max_record_send_params (gnutls_session_t session,
38
opaque * data, size_t);
40
static int _gnutls_max_record_unpack (gnutls_buffer_st * ps,
41
extension_priv_data_t * _priv);
42
static int _gnutls_max_record_pack (extension_priv_data_t _priv,
43
gnutls_buffer_st * ps);
45
/* Maps record size to numbers according to the
48
static int _gnutls_mre_num2record (int num);
49
static int _gnutls_mre_record2num (uint16_t record_size);
52
extension_entry_st ext_mod_max_record_size = {
53
.name = "MAX RECORD SIZE",
54
.type = GNUTLS_EXTENSION_MAX_RECORD_SIZE,
55
.parse_type = GNUTLS_EXT_TLS,
57
.recv_func = _gnutls_max_record_recv_params,
58
.send_func = _gnutls_max_record_send_params,
59
.pack_func = _gnutls_max_record_pack,
60
.unpack_func = _gnutls_max_record_unpack,
34
65
* In case of a server: if a MAX_RECORD_SIZE extension type is received then it stores
35
66
* into the session the new value. The server may use gnutls_get_max_record_size(),
44
75
_gnutls_max_record_recv_params (gnutls_session_t session,
45
const opaque * data, size_t _data_size)
76
const opaque * data, size_t _data_size)
48
79
ssize_t data_size = _data_size;
80
extension_priv_data_t epriv;
50
83
if (session->security_parameters.entity == GNUTLS_SERVER)
54
DECR_LEN (data_size, 1);
56
new_size = _gnutls_mre_num2record (data[0]);
64
session->security_parameters.max_record_send_size = new_size;
65
session->security_parameters.max_record_recv_size = new_size;
87
DECR_LEN (data_size, 1);
89
new_size = _gnutls_mre_num2record (data[0]);
97
session->security_parameters.max_record_send_size = new_size;
98
session->security_parameters.max_record_recv_size = new_size;
69
{ /* CLIENT SIDE - we must check if the sent record size is the right one
102
{ /* CLIENT SIDE - we must check if the sent record size is the right one
71
104
if (data_size > 0)
77
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
80
new_size = _gnutls_mre_num2record (data[0]);
83
|| new_size != session->internals.proposed_record_size)
86
return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
90
session->security_parameters.max_record_recv_size =
91
session->internals.proposed_record_size;
106
ret = _gnutls_ext_get_session_data (session,
107
GNUTLS_EXTENSION_MAX_RECORD_SIZE,
112
return GNUTLS_E_INTERNAL_ERROR;
118
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
121
new_size = _gnutls_mre_num2record (data[0]);
123
if (new_size < 0 || new_size != epriv.num)
126
return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
130
session->security_parameters.max_record_recv_size = epriv.num;
102
141
/* returns data_size or a negative number on failure
105
144
_gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
109
150
/* this function sends the client extension data (dnsname) */
110
151
if (session->security_parameters.entity == GNUTLS_CLIENT)
113
if (session->internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE)
119
return GNUTLS_E_SHORT_MEMORY_BUFFER;
123
(uint8_t) _gnutls_mre_record2num (session->
124
internals.proposed_record_size);
153
extension_priv_data_t epriv;
155
ret = _gnutls_ext_get_session_data (session,
156
GNUTLS_EXTENSION_MAX_RECORD_SIZE,
158
if (ret < 0) /* it is ok not to have it */
163
if (epriv.num != DEFAULT_MAX_RECORD_SIZE)
169
return GNUTLS_E_SHORT_MEMORY_BUFFER;
172
data[0] = (uint8_t) _gnutls_mre_record2num (epriv.num);
132
180
if (session->security_parameters.max_record_recv_size !=
133
DEFAULT_MAX_RECORD_SIZE)
139
return GNUTLS_E_SHORT_MEMORY_BUFFER;
181
DEFAULT_MAX_RECORD_SIZE)
187
return GNUTLS_E_SHORT_MEMORY_BUFFER;
144
_gnutls_mre_record2num
145
(session->security_parameters.max_record_recv_size);
192
_gnutls_mre_record2num
193
(session->security_parameters.max_record_recv_size);
205
_gnutls_max_record_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
209
BUFFER_APPEND_NUM (ps, epriv.num);
216
_gnutls_max_record_unpack (gnutls_buffer_st * ps,
217
extension_priv_data_t * _priv)
219
extension_priv_data_t epriv;
222
BUFFER_POP_NUM (ps, epriv.num);
155
232
/* Maps numbers to record sizes according to the
156
233
* extensions draft.
159
236
_gnutls_mre_num2record (int num)
276
* gnutls_record_get_max_size:
277
* @session: is a #gnutls_session_t structure.
279
* Get the record size. The maximum record size is negotiated by the
280
* client after the first handshake message.
282
* Returns: The maximum record packet size in this connection.
285
gnutls_record_get_max_size (gnutls_session_t session)
287
/* Recv will hold the negotiated max record size
290
return session->security_parameters.max_record_recv_size;
295
* gnutls_record_set_max_size:
296
* @session: is a #gnutls_session_t structure.
297
* @size: is the new size
299
* This function sets the maximum record packet size in this
300
* connection. This property can only be set to clients. The server
301
* may choose not to accept the requested size.
303
* Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
304
* 4096(=2^12). The requested record size does get in effect
305
* immediately only while sending data. The receive part will take
306
* effect after a successful handshake.
308
* This function uses a TLS extension called 'max record size'. Not
309
* all TLS implementations use or even understand this extension.
311
* Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
312
* otherwise an error code is returned.
315
gnutls_record_set_max_size (gnutls_session_t session, size_t size)
318
extension_priv_data_t epriv;
320
if (session->security_parameters.entity == GNUTLS_SERVER)
321
return GNUTLS_E_INVALID_REQUEST;
323
new_size = _gnutls_mre_record2num (size);
331
session->security_parameters.max_record_send_size = size;
334
_gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_MAX_RECORD_SIZE,