[gnutls-dev] [PATCH] bug in lib/gnutls_buffers.c

Nikos Mavroyanopoulos nmav@gnutls.org
Tue May 27 23:36:01 2003


--h31gzZEtNLTqOjlF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, May 27, 2003 at 09:19:33PM +0300, Sergey Poznyakoff wrote:

> Hello,
> The buffering mechanism in gnutls_buffers.c does not work when
> the user-defined pull function is used. Here's the short
> synopsis:
> The comment to _gnutls_io_clear_peeked_data() states that `this
> function is only used with berkeley style sockets.', however no
> provision is made to ensure this is so. This causes the function
> to be called even if the pull function is used. Now, what happens
> is that calling _gnutls_io_clear_peeked_data() after
> _gnutls_read(..., MSG_PEEK) blocks the program, since it actually
> attempts to read the same data twice.
> Attached is the patch that corrects the bug.

Thank you for the report and the patch. Does the attached patch
also solve the problem?

> Regards,
> Sergey

-- 
Nikos Mavroyanopoulos

--h31gzZEtNLTqOjlF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: gnutls_buffers.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_buffers.c,v
retrieving revision 2.104
diff -u -u -r2.104 gnutls_buffers.c
--- gnutls_buffers.c	24 Mar 2003 17:21:54 -0000	2.104
+++ gnutls_buffers.c	27 May 2003 21:33:30 -0000
@@ -331,7 +331,7 @@
 	size_t min;
 	int buf_pos;
 	char *buf;
-	int recvlowat = RCVLOWAT;
+	int recvlowat;
 	int recvdata, alloc_size;
 
 	*iptr = session->internals.record_recv_buffer.data;
@@ -341,13 +341,22 @@
 		return GNUTLS_E_INVALID_REQUEST;
 	}
 	
-	/* leave peeked data to the kernel space only if application data
-	 * is received and we don't have any peeked 
-	 * data in gnutls session.
+	/* If an external pull function is used, then do not leave
+	 * any data into the kernel buffer.
 	 */
-	if ( recv_type != GNUTLS_APPLICATION_DATA
-		&& session->internals.have_peeked_data==0)
+	if (session->internals._gnutls_pull_func != NULL) {
 		recvlowat = 0;
+	} else {
+		/* leave peeked data to the kernel space only if application data
+		 * is received and we don't have any peeked 
+		 * data in gnutls session.
+		 */
+		if ( recv_type != GNUTLS_APPLICATION_DATA
+			&& session->internals.have_peeked_data==0)
+			recvlowat = 0;
+		else recvlowat = RCVLOWAT;
+	}
+	
 
 	
 	/* calculate the actual size, ie. get the minimum of the

--h31gzZEtNLTqOjlF--