mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
inet: dump source and destination addresses for closed sockets
If a socket has been closed, it still has both addresses and we need to dump them. travis-ci: success for series starting with [01/21] build: install libnet-dev Signed-off-by: Andrei Vagin <avagin@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
6e68374369
commit
e7f03fbae1
@ -182,10 +182,24 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dump_sockaddr(union libsoccr_addr *sa, u32 *pb_port, u32 *pb_addr)
|
||||||
|
{
|
||||||
|
if (sa->sa.sa_family == AF_INET) {
|
||||||
|
memcpy(pb_addr, &sa->v4.sin_addr, sizeof(sa->v4.sin_addr));
|
||||||
|
*pb_port = ntohs(sa->v4.sin_port);
|
||||||
|
return 0;
|
||||||
|
} if (sa->sa.sa_family == AF_INET6) {
|
||||||
|
*pb_port = ntohs(sa->v6.sin6_port);
|
||||||
|
memcpy(pb_addr, &sa->v6.sin6_addr, sizeof(sa->v6.sin6_addr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p, int proto)
|
static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p, int proto)
|
||||||
{
|
{
|
||||||
struct inet_sk_desc *sk;
|
struct inet_sk_desc *sk;
|
||||||
char address;
|
union libsoccr_addr address;
|
||||||
socklen_t aux;
|
socklen_t aux;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -193,26 +207,40 @@ static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p, int
|
|||||||
if (!sk)
|
if (!sk)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* It should has no peer name */
|
ret = do_dump_opt(lfd, SOL_SOCKET, SO_DOMAIN, &sk->sd.family, sizeof(sk->sd.family));
|
||||||
aux = sizeof(address);
|
ret |= do_dump_opt(lfd, SOL_SOCKET, SO_TYPE, &sk->type, sizeof(sk->type));
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (sk->sd.family == AF_INET)
|
||||||
|
aux = sizeof(struct sockaddr_in);
|
||||||
|
else if (sk->sd.family == AF_INET6)
|
||||||
|
aux = sizeof(struct sockaddr_in6);
|
||||||
|
else {
|
||||||
|
pr_err("Unsupported socket family: %d\n", sk->sd.family);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ret = getsockopt(lfd, SOL_SOCKET, SO_PEERNAME, &address, &aux);
|
ret = getsockopt(lfd, SOL_SOCKET, SO_PEERNAME, &address, &aux);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno != ENOTCONN) {
|
if (errno != ENOTCONN) {
|
||||||
pr_perror("Unexpected error returned from unconnected socket");
|
pr_perror("Unexpected error returned from unconnected socket");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else if (ret == 0) {
|
} else if (dump_sockaddr(&address, &sk->dst_port, sk->dst_addr))
|
||||||
pr_err("Name resolved on unconnected socket\n");
|
goto err;
|
||||||
|
|
||||||
|
ret = getsockname(lfd, &address.sa, &aux);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno != ENOTCONN) {
|
||||||
|
pr_perror("Unexpected error returned from unconnected socket");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else if (dump_sockaddr(&address, &sk->src_port, sk->src_addr))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
sk->sd.ino = p->stat.st_ino;
|
sk->sd.ino = p->stat.st_ino;
|
||||||
|
|
||||||
ret = do_dump_opt(lfd, SOL_SOCKET, SO_DOMAIN, &sk->sd.family, sizeof(sk->sd.family));
|
|
||||||
ret |= do_dump_opt(lfd, SOL_SOCKET, SO_TYPE, &sk->type, sizeof(sk->type));
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (proto == IPPROTO_TCP) {
|
if (proto == IPPROTO_TCP) {
|
||||||
struct tcp_info info;
|
struct tcp_info info;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user