Commit 29738509 authored by Radostin Stoyanov's avatar Radostin Stoyanov Committed by Andrei Vagin

remote: Refactor TCP server setup

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: 's avatarRadostin Stoyanov <rstoyanov1@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 9388b78d
......@@ -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);
......
......@@ -991,7 +991,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:
......
......@@ -1245,7 +1245,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));
......@@ -1262,25 +1263,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);
......@@ -1289,6 +1291,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;
......@@ -1300,19 +1308,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;
......@@ -1375,7 +1383,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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment