From fd2995cc5b6eb0583c0480bae8d0a5f13c577be0 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 1 Dec 2016 11:32:26 +0300 Subject: [PATCH] soccr: move connect from criu to soccr We will need to disable the repair mode before connect() to restore syn-sent sockets. And even now connect() looks like a part of internal logic of libsoccr. travis-ci: success for series starting with [01/21] build: install libnet-dev v2: remove libsoccr_set_sk_data_unbound() from soccr.h Signed-off-by: Andrei Vagin Signed-off-by: Pavel Emelyanov --- criu/sk-inet.c | 11 +++++------ criu/sk-tcp.c | 9 --------- soccr/soccr.c | 30 ++++++++++++++++-------------- soccr/soccr.h | 13 +++---------- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/criu/sk-inet.c b/criu/sk-inet.c index 1336405a2..24166ad8d 100644 --- a/criu/sk-inet.c +++ b/criu/sk-inet.c @@ -594,6 +594,11 @@ static int open_inet_sk(struct file_desc *d) if (restore_opt(sk, SOL_SOCKET, SO_REUSEADDR, &yes)) goto err; + if (ie->src_port) { + if (inet_bind(sk, ii)) + goto err; + } + if (tcp_connection(ie)) { if (!opts.tcp_established_ok) { pr_err("Connected TCP socket in image\n"); @@ -614,12 +619,6 @@ static int open_inet_sk(struct file_desc *d) * Listen sockets are easiest ones -- simply * bind() and listen(), and that's all. */ - - if (ie->src_port) { - if (inet_bind(sk, ii)) - goto err; - } - if (ie->state == TCP_LISTEN) { if (ie->proto != IPPROTO_TCP) { pr_err("Wrong socket in listen state %d\n", ie->proto); diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c index 3e8984816..b238dbac6 100644 --- a/criu/sk-tcp.c +++ b/criu/sk-tcp.c @@ -349,15 +349,6 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_ (void)data; - if (libsoccr_set_sk_data_unbound(socr, &data, sizeof(data))) - goto err_c; - - if (inet_bind(sk, ii)) - goto err_c; - - if (inet_connect(sk, ii)) - goto err_c; - if (libsoccr_set_sk_data_noq(socr, &data, sizeof(data))) goto err_c; diff --git a/soccr/soccr.c b/soccr/soccr.c index 019eeea99..4b6c227f0 100644 --- a/soccr/soccr.c +++ b/soccr/soccr.c @@ -323,9 +323,17 @@ static int set_queue_seq(struct libsoccr_sk *sk, int queue, __u32 seq) return 0; } -int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, +#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 addr_size; + int onr = 0; + if (!data || data_size < SOCR_DATA_MIN_SIZE) return -1; @@ -339,21 +347,15 @@ int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, data->outq_seq - data->outq_len)) return -3; - return 0; -} + if (data->dst_addr.sa.sa_family == AF_INET) + addr_size = sizeof(data->dst_addr.v4); + else + addr_size = sizeof(data->dst_addr.v6); -#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) + if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1) { + loge("Can't connect inet socket back\n"); return -1; + } logd("\tRestoring TCP options\n"); diff --git a/soccr/soccr.h b/soccr/soccr.h index c5c3e1be7..789f5146c 100644 --- a/soccr/soccr.h +++ b/soccr/soccr.h @@ -178,12 +178,12 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal); * sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); * * h = libsoccr_pause(sk) - * libsoccr_set_sk_data_unbound(h, &data, sizeof(data)) * bind(sk, &name, ...) - * connect(sk, &name, ...) - * libsoccr_set_sk_data(h, &data, sizeof(data)) + * + * libsoccr_set_sk_data_noq(h, &data, sizeof(data)) * libsoccr_set_queue_bytes(h, &data, sizeof(data), TCP_RECV_QUEUE, inq) * libsoccr_set_queue_bytes(h, &data, sizeof(data), TCP_SEND_QUEUE, outq) + * libsoccr_set_sk_data(h, &data, sizeof(data)) * * libsoccr_resume(h) * @@ -191,13 +191,6 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal); * enabled back. */ -/* - * Performs restore action while the socket is not bind()-ed and - * not connect()-ed. The data should be the one from _get_sk_data - * call. The data_size is the amount of bytes sitting in there. - */ -int libsoccr_set_sk_data_unbound(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size); - /* * Performs additional restore actions on bind()-ed and connect()-ed * socket, but without queues restored.