From: Nikos Mavrogiannopoulos Date: Sun, 19 Aug 2001 14:25:44 +0000 (+0000) Subject: better support for buffered read and several cleanups X-Git-Tag: gnutls_0_2_2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=64076d11d87fe35153cd8d5a9aacee91e4fea339;p=thirdparty%2Fgnutls.git better support for buffered read and several cleanups --- diff --git a/NEWS b/NEWS index 47c02ebe8e..281ebf5c20 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +Version 0.2.1 (07/08/2001) +- SRP fixes + Version 0.2.0 (07/08/2001) - Partial support for X509v3 Certificate extensions. - Added Internal memory handlers diff --git a/configure.in b/configure.in index f2c75f7969..f81784eccf 100644 --- a/configure.in +++ b/configure.in @@ -11,7 +11,7 @@ AC_DEFINE_UNQUOTED(T_OS, "$target_os") GNUTLS_MAJOR_VERSION=0 GNUTLS_MINOR_VERSION=2 -GNUTLS_MICRO_VERSION=0 +GNUTLS_MICRO_VERSION=2 GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION AC_DEFINE_UNQUOTED(GNUTLS_VERSION, "$GNUTLS_VERSION") diff --git a/lib/auth_srp.c b/lib/auth_srp.c index 11cd3cef95..8a4977f1fa 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -86,7 +86,7 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data) state->gnutls_key->auth_info_size = sizeof(SRP_SERVER_AUTH_INFO_INT); username = ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username; - strcpy( username, state->gnutls_internals.srp_username); + strcpy( username, state->security_parameters.extensions.srp_username); pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, username, &err); diff --git a/lib/ext_srp.c b/lib/ext_srp.c index b2d716e3ec..d174c74f7c 100644 --- a/lib/ext_srp.c +++ b/lib/ext_srp.c @@ -41,12 +41,12 @@ int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_si gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - if ( sizeof( state->gnutls_internals.srp_username) <= len) { + if ( sizeof( state->security_parameters.extensions.srp_username) <= len) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - memcpy( state->gnutls_internals.srp_username, &data[1], len); - state->gnutls_internals.srp_username[len]=0; /* null terminated */ + memcpy( state->security_parameters.extensions.srp_username, &data[1], len); + state->security_parameters.extensions.srp_username[len]=0; /* null terminated */ } } else { /* client side reading server hello extensions */ if (state->gnutls_internals.resumed==RESUME_FALSE) diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 20701b6458..731c1ef83c 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -18,10 +18,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include "gnutls_int.h" -#include "gnutls_errors.h" +#include +#include +#include + #ifdef HAVE_ERRNO_H - # include +# include +#endif + +#ifndef EAGAIN +# define EAGAIN EWOULDBLOCK #endif extern ssize_t (*_gnutls_recv_func)( SOCKET, void*, size_t, int); @@ -132,8 +138,9 @@ int gnutls_getDataFromBuffer(ContentType type, GNUTLS_STATE state, char *data, i return length; } + /* This function is like read. But it does not return -1 on error. - * It does return -errno instead. + * It does return gnutls_errno instead. */ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) { @@ -149,7 +156,10 @@ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) while (left > 0) { i = _gnutls_recv_func(fd, &ptr[i], left, flag); if (i < 0) { - return (0-errno); + if (errno == EAGAIN) + return GNUTLS_E_AGAIN; + else + return GNUTLS_E_UNKNOWN_ERROR; } else { if (i == 0) break; /* EOF */ @@ -178,10 +188,105 @@ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) } +#define RCVLOWAT state->gnutls_internals.lowat + +int _gnutls_clear_peeked_data( SOCKET cd, GNUTLS_STATE state) { +char peekdata1; +char *peekdata2; + + if (state->gnutls_internals.have_peeked_data==0) + return 0; + + if (RCVLOWAT != 1) { + if (RCVLOWAT == 0) + return 0; + + peekdata2 = gnutls_malloc( RCVLOWAT); + + /* this was already read by using MSG_PEEK - so it shouldn't fail */ + _gnutls_Read( cd, peekdata2, RCVLOWAT, 0); + + gnutls_free(peekdata2); + } else { + _gnutls_Read( cd, &peekdata1, RCVLOWAT, 0); + } + state->gnutls_internals.have_peeked_data=0; + + return 0; +} + + +void _gnutls_read_clear_buffer( GNUTLS_STATE state) { + state->gnutls_internals.recv_buffer_data_size = 0; +} + +/* This function is like read. But it does not return -1 on error. + * It does return gnutls_errno instead. + */ +ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, void *iptr, size_t sizeOfPtr, int flag, ContentType recv_type) +{ + ssize_t ret=0, ret2=0; + int min; + char *ptr = iptr; + int recvlowat = RCVLOWAT; + + /* leave peeked data to the kernel space only if application data + * is received. + */ + if (recv_type != GNUTLS_APPLICATION_DATA) + recvlowat = 0; + + /* copy peeked data to given buffer + */ + min = GMIN( state->gnutls_internals.recv_buffer_data_size, sizeOfPtr); + if ( min > 0) { + memcpy( iptr, state->gnutls_internals.recv_buffer_data, min); + if ( min == sizeOfPtr) + return min; + } + + /* since we are going to read data, we must clear any peeked. + */ + _gnutls_clear_peeked_data( fd, state); + + /* read fresh data - but leave RCVLOWAT bytes in the kernel buffer. + */ + if ( sizeOfPtr - min - recvlowat > 0) + ret = _gnutls_Read( fd, &ptr[min], sizeOfPtr - min - recvlowat, flag); + if (ret >= 0 && recvlowat > 0) { + ret2 = _gnutls_Read( fd, &ptr[min+ret], recvlowat, MSG_PEEK|flag); + state->gnutls_internals.have_peeked_data = 1; + } + + if (ret < 0 || ret2 < 0) + return GMIN(ret, ret2); + + + ret += ret2; + + if (ret < recvlowat) { + gnutls_assert(); + return GNUTLS_E_AGAIN; + } + + + /* copy fresh data to our buffer. + */ + if ( ret+state->gnutls_internals.recv_buffer_data_size > sizeof( state->gnutls_internals.recv_buffer_data)) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + memcpy( &state->gnutls_internals.recv_buffer_data[state->gnutls_internals.recv_buffer_data_size], &ptr[min], ret); + state->gnutls_internals.recv_buffer_data_size += ret; + + return ret+min; +} + + /* This function is like write. But it does not return -1 on error. * It does return -errno instead. */ -ssize_t _gnutls_Write(int fd, const void *iptr, size_t n, int flags) +ssize_t _gnutls_write(int fd, const void *iptr, size_t n, int flags) { size_t left; #ifdef WRITE_DEBUG diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index 7ecbfe88f9..afb2a30224 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -21,8 +21,11 @@ int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, int length); int gnutls_getDataBufferSize(ContentType type, GNUTLS_STATE state); int gnutls_getDataFromBuffer(ContentType type, GNUTLS_STATE state, char *data, int length); -ssize_t _gnutls_Read(int fd, void *iptr, size_t n, int); -ssize_t _gnutls_Write(int fd, const void *iptr, size_t n, int ); +ssize_t _gnutls_read_buffered(int fd, GNUTLS_STATE, void *iptr, size_t n, int, ContentType); +void _gnutls_read_clear_buffer( GNUTLS_STATE); +int _gnutls_clear_peeked_data( SOCKET cd, GNUTLS_STATE state); + +ssize_t _gnutls_write(int fd, const void *iptr, size_t n, int ); /* used in SSL3 */ int gnutls_getHashDataFromBuffer( GNUTLS_STATE state, char *data, int length); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 3e8dafa705..4fce48b09b 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -82,7 +82,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_KEY_USAGE_VIOLATION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0), - GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_HELLO_REQUEST, 0), + GNUTLS_ERROR_ENTRY( GNUTLS_E_REHANDSHAKE, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_APPLICATION_DATA, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1), {0} diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 5eaeaf2ad3..e66bfaf0ba 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -37,7 +37,7 @@ #define GNUTLS_E_PARSING_ERROR -34 #define GNUTLS_E_MPI_PRINT_FAILED -35 #define GNUTLS_E_AUTH_FAILED -36 -#define GNUTLS_E_GOT_HELLO_REQUEST -37 +#define GNUTLS_E_REHANDSHAKE -37 #define GNUTLS_E_GOT_APPLICATION_DATA -38 #define GNUTLS_E_RECORD_LIMIT_REACHED -39 #define GNUTLS_E_ENCRYPTION_FAILED -40 diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 4937f8fc45..ec7a0977f3 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -204,6 +204,7 @@ typedef struct { */ typedef struct { opaque dnsname[MAX_DNSNAME_SIZE]; + opaque srp_username[MAX_SRP_USERNAME]; } TLSExtensions; /* AUTH_INFO structures MUST NOT contain malloced @@ -322,6 +323,16 @@ typedef struct { /* sockets internals */ int lowat; + /* this buffer holds a record packet -mostly used for + * non blocking IO. + */ + opaque recv_buffer_data[MAX_RECV_SIZE]; + int recv_buffer_data_size; + + /* 0 if no peeked data was kept, 1 otherwise. + */ + int have_peeked_data; + /* gdbm */ char* db_name; int expire_time; @@ -352,7 +363,6 @@ typedef struct { int peer_pk_algorithm; /* holds the username got in the srp tls extension */ - opaque srp_username[MAX_SRP_USERNAME]; } GNUTLS_INTERNALS; struct GNUTLS_STATE_INT { diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index b0bb5a646d..22bdf2bd7d 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -35,13 +35,6 @@ #include "gnutls_record.h" #include "gnutls_datum.h" -#ifdef HAVE_ERRNO_H -# include -#endif - -#ifndef EAGAIN -# define EAGAIN EWOULDBLOCK -#endif GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state) { GNUTLS_Version ver; @@ -61,7 +54,9 @@ void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) { * Used to set the lowat value in order for select to check * if there are pending data to socket buffer. Used only * if you have changed the default low water value (default is 1). - * Normally you will not need that function. + * Normally you will not need that function. + * If you plan to use non standard recv() function you should set + * this to zero. **/ int gnutls_set_lowat(GNUTLS_STATE state, int num) { state->gnutls_internals.lowat = num; @@ -449,7 +444,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha WRITEuint16( cipher_size-RECORD_HEADER_SIZE, &headers[3]); memcpy( cipher, headers, RECORD_HEADER_SIZE); - if (_gnutls_Write(cd, cipher, cipher_size, flags) != cipher_size) { + if (_gnutls_write(cd, cipher, cipher_size, flags) != cipher_size) { state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); @@ -476,12 +471,10 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha cipher_size = _gnutls_encrypt( state, &data[i*Size], Size, &cipher, type); if (cipher_size<=0) return cipher_size; - WRITEuint16( cipher_size, &headers[3]); - + WRITEuint16( cipher_size-RECORD_HEADER_SIZE, &headers[3]); memcpy( cipher, headers, RECORD_HEADER_SIZE); - cipher_size += RECORD_HEADER_SIZE; - if (_gnutls_Write(cd, cipher, cipher_size, flags) != cipher_size) { + if (_gnutls_write(cd, cipher, cipher_size, flags) != cipher_size) { state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); @@ -519,17 +512,6 @@ ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state) } -#define RCVLOWAT state->gnutls_internals.lowat /* this is the default for TCP - just don't change that! */ - -static int _gnutls_clear_peeked_data( SOCKET cd, GNUTLS_STATE state) { -char peekdata; - - /* this was already read by using MSG_PEEK - so it shouldn't fail */ - _gnutls_Read( cd, &peekdata, RCVLOWAT, 0); - - return 0; -} - #define CHECK_RECORD_VERSION /* This function behave exactly like read(). The only difference is @@ -537,7 +519,7 @@ char peekdata; * send (if called by the user the Content is Userdata only) * It is intended to receive data, under the current state. * flags is the sockets flags to use. Currently only MSG_DONTWAIT is - * supported. + * supported, and should be used together with MSG_WAITALL. */ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, HandshakeType htype, char *data, size_t sizeofdata, int flags) { @@ -548,20 +530,23 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha ContentType recv_type; uint16 length; uint8 *ciphertext; + uint8 *recv_data; int ret = 0; int header_size = RECORD_HEADER_SIZE; + + + /* If we have enough data in the cache do not bother receiving * a new packet. (in order to flush the cache) */ if ( (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && gnutls_getDataBufferSize(type, state) > 0) { ret = gnutls_getDataFromBuffer(type, state, data, sizeofdata); - if (type==GNUTLS_APPLICATION_DATA) { - /* if the buffer just got empty */ - if (gnutls_getDataBufferSize(type, state)==0) { - _gnutls_clear_peeked_data( cd, state); - } + /* if the buffer just got empty */ + if (gnutls_getDataBufferSize(type, state)==0) { + _gnutls_clear_peeked_data( cd, state); } + return ret; } @@ -572,8 +557,8 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha /* in order for GNUTLS_E_AGAIN to be returned the socket * must be set to non blocking mode */ - if ( (ret = _gnutls_Read(cd, headers, RECORD_HEADER_SIZE, MSG_PEEK|flags)) != RECORD_HEADER_SIZE) { - if (ret==(0-EAGAIN)) return GNUTLS_E_AGAIN; + if ( (ret = _gnutls_read_buffered(cd, state, headers, RECORD_HEADER_SIZE, flags, -1)) != RECORD_HEADER_SIZE) { + if (ret==GNUTLS_E_AGAIN) return ret; state->gnutls_internals.valid_connection = VALID_FALSE; if (type==GNUTLS_ALERT) return 0; /* we were expecting close notify */ @@ -648,15 +633,14 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - ciphertext = gnutls_malloc(length+header_size); + recv_data = gnutls_malloc(length+header_size); + + /* check if we have that data into buffer. + */ + if ( (ret = _gnutls_read_buffered(cd, state, recv_data, header_size+length, flags, recv_type)) != length+header_size) { + gnutls_free(recv_data); + if (ret==GNUTLS_E_AGAIN) return ret; -/* check if we have that data into buffer. This seems to be - * expensive - but this is the only way to handle Non Blocking IO. - */ - if ( (ret = _gnutls_Read(cd, ciphertext, header_size+length, MSG_PEEK|flags)) != length+header_size) { - gnutls_free(ciphertext); - - if (ret==(0-EAGAIN)) return GNUTLS_E_AGAIN; state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); @@ -666,42 +650,8 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha /* ok now we are sure that we can read all the data - so * move on ! */ - if (_gnutls_Read(cd, headers, header_size, 0)!=header_size) { /* read and clear the headers - again! */ - gnutls_free(ciphertext); - state->gnutls_internals.valid_connection = VALID_FALSE; - state->gnutls_internals.resumable = RESUME_FALSE; - gnutls_assert(); - return GNUTLS_E_UNKNOWN_ERROR; - } - -/* Read the whole packet - again? - * Here we keep RCVLOWAT bytes in the TCP buffers, only for - * APPLICATION_DATA data. - */ - if ( type==GNUTLS_APPLICATION_DATA && type==recv_type) { - /* get the data - but do not free the buffer in the kernel */ - ret = _gnutls_Read(cd, ciphertext, length-RCVLOWAT, 0); - if (ret>=0) - ret += _gnutls_Read(cd, &ciphertext[length-RCVLOWAT], RCVLOWAT, MSG_PEEK); - - } else { /* our - internal data */ - ret = _gnutls_Read(cd, ciphertext, length, 0); - } - - /* Oooops... very rare case since we know that the system HAD - * received that data. - */ - if (ret != length) { -#ifdef RECORD_DEBUG - _gnutls_log( "Record: Received packet with length: %d\nExpected %d\n", ret, length); -#endif - gnutls_free(ciphertext); - state->gnutls_internals.valid_connection = VALID_FALSE; - state->gnutls_internals.resumable = RESUME_FALSE; - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - + _gnutls_read_clear_buffer( state); + ciphertext = &recv_data[header_size]; /* decrypt the data we got */ @@ -721,7 +671,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); - gnutls_free(ciphertext); + gnutls_free(recv_data); return tmplen; } @@ -732,7 +682,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha _gnutls_log( "Record: ChangeCipherSpec Packet was received\n"); #endif - gnutls_free(ciphertext); + gnutls_free(recv_data); if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */ gnutls_assert(); @@ -758,7 +708,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha return GNUTLS_E_RECORD_LIMIT_REACHED; } - gnutls_free(ciphertext); + gnutls_free(recv_data); if ( (recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) { gnutls_insertDataBuffer(type, state, (void *) tmpdata, tmplen); @@ -782,9 +732,8 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha gnutls_bye(cd, state, 1); gnutls_free(tmpdata); - + return 0; /* EOF */ -/* return GNUTLS_E_CLOSURE_ALERT_RECEIVED; */ } else { /* if the alert is FATAL or WARNING @@ -810,7 +759,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha gnutls_assert(); gnutls_free(tmpdata); - + return GNUTLS_E_UNEXPECTED_PACKET; case GNUTLS_APPLICATION_DATA: #if 0 @@ -830,7 +779,12 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha break; case GNUTLS_HANDSHAKE: - /* This is only legal if HELLO_REQUEST is received */ + /* This is only legal if HELLO_REQUEST is received - and we are a client */ + if (htype!=GNUTLS_HELLO_REQUEST && state->security_parameters.entity==GNUTLS_SERVER) { + gnutls_assert(); + gnutls_free( tmpdata); + return GNUTLS_E_UNEXPECTED_PACKET; + } break; default: @@ -846,13 +800,12 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha /* Get Application data from buffer */ if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) { ret = gnutls_getDataFromBuffer(type, state, data, sizeofdata); - if (type==GNUTLS_APPLICATION_DATA) { - /* if the buffer just got empty */ - if (gnutls_getDataBufferSize(type, state)==0) { - _gnutls_clear_peeked_data( cd, state); - } + /* if the buffer just got empty */ + if (gnutls_getDataBufferSize(type, state)==0) { + _gnutls_clear_peeked_data( cd, state); } + gnutls_free(tmpdata); } else { if (recv_type == GNUTLS_HANDSHAKE) { @@ -861,7 +814,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha if (ret < 0) { gnutls_assert(); } else /* inform the caller */ - ret = GNUTLS_E_GOT_HELLO_REQUEST; + ret = GNUTLS_E_REHANDSHAKE; } else { gnutls_assert(); ret = GNUTLS_E_UNEXPECTED_PACKET; diff --git a/src/cli.c b/src/cli.c index d3377609de..5c219d8362 100644 --- a/src/cli.c +++ b/src/cli.c @@ -288,8 +288,8 @@ int main(int argc, char** argv) if (FD_ISSET(sd, &rset)) { bzero(buffer, MAX_BUF+1); - ret = gnutls_read(sd, state, buffer, MAX_BUF); + /* remove new line */ if (gnutls_is_fatal_error(ret) == 1 || ret==0) { @@ -304,8 +304,8 @@ int main(int argc, char** argv) } else { if (ret==GNUTLS_E_WARNING_ALERT_RECEIVED || ret==GNUTLS_E_FATAL_ALERT_RECEIVED) printf("* Received alert [%d]\n", gnutls_get_last_alert(state)); - if (ret==GNUTLS_E_GOT_HELLO_REQUEST) - printf("* Received HelloRequest message (server asked to rehandshake)\n"); + if (ret==GNUTLS_E_REHANDSHAKE) + printf("* Rehandshake was performed\n"); if (ret > 0) { printf("- Received[%d]: ", ret);