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)