summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-25 13:44:23 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-25 13:44:23 +0000
commita11331f92db2e6fc8ebf44f50ef02150924fd8ae (patch)
tree6ceb18bbb6661528b639a928093ab5fae9207eda
parent3d1c141575c1c58789aff5b38ec5dd6b479d6564 (diff)
downloadgnutls-a11331f92db2e6fc8ebf44f50ef02150924fd8ae.tar.gz
some memory optimization while receiving packets
-rw-r--r--doc/tex/cover.tex2
-rw-r--r--lib/gnutls_buffers.c41
-rw-r--r--lib/gnutls_buffers.h2
-rw-r--r--lib/gnutls_record.c16
-rw-r--r--lib/gnutls_ui.c8
-rw-r--r--src/serv.c9
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);
+ }
}
}