From: Nikos Mavrogiannopoulos Date: Mon, 21 Feb 2011 23:01:57 +0000 (+0100) Subject: Added gnutls_record_recv_seq() that can return the sequence number X-Git-Tag: gnutls_2_99_0~200 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9a24a046b1f5ec92d6fffc27c8da7cb8652f4142;p=thirdparty%2Fgnutls.git Added gnutls_record_recv_seq() that can return the sequence number of the record packet, in addition to data. --- diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 9a44af76d4..33c6c6661e 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -977,7 +977,7 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session, while (left > 0) { dsize = ptr_size - left; - i = _gnutls_recv_int (session, type, htype, &ptr[dsize], left); + i = _gnutls_recv_int (session, type, htype, &ptr[dsize], left, NULL); if (i < 0) { diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 2d0aec7878..e8c427ff4b 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -3112,7 +3112,7 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init) { case STATE0: case STATE30: - ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1); + ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1, NULL); STATE = STATE30; if (ret <= 0) { diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 84c1b4b32b..3f6ea81e9a 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -245,7 +245,7 @@ gnutls_bye (gnutls_session_t session, gnutls_close_request_t how) do { _gnutls_io_clear_peeked_data (session); - ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0); + ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0, NULL); } while (ret == GNUTLS_E_GOT_APPLICATION_DATA); @@ -354,7 +354,7 @@ ssize_t _gnutls_send_int (gnutls_session_t session, content_type_t type, gnutls_handshake_description_t htype, unsigned int epoch_rel, const void *_data, - size_t sizeofdata, unsigned int mflags) + size_t data_size, unsigned int mflags) { mbuffer_st *bufel; size_t cipher_size; @@ -387,7 +387,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, * ok, and means to resume. */ if (session->internals.record_send_buffer.byte_length == 0 && - (sizeofdata == 0 && _data == NULL)) + (data_size == 0 && _data == NULL)) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; @@ -414,12 +414,12 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, _gnutls_record_log ("REC[%p]: Preparing Packet %s(%d) with length: %d\n", session, - _gnutls_packet2str (type), type, (int) sizeofdata); + _gnutls_packet2str (type), type, (int) data_size); - if (sizeofdata > MAX_RECORD_SEND_SIZE(session)) + if (data_size > MAX_RECORD_SEND_SIZE(session)) data2send_size = MAX_RECORD_SEND_SIZE(session); else - data2send_size = sizeofdata; + data2send_size = data_size; /* Only encrypt if we don't have data to send * from the previous run. - probably interrupted. @@ -536,7 +536,7 @@ check_recv_type (content_type_t recv_type) */ static int check_buffers (gnutls_session_t session, content_type_t type, - opaque * data, int sizeofdata) + opaque * data, int data_size) { if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE || @@ -544,7 +544,7 @@ check_buffers (gnutls_session_t session, content_type_t type, && _gnutls_record_buffer_get_size (type, session) > 0) { int ret, ret2; - ret = _gnutls_record_buffer_get (type, session, data, sizeofdata); + ret = _gnutls_record_buffer_get (type, session, data, data_size); if (ret < 0) { gnutls_assert (); @@ -962,7 +962,7 @@ int ret; ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type, gnutls_handshake_description_t htype, - opaque * data, size_t data_size) + opaque * data, size_t data_size, void* seq) { uint64 *packet_sequence; uint8_t *ciphertext; @@ -1032,6 +1032,8 @@ begin: 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. */ @@ -1231,7 +1233,7 @@ recv_error: * gnutls_record_send: * @session: is a #gnutls_session_t structure. * @data: contains the data to send - * @sizeofdata: is the length of the data + * @data_size: is the length of the data * * This function has the similar semantics with send(). The only * difference is that it accepts a GnuTLS session, and uses different @@ -1251,16 +1253,16 @@ recv_error: * size. cf. gnutls_record_get_direction(). * * Returns: the number of bytes sent, or a negative error code. The - * number of bytes sent might be less than @sizeofdata. The maximum + * number of bytes sent might be less than @data_size. The maximum * number of bytes this function can send in a single call depends * on the negotiated maximum record size. **/ ssize_t gnutls_record_send (gnutls_session_t session, const void *data, - size_t sizeofdata) + size_t data_size) { return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1, - EPOCH_WRITE_CURRENT, data, sizeofdata, + EPOCH_WRITE_CURRENT, data, data_size, MBUFFER_FLUSH); } @@ -1268,7 +1270,7 @@ gnutls_record_send (gnutls_session_t session, const void *data, * gnutls_record_recv: * @session: is a #gnutls_session_t structure. * @data: the buffer that the data will be read into - * @sizeofdata: the number of requested bytes + * @data_size: the number of requested bytes * * This function has the similar semantics with recv(). The only * difference is that it accepts a GnuTLS session, and uses different @@ -1292,11 +1294,34 @@ gnutls_record_send (gnutls_session_t session, const void *data, * * Returns: the number of bytes received and zero on EOF. A negative * error code is returned in case of an error. The number of bytes - * received might be less than @sizeofdata. + * received might be less than @data_size. + **/ +ssize_t +gnutls_record_recv (gnutls_session_t session, void *data, size_t data_size) +{ + return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data, + data_size, NULL); +} + +/** + * gnutls_record_recv_seq: + * @session: is a #gnutls_session_t structure. + * @data: the buffer that the data will be read into + * @data_size: the number of requested bytes + * @seq: is the packet's 64-bit sequence number. + * + * This function is the same as gnutls_record_recv(), except that + * it returns in addition to data, the sequence number of the data. + * This is useful in DTLS. + * + * Returns: the number of bytes received and zero on EOF. A negative + * error code is returned in case of an error. The number of bytes + * received might be less than @data_size. **/ ssize_t -gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata) +gnutls_record_recv_seq (gnutls_session_t session, void *data, size_t data_size, + unsigned char seq[8]) { return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data, - sizeofdata); + data_size, seq); } diff --git a/lib/gnutls_record.h b/lib/gnutls_record.h index b24b390c50..f413471704 100644 --- a/lib/gnutls_record.h +++ b/lib/gnutls_record.h @@ -35,6 +35,6 @@ ssize_t _gnutls_send_int (gnutls_session_t session, content_type_t type, size_t sizeofdata, unsigned int mflags); ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type, gnutls_handshake_description_t, opaque * data, - size_t sizeofdata); + size_t sizeofdata, void* seq); #endif diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index ebe09bd63f..d3e9d877af 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -787,6 +787,8 @@ extern "C" size_t sizeofdata); #define gnutls_read gnutls_record_recv #define gnutls_write gnutls_record_send + ssize_t gnutls_record_recv_seq (gnutls_session_t session, void *data, size_t data_size, + unsigned char seq[8]); void gnutls_session_enable_compatibility_mode (gnutls_session_t session); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 90ba4b5495..978a2a5c81 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -703,6 +703,7 @@ GNUTLS_3_0_0 { gnutls_transport_set_pull_timeout_function; gnutls_dtls_get_mtu; gnutls_dtls_set_mtu; + gnutls_record_recv_seq; } GNUTLS_2_12; GNUTLS_PRIVATE { diff --git a/src/udp-serv.c b/src/udp-serv.c index 284348325b..a5ba6e4d88 100644 --- a/src/udp-serv.c +++ b/src/udp-serv.c @@ -29,6 +29,7 @@ int udp_server(const char* name, int port) char buffer[MAX_BUFFER]; priv_data_st priv; gnutls_session_t session; + unsigned char sequence[8]; ret = listen_socket (name, port, SOCK_DGRAM); if (ret < 0) @@ -77,7 +78,10 @@ int udp_server(const char* name, int port) for(;;) { - ret = gnutls_record_recv(session, buffer, MAX_BUFFER); + do { + ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence); + } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + if (ret < 0) { fprintf(stderr, "Error in recv(): %s\n", gnutls_strerror(ret)); @@ -89,7 +93,8 @@ int udp_server(const char* name, int port) break; } buffer[ret] = 0; - printf("received[%d]: %s\n", ret, buffer); + printf("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", sequence[0], sequence[1], sequence[2], + sequence[3], sequence[4], sequence[5], sequence[6], sequence[7], buffer); /* reply back */ ret = gnutls_record_send(session, buffer, ret);