diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-08-25 13:44:23 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-08-25 13:44:23 +0000 |
commit | a11331f92db2e6fc8ebf44f50ef02150924fd8ae (patch) | |
tree | 6ceb18bbb6661528b639a928093ab5fae9207eda | |
parent | 3d1c141575c1c58789aff5b38ec5dd6b479d6564 (diff) | |
download | gnutls-a11331f92db2e6fc8ebf44f50ef02150924fd8ae.tar.gz |
some memory optimization while receiving packets
-rw-r--r-- | doc/tex/cover.tex | 2 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 41 | ||||
-rw-r--r-- | lib/gnutls_buffers.h | 2 | ||||
-rw-r--r-- | lib/gnutls_record.c | 16 | ||||
-rw-r--r-- | lib/gnutls_ui.c | 8 | ||||
-rw-r--r-- | src/serv.c | 9 |
6 files changed, 40 insertions, 38 deletions
diff --git a/doc/tex/cover.tex b/doc/tex/cover.tex index 3b3bb4beef..deec4de4e6 100644 --- a/doc/tex/cover.tex +++ b/doc/tex/cover.tex @@ -13,7 +13,7 @@ \vspace*{\stretch{2}} - {\Large By Nikos Mavroyanopoulos and Fabio Fiorina\\[.1mm]} + {\Large By Nikos Mavroyanopoulos\\[.1mm]} \HRule \newpage diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index cc074a44f0..a044f316fc 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -220,43 +220,53 @@ 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. +/* This function is like recv(with MSG_PEEK). But it does not return -1 on error. * It does return gnutls_errno instead. + * This function reads data from the socket and keeps them in a buffer, of up to + * MAX_RECV_SIZE. */ -ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, void *iptr, size_t sizeOfPtr, int flag, ContentType recv_type) +ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t sizeOfPtr, int flag, ContentType recv_type) { ssize_t ret=0, ret2=0; int min; - char *ptr = iptr; + char *buf; int recvlowat = RCVLOWAT; + *iptr = NULL; + + if ( sizeOfPtr > MAX_RECV_SIZE) { + gnutls_assert(); /* internal error */ + return GNUTLS_E_UNKNOWN_ERROR; + } + /* leave peeked data to the kernel space only if application data * is received and we don't have any peeked data in there. */ if (recv_type != GNUTLS_APPLICATION_DATA && state->gnutls_internals.have_peeked_data==0) recvlowat = 0; + buf = state->gnutls_internals.recv_buffer_data; + + *iptr = buf; + /* 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); + sizeOfPtr -= min; /* 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 ( sizeOfPtr - recvlowat > 0) + ret = _gnutls_Read( fd, &buf[min], sizeOfPtr - recvlowat, flag); + if (ret >= 0 && recvlowat > 0) { + ret2 = _gnutls_Read( fd, &buf[min+ret], recvlowat, MSG_PEEK|flag); + state->gnutls_internals.have_peeked_data = 1; + } if (ret < 0 || ret2 < 0) return GMIN(ret, ret2); @@ -271,11 +281,6 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, void *iptr, size_t si /* 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; diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index afb2a30224..d9e39eef74 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -21,7 +21,7 @@ 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_buffered(int fd, GNUTLS_STATE, void *iptr, size_t n, int, ContentType); +ssize_t _gnutls_read_buffered(int fd, GNUTLS_STATE, opaque **iptr, size_t n, int, ContentType); void _gnutls_read_clear_buffer( GNUTLS_STATE); int _gnutls_clear_peeked_data( SOCKET cd, GNUTLS_STATE state); diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 39ce809de1..36d3d1f6f3 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -530,7 +530,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha uint8 *tmpdata; int tmplen; GNUTLS_Version version; - uint8 headers[RECORD_HEADER_SIZE]; + uint8 *headers; ContentType recv_type; uint16 length; uint8 *ciphertext; @@ -568,7 +568,7 @@ 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_buffered(cd, state, headers, RECORD_HEADER_SIZE, flags, -1)) != RECORD_HEADER_SIZE) { + if ( (ret = _gnutls_read_buffered(cd, state, &headers, header_size, flags, -1)) != header_size) { if (ret==GNUTLS_E_AGAIN) return ret; state->gnutls_internals.valid_connection = VALID_FALSE; @@ -647,12 +647,9 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - 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_read_buffered(cd, state, &recv_data, header_size+length, flags, recv_type)) != length+header_size) { if (ret==GNUTLS_E_AGAIN) return ret; state->gnutls_internals.valid_connection = VALID_FALSE; @@ -671,7 +668,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha */ tmplen = _gnutls_decrypt( state, ciphertext, length, &tmpdata, recv_type); if (tmplen < 0) { - switch (tmplen) { + switch (tmplen) { /* send appropriate alert */ case GNUTLS_E_MAC_FAILED: gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_BAD_RECORD_MAC); break; @@ -685,7 +682,6 @@ 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(recv_data); return tmplen; } @@ -696,8 +692,6 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha _gnutls_log( "Record: ChangeCipherSpec Packet was received\n"); #endif - gnutls_free(recv_data); - if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */ gnutls_assert(); gnutls_free(tmpdata); @@ -722,8 +716,6 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha return GNUTLS_E_RECORD_LIMIT_REACHED; } - gnutls_free(recv_data); - if ( (recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) { gnutls_insertDataBuffer(type, state, (void *) tmpdata, tmplen); } else { diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index 1ae9f5760f..0c94619a2d 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -74,7 +74,8 @@ int gnutls_anon_client_get_dh_bits( ANON_CLIENT_AUTH_INFO info) { * @info: is an X509PKI_CLIENT_AUTH_INFO structure * * This function will return the name of the peer. The name is gnutls_DN structure and - * is a obtained by the peer's certificate. + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns NULL. * **/ const gnutls_DN* gnutls_x509pki_client_get_peer_dn( X509PKI_CLIENT_AUTH_INFO info) { @@ -87,7 +88,8 @@ const gnutls_DN* gnutls_x509pki_client_get_peer_dn( X509PKI_CLIENT_AUTH_INFO in * @info: is an X509PKI_CLIENT_AUTH_INFO structure * * This function will return the name of the peer's certificate issuer. The name is gnutls_DN structure and - * is a obtained by the peer's certificate. + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns NULL. * **/ const gnutls_DN* gnutls_x509pki_client_get_issuer_dn( X509PKI_CLIENT_AUTH_INFO info) { @@ -114,7 +116,7 @@ CertificateStatus gnutls_x509pki_client_get_peer_certificate_status( X509PKI_CL * @info: is an X509PKI_CLIENT_AUTH_INFO structure * * This function will return the peer's certificate version (1, 2, 3). This is obtained by the X509 Certificate - * Version field. + * Version field. If the certificate is invalid then version will be zero. * **/ int gnutls_x509pki_client_get_peer_certificate_version( X509PKI_CLIENT_AUTH_INFO info) { diff --git a/src/serv.c b/src/serv.c index f009c9f7fc..246dc13818 100644 --- a/src/serv.c +++ b/src/serv.c @@ -179,11 +179,14 @@ void print_info(GNUTLS_STATE state) printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info)); dn = gnutls_x509pki_client_get_peer_dn( x509_info); - PRINT_DN( dn); + if (dn!=NULL) + PRINT_DN( dn); dn = gnutls_x509pki_client_get_issuer_dn( x509_info); - printf(" - Certificate Issuer's info:\n"); - PRINT_DN( dn); + if (dn!=NULL) { + printf(" - Certificate Issuer's info:\n"); + PRINT_DN( dn); + } } } |