Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Date: Tue, 14 Aug 2001 12:53:50 -0400 From: Jason Tishler To: "Gerrit P. Haase" Cc: Cygwin Subject: Winsock recv/WSARecv(..., MSG_PEEK) is unreliable (was Re: Transient fetchmail ...) Message-ID: <20010814125350.F581@dothill.com> Mail-Followup-To: "Gerrit P. Haase" , Cygwin Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="v5WMQ1DpiN2iUBVP" Content-Disposition: inline In-Reply-To: <20010808230100.H223@dothill.com> User-Agent: Mutt/1.3.18i --v5WMQ1DpiN2iUBVP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Aug 08, 2001 at 11:01:00PM -0400, Jason Tishler wrote: > Thanks for trying to help me, it is much appreciated. Unfortunately, > your problem seems to be similar to (or the same as) Olaf's. Your > problem seems to be on the transmit side -- mine seems to be on the > receive side. I believe that I have finally found the root cause to my transient fetchmail corruption problems under Windows 2000. From the following MSDN articles, it appears the Winsock's recv/WSARecv(..., MSG_PEEK) is inherently unreliable and strongly discouraged: http://support.microsoft.com/support/kb/articles/Q192/5/99.ASP http://support.microsoft.com/support/kb/articles/Q140/2/63.asp The following fetchmail code is affected by the above: int SockRead(int sock, char *buf, int len) { char *bp = buf; ... do { ... if ((n = recv(sock, bp, len, MSG_PEEK)) <= 0) return (-1); if ((newline = memchr(bp, '\n', n)) != NULL) n = newline - bp + 1; // *** [1] *** if ((n = read(sock, bp, n)) == -1) // *** [2] *** return (-1); bp += n; ... } while (!newline && len); *bp = '\0'; ... } The number of bytes read in [2] is occasionally less than the number of bytes requested as determined by [1]. This causes fetchmail to put null characters in the wrong place and to read the same bytes more than once. This is the source of the "corruption" that I have been experiencing under 2000. For some reason, this problem has not occurred (yet) under NT 4.0 SP5/SP6a. Is there any way to fix this in Cygwin? Otherwise, other applications that use MSG_PEEK may fail in similar ways. The attached *ugly* patch to fetchmail works around this problem. If the MSG_PEEK problem cannot be fixed in Cygwin, then what is the best way to solve this issue in fetchmail? I see the following options: 1. Leverage off of existing BeOS specific code that does not use MSG_PEEK but only reads one byte at a time. 2. Rework the ugly patch with __CYGWIN__ #ifdefs. 3. Rework SockRead() to not use MSG_PEEK, but instead "drain data immediately upon arrival into application-allocated buffer space" as suggested by the MSDN. I guess that have I ordered the above in what I think is decreasing chance of acceptance into fetchmail CVS. Does anyone have any other, hopefully better, ideas? Thanks, Jason --v5WMQ1DpiN2iUBVP Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="socket.c.patch" --- socket.c.orig Tue Aug 14 10:36:19 2001 +++ socket.c Tue Aug 14 10:38:06 2001 @@ -493,7 +493,7 @@ int SockWrite(int sock, char *buf, int l int SockRead(int sock, char *buf, int len) { char *newline, *bp = buf; - int n; + int n, n2, n3; #ifdef SSL_ENABLE SSL *ssl; #endif @@ -578,8 +578,15 @@ int SockRead(int sock, char *buf, int le if ((newline = memchr(bp, '\n', n)) != NULL) n = newline - bp + 1; #ifndef __BEOS__ - if ((n = fm_read(sock, bp, n)) == -1) + if ((n2 = fm_read(sock, bp, n)) == -1) return(-1); + + if (n2 != n) + { + if ((n3 = fm_read(sock, bp + n2, n - n2)) == -1) + return(-1); + printf("n = %d, n2 = %d, n3 = %d\n", n, n2, n3); + } #endif /* __BEOS__ */ #endif bp += n; --v5WMQ1DpiN2iUBVP Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --v5WMQ1DpiN2iUBVP--