[CRIU] [PATCH 3/3] soccr: Move src/dst address from _data
Andrey Vagin
avagin at virtuozzo.com
Tue Dec 13 16:36:40 PST 2016
On Tue, Dec 13, 2016 at 05:32:16PM +0300, Pavel Emelyanov wrote:
>
> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
> ---
> criu/sk-tcp.c | 8 ++++++--
> soccr/soccr.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------------
> soccr/soccr.h | 18 +++++++++++++++---
> 3 files changed, 63 insertions(+), 21 deletions(-)
>
> diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
> index c8d4069..2512624 100644
> --- a/criu/sk-tcp.c
> +++ b/criu/sk-tcp.c
> @@ -285,6 +285,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
> struct cr_img *img;
> TcpStreamEntry *tse;
> struct libsoccr_sk_data data = {};
> + union libsoccr_addr sa_src, sa_dst;
>
> pr_info("Restoring TCP connection id %x ino %x\n", ii->ie->id, ii->ie->ino);
>
> @@ -335,15 +336,18 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
> data.rcv_wup = tse->rcv_wup;
> }
>
> - if (restore_sockaddr(&data.src_addr,
> + if (restore_sockaddr(&sa_src,
> ii->ie->family, ii->ie->src_port,
> ii->ie->src_addr, 0) < 0)
> goto err_c;
> - if (restore_sockaddr(&data.dst_addr,
> + if (restore_sockaddr(&sa_dst,
> ii->ie->family, ii->ie->dst_port,
> ii->ie->dst_addr, 0) < 0)
> goto err_c;
>
> + libsoccr_set_addr(socr, 1, &sa_src);
> + libsoccr_set_addr(socr, 0, &sa_dst);
> +
> /*
> * O_NONBLOCK has to be set before libsoccr_restore(),
> * it is required to restore syn-sent sockets.
> diff --git a/soccr/soccr.c b/soccr/soccr.c
> index e6d0692..7324f94 100644
> --- a/soccr/soccr.c
> +++ b/soccr/soccr.c
> @@ -106,6 +106,8 @@ struct libsoccr_sk {
> int fd;
> char *recv_queue;
> char *send_queue;
> + union libsoccr_addr *src_addr;
> + union libsoccr_addr *dst_addr;
> };
>
> struct libsoccr_sk *libsoccr_pause(int fd)
> @@ -123,6 +125,8 @@ struct libsoccr_sk *libsoccr_pause(int fd)
>
> ret->recv_queue = NULL;
> ret->send_queue = NULL;
> + ret->src_addr = NULL;
> + ret->dst_addr = NULL;
> ret->fd = fd;
> return ret;
> }
> @@ -132,6 +136,8 @@ void libsoccr_resume(struct libsoccr_sk *sk)
> tcp_repair_off(sk->fd);
> free(sk->send_queue);
> free(sk->recv_queue);
> + free(sk->src_addr);
src_addr is set to an extrernal buffer, is it ok to call free() for it?
> + free(sk->dst_addr);
> free(sk);
> }
>
> @@ -376,6 +382,12 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal)
> return ret;
> }
>
> +union libsoccr_addr *libsoccr_get_addr(struct libsoccr_sk *sk, int self, int steal)
> +{
> + /* FIXME -- implemeted in CRIU, makes sence to have it here too */
> + return NULL;
> +}
> +
> static int set_queue_seq(struct libsoccr_sk *sk, int queue, __u32 seq)
> {
> logd("\tSetting %d queue seq to %u\n", queue, seq);
> @@ -408,6 +420,9 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
> if (!data || data_size < SOCR_DATA_MIN_SIZE)
> return -1;
>
> + if (!sk->dst_addr || !sk->src_addr)
> + return -1;
> +
> mstate = 1 << data->state;
>
> if (data->state == TCP_LISTEN)
> @@ -431,15 +446,15 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
> if (set_queue_seq(sk, TCP_SEND_QUEUE, seq))
> return -3;
>
> - if (data->dst_addr.sa.sa_family == AF_INET)
> - addr_size = sizeof(data->dst_addr.v4);
> + if (sk->dst_addr->sa.sa_family == AF_INET)
> + addr_size = sizeof(sk->dst_addr->v4);
> else
> - addr_size = sizeof(data->dst_addr.v6);
> + addr_size = sizeof(sk->dst_addr->v6);
>
> if (data->state == TCP_SYN_SENT && tcp_repair_off(sk->fd))
> return -1;
>
> - if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1 &&
> + if (connect(sk->fd, &sk->dst_addr->sa, addr_size) == -1 &&
> errno != EINPROGRESS) {
> loge("Can't connect inet socket back\n");
> return -1;
> @@ -495,7 +510,8 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
> return 0;
> }
>
> -static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t flags)
> +static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
> + unsigned data_size, uint8_t flags)
> {
> int ret, exit_code = -1;
> char errbuf[LIBNET_ERRBUF_SIZE];
> @@ -503,7 +519,7 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
> int libnet_type;
> libnet_t *l;
>
> - if (data->dst_addr.sa.sa_family == AF_INET6)
> + if (sk->dst_addr->sa.sa_family == AF_INET6)
> libnet_type = LIBNET_RAW6;
> else
> libnet_type = LIBNET_RAW4;
> @@ -519,8 +535,8 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
> goto err;
>
> ret = libnet_build_tcp(
> - ntohs(data->dst_addr.v4.sin_port), /* source port */
> - ntohs(data->src_addr.v4.sin_port), /* destination port */
> + ntohs(sk->dst_addr->v4.sin_port), /* source port */
> + ntohs(sk->src_addr->v4.sin_port), /* destination port */
> data->inq_seq, /* sequence number */
> data->outq_seq - data->outq_len, /* acknowledgement num */
> flags, /* control flags */
> @@ -537,11 +553,11 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
> goto err;
> }
>
> - if (data->dst_addr.sa.sa_family == AF_INET6) {
> + if (sk->dst_addr->sa.sa_family == AF_INET6) {
> struct libnet_in6_addr src, dst;
>
> - memcpy(&dst, &data->dst_addr.v6.sin6_addr, sizeof(dst));
> - memcpy(&src, &data->src_addr.v6.sin6_addr, sizeof(src));
> + memcpy(&dst, &sk->dst_addr->v6.sin6_addr, sizeof(dst));
> + memcpy(&src, &sk->src_addr->v6.sin6_addr, sizeof(src));
>
> ret = libnet_build_ipv6(
> 0, 0,
> @@ -554,7 +570,7 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
> 0, /* payload size */
> l, /* libnet handle */
> 0); /* libnet id */
> - } else if (data->dst_addr.sa.sa_family == AF_INET)
> + } else if (sk->dst_addr->sa.sa_family == AF_INET)
> ret = libnet_build_ipv4(
> LIBNET_IPV4_H + LIBNET_TCP_H + 20, /* length */
> 0, /* TOS */
> @@ -563,8 +579,8 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
> 64, /* TTL */
> IPPROTO_TCP, /* protocol */
> 0, /* checksum */
> - data->dst_addr.v4.sin_addr.s_addr, /* source IP */
> - data->src_addr.v4.sin_addr.s_addr, /* destination IP */
> + sk->dst_addr->v4.sin_addr.s_addr, /* source IP */
> + sk->src_addr->v4.sin_addr.s_addr, /* destination IP */
> NULL, /* payload */
> 0, /* payload size */
> l, /* libnet handle */
> @@ -667,7 +683,7 @@ int libsoccr_restore(struct libsoccr_sk *sk,
>
> /* Send a fin packet to the socket to restore it in a receive queue. */
> if (mstate & (RCVQ_FIRST_FIN | RCVQ_SECOND_FIN))
> - if (send_fin(data, data_size, TH_ACK | TH_FIN) < 0)
> + if (send_fin(sk, data, data_size, TH_ACK | TH_FIN) < 0)
> return -1;
>
> if (mstate & SNDQ_SECOND_FIN)
> @@ -678,7 +694,7 @@ int libsoccr_restore(struct libsoccr_sk *sk,
>
> if (mstate & SNDQ_FIN_ACKED) {
> data->outq_seq++;
> - if (send_fin(data, data_size, TH_ACK) < 0)
> + if (send_fin(sk, data, data_size, TH_ACK) < 0)
> return -1;
> }
>
> @@ -806,3 +822,13 @@ int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes)
>
> return -1;
> }
> +
> +int libsoccr_set_addr(struct libsoccr_sk *sk, int self, union libsoccr_addr *addr)
> +{
> + if (self)
> + sk->src_addr = addr;
> + else
> + sk->dst_addr = addr;
> +
> + return 0;
> +}
> diff --git a/soccr/soccr.h b/soccr/soccr.h
> index 36043ae..d6ad3cf 100644
> --- a/soccr/soccr.h
> +++ b/soccr/soccr.h
> @@ -90,9 +90,6 @@ struct libsoccr_sk_data {
> __u32 max_window;
> __u32 rcv_wnd;
> __u32 rcv_wup;
> -
> - union libsoccr_addr src_addr;
> - union libsoccr_addr dst_addr;
> };
>
> /*
> @@ -172,6 +169,13 @@ int libsoccr_save(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigne
> char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
>
> /*
> + * Returns filled libsoccr_addr for a socket. This value is also required
> + * on restore, but addresses may be obtained from somewhere else, these
> + * are just common sockaddr-s.
> + */
> +union libsoccr_addr *libsoccr_get_addr(struct libsoccr_sk *sk, int self, int steal);
> +
> +/*
> * RESTORING calls
> *
> * The restoring of a socket is like below
> @@ -183,6 +187,8 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
> * h = libsoccr_pause(sk)
> * libsoccr_set_queue_bytes(h, TCP_SEND_QUEUE, outq);
> * libsoccr_set_queue_bytes(h, TCP_RECV_QUEUE, inq);
> + * libsoccr_set_addr(h, 1, src_addr);
> + * libsoccr_set_addr(h, 0, dst_addr);
> * libsoccr_restore(h, &data, sizeof(data))
> *
> * libsoccr_resume(h)
> @@ -198,6 +204,12 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
> int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes);
>
> /*
> + * Set a pointer on the libsoccr_addr for src/dst. The buffer is as
> + * well stolen by the library and is fre()-ed after libsoccr_resume().
> + */
> +int libsoccr_set_addr(struct libsoccr_sk *sk, int self, union libsoccr_addr *);
> +
> +/*
> * Performs restore actions on bind()-ed socket
> */
> int libsoccr_restore(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
> --
> 2.5.0
>
More information about the CRIU
mailing list