mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
soccr: c/r ipv6 sockets which handles ipv4 connections
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@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
09b93e0ac5
commit
6e770e50b8
1 changed files with 23 additions and 6 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue