[CRIU] [PATCHv4 3/7] util: Enable hostname resolution in tcp_client
Radostin Stoyanov
rstoyanov1 at gmail.com
Thu Sep 13 20:28:07 MSK 2018
Add hostname resolution in setup_tcp_client(). This change allows a
valid hostname to be provided as value for --address option when
connecting to page server.
This change is needed for the following path which removes
setup_TCP_client_socket() from img-proxy.c. In this function the
hostname resolution was implemented using gethostbyname()
However, here we use `getaddrinfo` instead because gethostbyname() is
marked obsolescent in POSIX.1-2001 and is removed in POSIX.1-2008
specifications.
Signed-off-by: Radostin Stoyanov <rstoyanov1 at gmail.com>
---
Documentation/criu.txt | 2 +-
criu/include/util.h | 2 +-
criu/util.c | 67 +++++++++++++++++++++++++++++++++---------
3 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index 003d748c..4194f5b0 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -558,7 +558,7 @@ Launches *criu* in page server mode.
It isn't supposed to use --daemon and --status-fd together.
*--address* 'address'::
- Page server IP address.
+ Page server IP address or hostname.
*--port* 'number'::
Page server port number.
diff --git a/criu/include/util.h b/criu/include/util.h
index af9b6c53..1e2fec81 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -291,7 +291,7 @@ void print_data(unsigned long addr, unsigned char *data, size_t size);
int setup_tcp_server(char *type, char *addr, unsigned short *port);
int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk);
-int setup_tcp_client(char *addr);
+int setup_tcp_client(char *hostname);
#define LAST_PID_PATH "sys/kernel/ns_last_pid"
#define PID_MAX_PATH "sys/kernel/pid_max"
diff --git a/criu/util.c b/criu/util.c
index 7171d6cd..bdb4aadf 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -30,6 +30,7 @@
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sched.h>
@@ -1391,28 +1392,66 @@ out:
return -1;
}
-int setup_tcp_client(char *addr)
+int setup_tcp_client(char *hostname)
{
struct sockaddr_storage saddr;
- int sk;
-
- pr_info("Connecting to server %s:%u\n", addr, opts.port);
+ struct addrinfo addr_criteria, *addr_list, *p;
+ char ipstr[INET6_ADDRSTRLEN];
+ int sk = -1;
+ void *ip;
- if (get_sockaddr_in(&saddr, addr, opts.port))
- return -1;
+ memset(&addr_criteria, 0, sizeof(addr_criteria));
+ addr_criteria.ai_family = AF_UNSPEC;
+ addr_criteria.ai_socktype = SOCK_STREAM;
+ addr_criteria.ai_protocol = IPPROTO_TCP;
- sk = socket(saddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
- if (sk < 0) {
- pr_perror("Can't create socket");
- return -1;
+ /*
+ * addr_list contains a list of addrinfo structures that corresponding
+ * to the criteria specified in hostname and addr_criteria.
+ */
+ if (getaddrinfo(hostname, NULL, &addr_criteria, &addr_list)) {
+ pr_perror("Failed to resolve hostname: %s", hostname);
+ goto out;
}
- if (connect(sk, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- pr_perror("Can't connect to server");
- close(sk);
- return -1;
+ /*
+ * Iterate through addr_list and try to connect. The loop stops if the
+ * connection is successful or we reach the end of the list.
+ */
+ for(p = addr_list; p != NULL; p = p->ai_next) {
+
+ if (p->ai_family == AF_INET) {
+ struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
+ ip = &(ipv4->sin_addr);
+ } else {
+ struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
+ ip = &(ipv6->sin6_addr);
+ }
+
+ inet_ntop(p->ai_family, ip, ipstr, sizeof(ipstr));
+ pr_info("Connecting to server %s:%u\n", ipstr, opts.port);
+
+ if (get_sockaddr_in(&saddr, ipstr, opts.port))
+ goto out;
+
+ sk = socket(saddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
+ if (sk < 0) {
+ pr_perror("Can't create socket");
+ goto out;
+ }
+
+ if (connect(sk, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+ pr_info("Can't connect to server %s:%u\n", ipstr, opts.port);
+ close(sk);
+ sk = -1;
+ } else {
+ /* Connected successfully */
+ break;
+ }
}
+out:
+ freeaddrinfo(addr_list);
return sk;
}
--
2.17.1
More information about the CRIU
mailing list