[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