[CRIU] [PATCH cr] tcp: save and restore rcv_wscale (v2)

Andrey Vagin avagin at openvz.org
Wed Sep 19 06:26:16 EDT 2012


rcv_wscale is a symetric parameter with snd_wscale.

Both this parameters are set on a connection handshake.

Without this value a remote window size can't be interpreted correctly,
because a value from a packet should be shifted on rcv_wscale.

This patch doesn't break a back compatibility, a rcv window
will be restored with the same bug (rcv_wscale = 0).

v2: Update to a new kernel interface:
	[PATCH] tcp: restore rcv_wscale in a repair mode (v2)

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 protobuf/tcp-stream.proto |    1 +
 sk-tcp.c                  |   13 +++++++++----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/protobuf/tcp-stream.proto b/protobuf/tcp-stream.proto
index 3c21d3c..f3355dc 100644
--- a/protobuf/tcp-stream.proto
+++ b/protobuf/tcp-stream.proto
@@ -7,4 +7,5 @@ message tcp_stream_entry {
 	required uint32		opt_mask	= 5; /* TCPI_OPT_ bits */
 	required uint32		snd_wscale	= 6;
 	required uint32		mss_clamp	= 7;
+	optional uint32		rcv_wscale	= 8;
 }
diff --git a/sk-tcp.c b/sk-tcp.c
index 0d1f57f..da156cb 100644
--- a/sk-tcp.c
+++ b/sk-tcp.c
@@ -204,8 +204,11 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
 		goto err_sopt;
 
 	tse->opt_mask = ti.tcpi_options;
-	if (ti.tcpi_options & TCPI_OPT_WSCALE)
+	if (ti.tcpi_options & TCPI_OPT_WSCALE) {
 		tse->snd_wscale = ti.tcpi_snd_wscale;
+		tse->rcv_wscale = ti.tcpi_rcv_wscale;
+		tse->has_rcv_wscale = true;
+	}
 
 	pr_info("\toptions: mss_clamp %x wscale %x tstamp %d sack %d\n",
 			(int)tse->mss_clamp,
@@ -398,9 +401,10 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
 	}
 
 	if (tse->opt_mask & TCPI_OPT_WSCALE) {
-		pr_debug("\t\tWill set wscale to %u\n", tse->snd_wscale);
+		pr_debug("\t\tWill set snd_wscale to %u\n", tse->snd_wscale);
+		pr_debug("\t\tWill set rcv_wscale to %u\n", tse->rcv_wscale);
 		opts[onr].opt_code = TCPOPT_WINDOW;
-		opts[onr].opt_val = tse->snd_wscale;
+		opts[onr].opt_val = tse->snd_wscale + (tse->rcv_wscale << 16);
 		onr++;
 	}
 
@@ -550,7 +554,8 @@ void show_tcp_stream(int fd, struct cr_options *opt)
 		pr_msg("OPTS: %#x\n", (int)tse->opt_mask);
 		pr_msg("\tmss_clamp %u\n", (int)tse->mss_clamp);
 		if (tse->opt_mask & TCPI_OPT_WSCALE)
-			pr_msg("\twscale %u\n", (int)tse->snd_wscale);
+			pr_msg("\tsnd wscale %u\n", (int)tse->snd_wscale);
+			pr_msg("\trcv wscale %u\n", (int)tse->rcv_wscale);
 		if (tse->opt_mask & TCPI_OPT_TIMESTAMPS)
 			pr_msg("\ttimestamps\n");
 		if (tse->opt_mask & TCPI_OPT_SACK)
-- 
1.7.1



More information about the CRIU mailing list