Skip to content

Commit

Permalink
sockets: allow port to be NULL when listening on IP address
Browse files Browse the repository at this point in the history
If the port in the SocketAddress struct is NULL, it can allow
the kernel to automatically select a free port. This is useful
in particular in unit tests to avoid a race trying to find a
free port to run a test case on.

Signed-off-by: Daniel P. Berrange <[email protected]>
  • Loading branch information
berrange committed Oct 20, 2015
1 parent 2a8e21c commit 0983f5e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
6 changes: 4 additions & 2 deletions qapi-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2614,7 +2614,9 @@
#
# @host: host part of the address
#
# @port: port part of the address, or lowest port if @to is present
# @port: port part of the address, or lowest port if @to is present.
# Kernel selects a free port if omitted for listener addresses.
# #optional
#
# @to: highest port to try
#
Expand All @@ -2629,7 +2631,7 @@
{ 'struct': 'InetSocketAddress',
'data': {
'host': 'str',
'port': 'str',
'*port': 'str',
'*to': 'uint16',
'*ipv4': 'bool',
'*ipv6': 'bool' } }
Expand Down
18 changes: 13 additions & 5 deletions util/qemu-sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
ai.ai_family = PF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;

if ((qemu_opt_get(opts, "host") == NULL) ||
(qemu_opt_get(opts, "port") == NULL)) {
error_setg(errp, "host and/or port not specified");
if ((qemu_opt_get(opts, "host") == NULL)) {
error_setg(errp, "host not specified");
return -1;
}
pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
if (qemu_opt_get(opts, "port") != NULL) {
pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
} else {
port[0] = '\0';
}
addr = qemu_opt_get(opts, "host");

to = qemu_opt_get_number(opts, "to", 0);
Expand All @@ -145,6 +148,10 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
/* lookup */
if (port_offset) {
unsigned long long baseport;
if (strlen(port) == 0) {
error_setg(errp, "port not specified");
return -1;
}
if (parse_uint_full(port, &baseport, 10) < 0) {
error_setg(errp, "can't convert to a number: %s", port);
return -1;
Expand All @@ -156,7 +163,8 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
}
snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
}
rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res);
rc = getaddrinfo(strlen(addr) ? addr : NULL,
strlen(port) ? port : NULL, &ai, &res);
if (rc != 0) {
error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
gai_strerror(rc));
Expand Down

0 comments on commit 0983f5e

Please sign in to comment.