[CRIU] [PATCH 04/11] inet: dump source and destination addresses for closed sockets
Andrei Vagin
avagin at openvz.org
Thu Nov 10 23:10:04 PST 2016
From: Andrei Vagin <avagin at virtuozzo.com>
If a socket has been closed, it still has both addresses and
we need to dump them.
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
criu/sk-inet.c | 61 +++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 924cf8c..5807ed2 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -180,10 +180,30 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
return 1;
}
+union sockaddr_inet {
+ struct sockaddr addr;
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+};
+
+static int dump_sockaddr(union sockaddr_inet *sa, u32 *pb_port, u32 *pb_addr)
+{
+ if (sa->addr.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->addr.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)
{
struct inet_sk_desc *sk;
- char address;
+ union sockaddr_inet address;
socklen_t aux;
int ret;
@@ -191,26 +211,40 @@ static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p, int
if (!sk)
goto err;
- /* It should has no peer name */
- aux = sizeof(address);
+ 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 (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);
if (ret < 0) {
if (errno != ENOTCONN) {
pr_perror("Unexpected error returned from unconnected socket");
goto err;
}
- } else if (ret == 0) {
- pr_err("Name resolved on unconnected socket\n");
+ } else if (dump_sockaddr(&address, &sk->dst_port, sk->dst_addr))
goto err;
- }
- 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)
+ ret = getsockname(lfd, &address.addr, &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;
+ sk->sd.ino = p->stat.st_ino;
+
if (proto == IPPROTO_TCP) {
struct tcp_info info;
@@ -654,11 +688,6 @@ err:
return -1;
}
-union sockaddr_inet {
- struct sockaddr_in v4;
- struct sockaddr_in6 v6;
-};
-
static int restore_sockaddr(union sockaddr_inet *sa,
int family, u32 pb_port, u32 *pb_addr, u32 ifindex)
{
--
2.7.4
More information about the CRIU
mailing list