[CRIU] [PATCHv4 1/7] remote: Refactor TCP server setup

Radostin Stoyanov rstoyanov1 at gmail.com
Thu Sep 13 20:28:05 MSK 2018


The function `setup_TCP_server_socket` (defined in img-remote.c) and
`setup_tcp_server` (defined in util.c) have very similar functionality.

Replace setup_TCP_server_socket() with setup_tcp_server() to reduce
code duplication and to enable IPv6 support for the image-cache action
of CRIU.

We set SO_REUSEADDR flag to allow reuse of local addresses.

Signed-off-by: Radostin Stoyanov <rstoyanov1 at gmail.com>
---
 criu/img-cache.c          |  3 ++-
 criu/img-remote.c         | 40 ---------------------------------------
 criu/include/img-remote.h |  1 -
 criu/include/util.h       |  2 +-
 criu/page-xfer.c          |  2 +-
 criu/util.c               | 30 ++++++++++++++++++-----------
 6 files changed, 23 insertions(+), 55 deletions(-)

diff --git a/criu/img-cache.c b/criu/img-cache.c
index b7de884e..2177afa8 100644
--- a/criu/img-cache.c
+++ b/criu/img-cache.c
@@ -6,6 +6,7 @@
 #include <netinet/in.h>
 #include <fcntl.h>
 #include "cr_options.h"
+#include "util.h"
 
 int accept_proxy_to_cache(int sockfd)
 {
@@ -31,7 +32,7 @@ int image_cache(bool background, char *local_cache_path, unsigned short cache_wr
 		proxy_to_cache_fd = opts.ps_socket;
 		pr_info("Re-using ps socket %d\n", proxy_to_cache_fd);
 	} else {
-		proxy_to_cache_fd = setup_TCP_server_socket(cache_write_port);
+		proxy_to_cache_fd = setup_tcp_server("image cache", NULL, &cache_write_port);
 		if (proxy_to_cache_fd < 0) {
 			pr_perror("Unable to open proxy to cache TCP socket");
 			return -1;
diff --git a/criu/img-remote.c b/criu/img-remote.c
index 896af57b..4391a1f9 100644
--- a/criu/img-remote.c
+++ b/criu/img-remote.c
@@ -118,46 +118,6 @@ struct roperation *get_rop_by_name(
 	return NULL;
 }
 
-int setup_TCP_server_socket(int port)
-{
-	struct sockaddr_in serv_addr;
-	int sockopt = 1;
-	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
-	if (sockfd < 0) {
-		pr_perror("Unable to open image socket");
-		return -1;
-	}
-
-	bzero((char *) &serv_addr, sizeof(serv_addr));
-	serv_addr.sin_family = AF_INET;
-	serv_addr.sin_addr.s_addr = INADDR_ANY;
-	serv_addr.sin_port = htons(port);
-
-	if (setsockopt(
-		sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) == -1) {
-		pr_perror("Unable to set SO_REUSEADDR");
-		goto err;
-	}
-
-	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
-		pr_perror("Unable to bind image socket");
-		goto err;
-	}
-
-	if (listen(sockfd, DEFAULT_LISTEN)) {
-		pr_perror("Unable to listen image socket");
-		goto err;
-	}
-
-	return sockfd;
-err:
-	close(sockfd);
-	return -1;
-}
-
-
-
 int setup_TCP_client_socket(char *hostname, int port)
 {
 	int sockfd;
diff --git a/criu/include/img-remote.h b/criu/include/img-remote.h
index 179a2ea7..99034ef8 100644
--- a/criu/include/img-remote.h
+++ b/criu/include/img-remote.h
@@ -82,7 +82,6 @@ int64_t recv_image_async(struct roperation *op);
 int64_t read_remote_header(int fd, char *snapshot_id, char *path, int *open_mode, uint64_t *size);
 int64_t write_remote_header(int fd, char *snapshot_id, char *path, int open_mode, uint64_t size);
 
-int setup_TCP_server_socket(int port);
 int setup_TCP_client_socket(char *hostname, int port);
 int setup_UNIX_server_socket(char *path);
 void socket_set_non_blocking(int fd);
diff --git a/criu/include/util.h b/criu/include/util.h
index dd280ec3..af9b6c53 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -289,7 +289,7 @@ char *xsprintf(const char *fmt, ...)
 
 void print_data(unsigned long addr, unsigned char *data, size_t size);
 
-int setup_tcp_server(char *type);
+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);
 
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 028754a3..a949f487 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -1013,7 +1013,7 @@ int cr_page_server(bool daemon_mode, bool lazy_dump, int cfd)
 		goto no_server;
 	}
 
-	sk = setup_tcp_server("page");
+	sk = setup_tcp_server("page", opts.addr, &opts.port);
 	if (sk == -1)
 		return -1;
 no_server:
diff --git a/criu/util.c b/criu/util.c
index 22d0be42..7171d6cd 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1260,7 +1260,8 @@ void print_data(unsigned long addr, unsigned char *data, size_t size)
 	}
 }
 
-static int get_sockaddr_in(struct sockaddr_storage *addr, char *host)
+static int get_sockaddr_in(struct sockaddr_storage *addr, char *host,
+			unsigned short port)
 {
 	memset(addr, 0, sizeof(*addr));
 
@@ -1277,25 +1278,26 @@ static int get_sockaddr_in(struct sockaddr_storage *addr, char *host)
 	}
 
 	if (addr->ss_family == AF_INET6) {
-		((struct sockaddr_in6 *)addr)->sin6_port = htons(opts.port);
+		((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
 	} else if (addr->ss_family == AF_INET) {
-		((struct sockaddr_in *)addr)->sin_port = htons(opts.port);
+		((struct sockaddr_in *)addr)->sin_port = htons(port);
 	}
 
 	return 0;
 }
 
-int setup_tcp_server(char *type)
+int setup_tcp_server(char *type, char *addr, unsigned short *port)
 {
 	int sk = -1;
+	int sockopt = 1;
 	struct sockaddr_storage saddr;
 	socklen_t slen = sizeof(saddr);
 
-	if (get_sockaddr_in(&saddr, opts.addr)) {
+	if (get_sockaddr_in(&saddr, addr, (*port))) {
 		return -1;
 	}
 
-	pr_info("Starting %s server on port %u\n", type, opts.port);
+	pr_info("Starting %s server on port %u\n", type, *port);
 
 	sk = socket(saddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
 
@@ -1304,6 +1306,12 @@ int setup_tcp_server(char *type)
 		return -1;
 	}
 
+	if (setsockopt(
+		sk, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) == -1) {
+		pr_perror("Unable to set SO_REUSEADDR");
+		goto out;
+	}
+
 	if (bind(sk, (struct sockaddr *)&saddr, slen)) {
 		pr_perror("Can't bind %s server", type);
 		goto out;
@@ -1315,19 +1323,19 @@ int setup_tcp_server(char *type)
 	}
 
 	/* Get socket port in case of autobind */
-	if (opts.port == 0) {
+	if ((*port) == 0) {
 		if (getsockname(sk, (struct sockaddr *)&saddr, &slen)) {
 			pr_perror("Can't get %s server name", type);
 			goto out;
 		}
 
 		if (saddr.ss_family == AF_INET6) {
-			opts.port = ntohs(((struct sockaddr_in6 *)&saddr)->sin6_port);
+			(*port) = ntohs(((struct sockaddr_in *)&saddr)->sin_port);
 		} else if (saddr.ss_family == AF_INET) {
-			opts.port = ntohs(((struct sockaddr_in *)&saddr)->sin_port);
+			(*port) = ntohs(((struct sockaddr_in6 *)&saddr)->sin6_port);
 		}
 
-		pr_info("Using %u port\n", opts.port);
+		pr_info("Using %u port\n", (*port));
 	}
 
 	return sk;
@@ -1390,7 +1398,7 @@ int setup_tcp_client(char *addr)
 
 	pr_info("Connecting to server %s:%u\n", addr, opts.port);
 
-	if (get_sockaddr_in(&saddr, addr))
+	if (get_sockaddr_in(&saddr, addr, opts.port))
 		return -1;
 
 	sk = socket(saddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
-- 
2.17.1



More information about the CRIU mailing list