delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/08/14/13:51:47

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
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 <jason AT tishler DOT net>
To: "Gerrit P. Haase" <freeweb AT nyckelpiga DOT de>
Cc: Cygwin <cygwin AT sources DOT redhat DOT com>
Subject: Winsock recv/WSARecv(..., MSG_PEEK) is unreliable (was Re: Transient fetchmail ...)
Message-ID: <20010814125350.F581@dothill.com>
Mail-Followup-To: "Gerrit P. Haase" <freeweb AT nyckelpiga DOT de>,
Cygwin <cygwin AT sources DOT redhat DOT com>
Mime-Version: 1.0
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--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019