[CRIU] [PATCH 1/2] soccr: c/r ipv6 sockets which handles ipv4 connections

Andrei Vagin avagin at virtuozzo.com
Sat Nov 4 04:22:26 MSK 2017


Applied

On Thu, Nov 02, 2017 at 12:40:34AM +0300, Andrei Vagin wrote:
> From: Andrei Vagin <avagin at virtuozzo.com>
> 
> IPv6 listening sockets can accept both ipv4 and ipv6 connections,
> in both cases a family of an accepted socket will be AF_INET6.
> 
> But we have to send tcp packets accoding with a connection type.
> 
> ------------------------ grep Error ------------------------
> (00.002320)     53: Debug: 		Will set rcv_wscale to 7
> (00.002325)     53: Debug: 		Will turn timestamps on
> (00.002331)     53: Debug: Will set mss clamp to 65495
> (00.002338)     53: Debug: 	Restoring TCP 1 queue data 2 bytes
> (00.002403)     53: Error (soccr/soccr.c:673): Unable to send a fin packet: libnet_write_raw_ipv6(): -1 bytes written (Network is unreachable)
> 
> (00.002434)     53: Error (criu/files.c:1191): Unable to open fd=3 id=0x6
> (00.002506) Error (criu/cr-restore.c:2171): Restoring FAILED.
> ------------------------ ERROR OVER ------------------------
> 
> Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
> 
> Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
> ---
>  soccr/soccr.c | 29 +++++++++++++++++++++++------
>  1 file changed, 23 insertions(+), 6 deletions(-)
> 
> diff --git a/soccr/soccr.c b/soccr/soccr.c
> index 394095f00..2d49766dc 100644
> --- a/soccr/soccr.c
> +++ b/soccr/soccr.c
> @@ -580,16 +580,33 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
>  	return 0;
>  }
>  
> +/* IPv4-Mapped IPv6 Addresses */
> +static int ipv6_addr_mapped(union libsoccr_addr *addr)
> +{
> +	return (addr->v6.sin6_addr.s6_addr32[2] == htonl(0x0000ffff));
> +}
> +
>  static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
>  		unsigned data_size, uint8_t flags)
>  {
> -	int ret, exit_code = -1;
> +	uint32_t src_v4 = sk->src_addr->v4.sin_addr.s_addr;
> +	uint32_t dst_v4 = sk->dst_addr->v4.sin_addr.s_addr;
> +	int ret, exit_code = -1, family;
>  	char errbuf[LIBNET_ERRBUF_SIZE];
>  	int mark = SOCCR_MARK;;
>  	int libnet_type;
>  	libnet_t *l;
>  
> -	if (sk->dst_addr->sa.sa_family == AF_INET6)
> +	family = sk->dst_addr->sa.sa_family;
> +
> +	if (family == AF_INET6 && ipv6_addr_mapped(sk->dst_addr)) {
> +		/* TCP over IPv4 */
> +		family = AF_INET;
> +		dst_v4 = sk->dst_addr->v6.sin6_addr.s6_addr32[3];
> +		src_v4 = sk->src_addr->v6.sin6_addr.s6_addr32[3];
> +	}
> +
> +	if (family == AF_INET6)
>  		libnet_type = LIBNET_RAW6;
>  	else
>  		libnet_type = LIBNET_RAW4;
> @@ -627,7 +644,7 @@ static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
>  		goto err;
>  	}
>  
> -	if (sk->dst_addr->sa.sa_family == AF_INET6) {
> +	if (family == AF_INET6) {
>  		struct libnet_in6_addr src, dst;
>  
>  		memcpy(&dst, &sk->dst_addr->v6.sin6_addr, sizeof(dst));
> @@ -644,7 +661,7 @@ static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
>  			0,		/* payload size */
>  			l,		/* libnet handle */
>  			0);		/* libnet id */
> -	} else if (sk->dst_addr->sa.sa_family == AF_INET)
> +	} else if (family == AF_INET)
>  		ret = libnet_build_ipv4(
>  			LIBNET_IPV4_H + LIBNET_TCP_H + 20,	/* length */
>  			0,			/* TOS */
> @@ -653,8 +670,8 @@ static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
>  			64,			/* TTL */
>  			IPPROTO_TCP,		/* protocol */
>  			0,			/* checksum */
> -			sk->dst_addr->v4.sin_addr.s_addr,	/* source IP */
> -			sk->src_addr->v4.sin_addr.s_addr,	/* destination IP */
> +			dst_v4,			/* source IP */
> +			src_v4,			/* destination IP */
>  			NULL,			/* payload */
>  			0,			/* payload size */
>  			l,			/* libnet handle */
> -- 
> 2.13.6
> 


More information about the CRIU mailing list