[CRIU] [PATCH 10/21] soccr: add support for syn-sent sockets
Andrei Vagin
avagin at openvz.org
Thu Dec 1 00:32:28 PST 2016
From: Andrei Vagin <avagin at virtuozzo.com>
For that we restore all sockets properties and then
disable the repair mode before calling connect() and
the kernel will sent a syn packet and move the socket
into the sys-sent state.
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
soccr/soccr.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/soccr/soccr.c b/soccr/soccr.c
index dce3151..6be8f7d 100644
--- a/soccr/soccr.c
+++ b/soccr/soccr.c
@@ -6,6 +6,7 @@
#include <linux/sockios.h>
#include <libnet.h>
#include <assert.h>
+#include <errno.h>
#include "soccr.h"
@@ -90,13 +91,15 @@ static int tcp_repair_on(int fd)
return ret;
}
-static void tcp_repair_off(int fd)
+static int tcp_repair_off(int fd)
{
int aux = 0, ret;
ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux));
if (ret < 0)
logerr("Failed to turn off repair mode on socket");
+
+ return ret;
}
struct libsoccr_sk {
@@ -150,6 +153,7 @@ static int refresh_sk(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, str
case TCP_CLOSE_WAIT:
case TCP_CLOSING:
case TCP_CLOSE:
+ case TCP_SYN_SENT:
break;
default:
loge("Unknown state %d\n", ti->tcpi_state);
@@ -400,6 +404,7 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
struct tcp_repair_opt opts[4];
int addr_size;
int onr = 0;
+ __u32 seq;
if (!data || data_size < SOCR_DATA_MIN_SIZE)
return -1;
@@ -417,8 +422,12 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
if (set_queue_seq(sk, TCP_RECV_QUEUE,
data->inq_seq - data->inq_len))
return -2;
- if (set_queue_seq(sk, TCP_SEND_QUEUE,
- data->outq_seq - data->outq_len))
+
+ seq = data->outq_seq - data->outq_len;
+ if (data->state == TCP_SYN_SENT)
+ seq--;
+
+ if (set_queue_seq(sk, TCP_SEND_QUEUE, seq))
return -3;
if (data->dst_addr.sa.sa_family == AF_INET)
@@ -426,11 +435,18 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
else
addr_size = sizeof(data->dst_addr.v6);
- if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1) {
+ if (data->state == TCP_SYN_SENT && tcp_repair_off(sk->fd))
+ return -1;
+
+ if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1 &&
+ errno != EINPROGRESS) {
loge("Can't connect inet socket back\n");
return -1;
}
+ if (data->state == TCP_SYN_SENT && tcp_repair_on(sk->fd))
+ return -1;
+
logd("\tRestoring TCP options\n");
if (data->opt_mask & TCPI_OPT_SACK) {
@@ -460,7 +476,8 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
opts[onr].opt_val = data->mss_clamp;
onr++;
- if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS,
+ if (data->state != TCP_SYN_SENT &&
+ setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS,
opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
logerr("Can't repair options");
return -2;
--
2.7.4
More information about the CRIU
mailing list