[09/12] soccr/tcp: Restore socket's info after binding it (v2)

Submitted by Pavel Emelianov on Aug. 5, 2016, 3:02 p.m.

Details

Message ID 57A4AA6F.7080405@virtuozzo.com
State Accepted
Series "Introduce library for socket C/R"
Commit 99bd6427147449e62daf2b819a8b2317bd42f2fb
Headers show

Commit Message

Pavel Emelianov Aug. 5, 2016, 3:02 p.m.
With window parameters, we have stuff to restore before
queues and after queues.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/sk-tcp.c | 82 ++---------------------------------------------------------
 soccr/soccr.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 soccr/soccr.h |  2 ++
 3 files changed, 83 insertions(+), 80 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
index 4161339..2007e52 100644
--- a/criu/sk-tcp.c
+++ b/criu/sk-tcp.c
@@ -68,10 +68,6 @@  enum {
 #define TCP_REPAIR_WINDOW       29
 #endif
 
-#ifndef TCPOPT_SACK_PERM
-#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
-#endif
-
 static LIST_HEAD(cpt_tcp_repair_sockets);
 static LIST_HEAD(rst_tcp_repair_sockets);
 
@@ -389,80 +385,6 @@  static int restore_tcp_queues(int sk, TcpStreamEntry *tse, struct cr_img *img)
 	return 0;
 }
 
-static int restore_tcp_opts(int sk, TcpStreamEntry *tse)
-{
-	struct tcp_repair_opt opts[4];
-	int onr = 0;
-
-	pr_debug("\tRestoring TCP options\n");
-
-	if (tse->opt_mask & TCPI_OPT_SACK) {
-		pr_debug("\t\tWill turn SAK on\n");
-		opts[onr].opt_code = TCPOPT_SACK_PERM;
-		opts[onr].opt_val = 0;
-		onr++;
-	}
-
-	if (tse->opt_mask & TCPI_OPT_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 + (tse->rcv_wscale << 16);
-		onr++;
-	}
-
-	if (tse->opt_mask & TCPI_OPT_TIMESTAMPS) {
-		pr_debug("\t\tWill turn timestamps on\n");
-		opts[onr].opt_code = TCPOPT_TIMESTAMP;
-		opts[onr].opt_val = 0;
-		onr++;
-	}
-
-	pr_debug("Will set mss clamp to %u\n", tse->mss_clamp);
-	opts[onr].opt_code = TCPOPT_MAXSEG;
-	opts[onr].opt_val = tse->mss_clamp;
-	onr++;
-
-	if (setsockopt(sk, SOL_TCP, TCP_REPAIR_OPTIONS,
-				opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
-		pr_perror("Can't repair options");
-		return -1;
-	}
-
-	if (tse->has_timestamp) {
-		if (setsockopt(sk, SOL_TCP, TCP_TIMESTAMP,
-				&tse->timestamp, sizeof(tse->timestamp)) < 0) {
-			pr_perror("Can't set timestamp");
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int restore_tcp_window(int sk, TcpStreamEntry *tse)
-{
-	struct tcp_repair_window opt = {
-		.snd_wl1 = tse->snd_wl1,
-		.snd_wnd = tse->snd_wnd,
-		.max_window = tse->max_window,
-		.rcv_wnd = tse->rcv_wnd,
-		.rcv_wup = tse->rcv_wup,
-	};
-
-	if (!kdat.has_tcp_window || !tse->has_snd_wnd) {
-		pr_warn_once("Window parameters are not restored\n");
-		return 0;
-	}
-
-	if (setsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &opt, sizeof(opt))) {
-		pr_perror("Unable to set window parameters");
-		return -1;
-	}
-
-	return 0;
-}
-
 static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_sk_info *ii)
 {
 	int aux;
@@ -529,7 +451,7 @@  static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
 	if (inet_connect(sk, ii))
 		goto err_c;
 
-	if (restore_tcp_opts(sk, tse))
+	if (libsoccr_set_sk_data_noq(socr, &data, sizeof(data)))
 		goto err_c;
 
 	if (restore_prepare_socket(sk))
@@ -538,7 +460,7 @@  static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
 	if (restore_tcp_queues(sk, tse, img))
 		goto err_c;
 
-	if (restore_tcp_window(sk, tse))
+	if (libsoccr_set_sk_data(socr, &data, sizeof(data)))
 		goto err_c;
 
 	if (tse->has_nodelay && tse->nodelay) {
diff --git a/soccr/soccr.c b/soccr/soccr.c
index 6eeb368..61a39ad 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -349,3 +349,82 @@  int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk,
 	return 0;
 }
 
+#ifndef TCPOPT_SACK_PERM
+#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
+#endif
+
+int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
+		struct libsoccr_sk_data *data, unsigned data_size)
+{
+	struct tcp_repair_opt opts[4];
+	int onr = 0;
+
+	if (!data || data_size < SOCR_DATA_MIN_SIZE)
+		return -1;
+
+	logd("\tRestoring TCP options\n");
+
+	if (data->opt_mask & TCPI_OPT_SACK) {
+		logd("\t\tWill turn SAK on\n");
+		opts[onr].opt_code = TCPOPT_SACK_PERM;
+		opts[onr].opt_val = 0;
+		onr++;
+	}
+
+	if (data->opt_mask & TCPI_OPT_WSCALE) {
+		logd("\t\tWill set snd_wscale to %u\n", data->snd_wscale);
+		logd("\t\tWill set rcv_wscale to %u\n", data->rcv_wscale);
+		opts[onr].opt_code = TCPOPT_WINDOW;
+		opts[onr].opt_val = data->snd_wscale + (data->rcv_wscale << 16);
+		onr++;
+	}
+
+	if (data->opt_mask & TCPI_OPT_TIMESTAMPS) {
+		logd("\t\tWill turn timestamps on\n");
+		opts[onr].opt_code = TCPOPT_TIMESTAMP;
+		opts[onr].opt_val = 0;
+		onr++;
+	}
+
+	logd("Will set mss clamp to %u\n", data->mss_clamp);
+	opts[onr].opt_code = TCPOPT_MAXSEG;
+	opts[onr].opt_val = data->mss_clamp;
+	onr++;
+
+	if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS,
+				opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
+		loge("Can't repair options");
+		return -2;
+	}
+
+	if (data->opt_mask & TCPI_OPT_TIMESTAMPS) {
+		if (setsockopt(sk->fd, SOL_TCP, TCP_TIMESTAMP,
+				&data->timestamp, sizeof(data->timestamp)) < 0) {
+			loge("Can't set timestamp");
+			return -3;
+		}
+	}
+
+	return 0;
+}
+
+int libsoccr_set_sk_data(struct libsoccr_sk *sk,
+		struct libsoccr_sk_data *data, unsigned data_size)
+{
+	if (data->flags & SOCCR_FLAGS_WINDOW) {
+		struct tcp_repair_window wopt = {
+			.snd_wl1 = data->snd_wl1,
+			.snd_wnd = data->snd_wnd,
+			.max_window = data->max_window,
+			.rcv_wnd = data->rcv_wnd,
+			.rcv_wup = data->rcv_wup,
+		};
+	
+		if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_WINDOW, &wopt, sizeof(wopt))) {
+			loge("Unable to set window parameters");
+			return -1;
+		}
+	}
+
+	return 0;
+}
diff --git a/soccr/soccr.h b/soccr/soccr.h
index 3458a1b..86c43f2 100644
--- a/soccr/soccr.h
+++ b/soccr/soccr.h
@@ -54,4 +54,6 @@  int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
 char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
 
 int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
+int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
+int libsoccr_set_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
 #endif