Rsync error on client end: unexpected tag 3 [sender] rsync error: error in rsync protocol data stream (code 12) at io.c(843) [sender]

Wayne Davison wayned at samba.org
Wed May 3 05:30:39 GMT 2006


On Wed, May 03, 2006 at 11:58:07AM +1000, Anthony Sadler wrote:
> unexpected tag 3 [sender]

My analysis shows that some deferred messages (which are those that
arrive in the generator when the generator is already trying to flush a
partial message down the socket) are not being handled by rwrite() like
they should be.  Furthermore, the MSG_LOG message doesn't actually need
to be deferred, since they cannot result in any data being written to
the socket.  This bug can only affect an rsync daemon that is receiving
files, as all other scenarios behave correctly with the existing code.

The attached patch should fix the problem.  I've also checked the fix
into CVS (and it will appear in the next nightly tar file that gets
generated).

Thanks for the detailed report, it was very helpful.

..wayne..
-------------- next part --------------
--- io.c	25 Apr 2006 23:51:15 -0000	1.193
+++ io.c	3 May 2006 05:13:31 -0000
@@ -294,6 +294,7 @@ static void read_msg_fd(void)
 			exit_cleanup(RERR_STREAMIO);
 		}
 		close_multiplexing_out();
+		defer_forwarding_messages = 0;
 		/* FALL THROUGH */
 	case MSG_INFO:
 	case MSG_ERROR:
@@ -303,7 +304,8 @@ static void read_msg_fd(void)
 			if (n >= sizeof buf)
 				n = sizeof buf - 1;
 			read_loop(fd, buf, n);
-			if (am_generator && am_server && defer_forwarding_messages)
+			if (am_generator && am_server
+			 && defer_forwarding_messages && tag != MSG_LOG)
 				msg_list_add(&msg2sndr, tag, buf, n);
 			else
 				rwrite((enum logcode)tag, buf, n);
@@ -1134,11 +1136,20 @@ static void msg2sndr_flush(void)
 
 	while (msg2sndr.head && io_multiplexing_out) {
 		struct msg_list_item *m = msg2sndr.head;
+		int tag = (IVAL(m->buf, 0) >> 24) - MPLEX_BASE;
 		if (!(msg2sndr.head = m->next))
 			msg2sndr.tail = NULL;
-		stats.total_written += m->len;
 		defer_forwarding_messages = 1;
-		writefd_unbuffered(sock_f_out, m->buf, m->len);
+		switch (tag) {
+		case MSG_INFO:
+		case MSG_ERROR:
+			rwrite((enum logcode)tag, m->buf + 4, m->len - 4);
+			break;
+		default:
+			stats.total_written += m->len;
+			writefd_unbuffered(sock_f_out, m->buf, m->len);
+			break;
+		}
 		defer_forwarding_messages = 0;
 		free(m);
 	}


More information about the rsync mailing list