rsync on cygwin: Connection reset by peer

OMeara, Randy randy.omeara at
Tue Oct 23 07:56:52 EST 2001

This is a message I posted (one of several) awhile back that addresses at
least one rsync/winsock problem.

Randy O'Meara

I have received a few queries regarding my progress in solving the rsync
sender's abortive connection close() on Winsock-based platforms.  In my
research, I stumbled across articles that implied that Microsoft is not the
only OS vendor that provides platforms that may exhibit this problem.  I am
posting this response to the list in hopes that even those that sent private
and public responses to my initial postings (slamming M$ and my decision to
use this platform) may possibly reap some benefit.

The symptom, exhibited at the receiver, may be observed as "read error:
Connection Reset" (or, very close to this) when retrieving a simple module
listing from an (unpatched) rsync daemon running on a Windows 2000 or
Windows NT platform using a command such as "rsync -av daemonHost::".  In
addition, the receiver may display only a portion of the expected module
listing.  Note that the problem is not exclusive to this simple module
listing mode.

The problem, as determined experimentally, lies in the manner in which the
rsync sender closes the connection (socket) that is utilized to communicate
with the receiver.  The rsync protocol does not include a final phase where
both participants agree to gracefully close the connection.  When the sender
completes transmission, it exits without explicitly shutting down the socket
fd.  I assume that, in most *N*X-based systems, allowing the system to clean
up open file descriptors on process exit does not cause the TCP RST flag to
be set and transmitted to the remote participant.  But, in at least
Winsock-based systems, the TCP RST flag is transmitted to the remote.  If
the remote (regardless of platform) has not completed receiving and
processing all data packets from the sender prior to the reception of the
RST packet, the unprocessed data is discarded.  An error message is
displayed and the receiver exits with a non-zero exit status.

The solution that works OK for *me* is to perform a graceful shutdown() of
socket FDs and to close() all open FDs prior to exit.  I have no doubt that
a more elegant solution than the one I have implemented does indeed exist.
For this reason, I am not providing a patch-format solution.  I am providing
the code that I used along with an indication of where to place the calls to
this function.

Randy O'Meara

**** place in cleanup.c just above _exit_cleanup() ****
void close_all()
/* rmo: 5/31/01
   Close all open sockets and files, allowing a (somewhat) graceful
   shutdown() of socket connections.  This eliminates the abortive
   TCP RST sent by a Winsock-based system when the close() occurs.
    int max_fd;
    int fd;
    int ret;
    struct stat st;

    max_fd = sysconf(_SC_OPEN_MAX) - 1;
    for (fd = max_fd; fd >= 0; fd--) {
      ret = fstat(fd,&st);
      if (fstat(fd,&st) == 0){	      	      /* Open fd */
	    if (is_a_socket(fd)) {
	      ret = shutdown(fd,2);	      /* Somewhat graceful */
            ret = close(fd);

**** call close_all() ****
cleanup.c:_exit_cleanup() just before exit(code)
socket.c:start_accept_loop() just before _exit(ret)

More information about the rsync mailing list