mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
util: introduce virSocketAddrParseAny
When preparing for migration, the libxl driver creates a new TCP listen socket for the incoming migration by calling virNetSocketNewListenTCP, passing the destination host name. virNetSocketNewListenTCP calls virSocketAddrParse to check if the host name is a wildcard address, in which case it avoids adding the AI_ADDRCONFIG flag to the hints passed to getaddrinfo. If the host name is not an IP address, virSocketAddrParse reports an error error : virSocketAddrParseInternal:121 : Cannot parse socket address 'myhost.example.com': Name or service not known But virNetSocketNewListenTCP succeeds regardless and the overall migration operation succeeds. Introduce virSocketAddrParseAny and use it when simply testing if a host name/addr is parsable. Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
0987730301
commit
412afdb8f4
@ -2731,6 +2731,7 @@ virSocketAddrMask;
|
||||
virSocketAddrMaskByPrefix;
|
||||
virSocketAddrNumericFamily;
|
||||
virSocketAddrParse;
|
||||
virSocketAddrParseAny;
|
||||
virSocketAddrParseIPv4;
|
||||
virSocketAddrParseIPv6;
|
||||
virSocketAddrPrefixToNetmask;
|
||||
|
@ -333,7 +333,7 @@ int virNetSocketNewListenTCP(const char *nodename,
|
||||
* startup in most cases.
|
||||
*/
|
||||
if (nodename &&
|
||||
!(virSocketAddrParse(&tmp_addr, nodename, AF_UNSPEC) > 0 &&
|
||||
!(virSocketAddrParseAny(&tmp_addr, nodename, AF_UNSPEC, false) > 0 &&
|
||||
virSocketAddrIsWildcard(&tmp_addr)))
|
||||
hints.ai_flags |= AI_ADDRCONFIG;
|
||||
|
||||
|
@ -101,6 +101,7 @@ static int
|
||||
virSocketAddrParseInternal(struct addrinfo **res,
|
||||
const char *val,
|
||||
int family,
|
||||
int ai_flags,
|
||||
bool reportError)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
@ -114,7 +115,7 @@ virSocketAddrParseInternal(struct addrinfo **res,
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_flags = ai_flags;
|
||||
if ((err = getaddrinfo(val, NULL, &hints, res)) != 0) {
|
||||
if (reportError)
|
||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||
@ -143,7 +144,7 @@ int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family)
|
||||
int len;
|
||||
struct addrinfo *res;
|
||||
|
||||
if (virSocketAddrParseInternal(&res, val, family, true) < 0)
|
||||
if (virSocketAddrParseInternal(&res, val, family, AI_NUMERICHOST, true) < 0)
|
||||
return -1;
|
||||
|
||||
if (res == NULL) {
|
||||
@ -163,6 +164,52 @@ int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family)
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* virSocketAddrParseAny:
|
||||
* @addr: where to store the return value, optional.
|
||||
* @val: a network host name or a numeric network address IPv4 or IPv6
|
||||
* @family: address family to pass down to getaddrinfo
|
||||
* @reportError: boolean to control error reporting
|
||||
*
|
||||
* Mostly a wrapper for getaddrinfo() extracting the address storage
|
||||
* from a host name like acme.example.com or a numeric string like 1.2.3.4
|
||||
* or 2001:db8:85a3:0:0:8a2e:370:7334.
|
||||
*
|
||||
* When @val is a network host name, this function may be susceptible to a
|
||||
* delay due to potentially lengthy netork host address lookups.
|
||||
*
|
||||
* Returns the length of the network address or -1 in case of error.
|
||||
*/
|
||||
int virSocketAddrParseAny(virSocketAddrPtr addr,
|
||||
const char *val,
|
||||
int family,
|
||||
bool reportError)
|
||||
{
|
||||
int len;
|
||||
struct addrinfo *res;
|
||||
|
||||
if (virSocketAddrParseInternal(&res, val, family, 0, reportError) < 0)
|
||||
return -1;
|
||||
|
||||
if (res == NULL) {
|
||||
if (reportError) {
|
||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||
_("No socket addresses found for '%s'"),
|
||||
val);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = res->ai_addrlen;
|
||||
if (addr != NULL) {
|
||||
memcpy(&addr->data.stor, res->ai_addr, len);
|
||||
addr->len = res->ai_addrlen;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* virSocketAddrParseIPv4:
|
||||
* @val: an IPv4 numeric address
|
||||
@ -1105,7 +1152,7 @@ virSocketAddrNumericFamily(const char *address)
|
||||
struct addrinfo *res;
|
||||
unsigned short family;
|
||||
|
||||
if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
|
||||
if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, AI_NUMERICHOST, false) < 0)
|
||||
return -1;
|
||||
|
||||
family = res->ai_addr->sa_family;
|
||||
|
@ -92,6 +92,11 @@ int virSocketAddrParse(virSocketAddrPtr addr,
|
||||
const char *val,
|
||||
int family);
|
||||
|
||||
int virSocketAddrParseAny(virSocketAddrPtr addr,
|
||||
const char *val,
|
||||
int family,
|
||||
bool reportError);
|
||||
|
||||
int virSocketAddrParseIPv4(virSocketAddrPtr addr,
|
||||
const char *val);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user