mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
qemu: Reformat listen address prior to checking
Currently, a listen address for a SPICE server can be specified. Later, when the domain is migrated, we need to relocate the graphics which involves telling new destination to the SPICE server. However, we can't just assume the listen address is the new location, because the listen address can be ANYCAST (0.0.0.0 for IPv4, :: for IPv6). In which case, we want to pass the remote hostname. But there are some troubles with ANYCAST. In both IPv4 and IPv6 it has many ways for specifying such address. For instance, in IPv4: 0, 0.0, 0.0.0, 0.0.0.0. The number of variations gets bigger in IPv6 world. Hence, in order to check for ANYCAST address sanely, we should take the provided listen address, parse it and format back in it's full form. Which is exactly what this patch does.
This commit is contained in:
parent
e90a3598c7
commit
e5fa9db17e
@ -1739,6 +1739,8 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
|
|||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
int ret;
|
int ret;
|
||||||
char *listenAddress;
|
char *listenAddress;
|
||||||
|
virSocketAddr addr;
|
||||||
|
bool reformatted = false;
|
||||||
|
|
||||||
if (!cookie)
|
if (!cookie)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1753,10 +1755,24 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
listenAddress = cookie->graphics->listen;
|
listenAddress = cookie->graphics->listen;
|
||||||
|
|
||||||
|
/* Okay, here's the magic: some mgmt applications set bare '0' as listen
|
||||||
|
* address. On the other hand, it's a valid IPv4 address. This means, we
|
||||||
|
* need to reformat the address so the if statement below can check just
|
||||||
|
* for two ANYCAST addresses and not all their variants. */
|
||||||
|
if (listenAddress &&
|
||||||
|
virSocketAddrParse(&addr, listenAddress, AF_UNSPEC) > 0) {
|
||||||
|
listenAddress = virSocketAddrFormat(&addr);
|
||||||
|
reformatted = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!listenAddress ||
|
if (!listenAddress ||
|
||||||
STREQ(listenAddress, "0.0.0.0") ||
|
STREQ(listenAddress, "0.0.0.0") ||
|
||||||
STREQ(listenAddress, "::"))
|
STREQ(listenAddress, "::")) {
|
||||||
|
if (reformatted)
|
||||||
|
VIR_FREE(listenAddress);
|
||||||
listenAddress = cookie->remoteHostname;
|
listenAddress = cookie->remoteHostname;
|
||||||
|
}
|
||||||
|
|
||||||
ret = qemuDomainObjEnterMonitorAsync(driver, vm,
|
ret = qemuDomainObjEnterMonitorAsync(driver, vm,
|
||||||
QEMU_ASYNC_JOB_MIGRATION_OUT);
|
QEMU_ASYNC_JOB_MIGRATION_OUT);
|
||||||
|
@ -193,6 +193,20 @@ mymain(void)
|
|||||||
ret = -1; \
|
ret = -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define DO_TEST_PARSE_AND_CHECK_FORMAT(addrstr, addrformated, family, pass) \
|
||||||
|
do { \
|
||||||
|
virSocketAddr addr; \
|
||||||
|
struct testParseData data = { &addr, addrstr, family, true}; \
|
||||||
|
memset(&addr, 0, sizeof(addr)); \
|
||||||
|
if (virtTestRun("Test parse " addrstr " family " #family, \
|
||||||
|
1, testParseHelper, &data) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
struct testFormatData data2 = { &addr, addrformated, pass }; \
|
||||||
|
if (virtTestRun("Test format " addrstr " family " #family, \
|
||||||
|
1, testFormatHelper, &data2) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define DO_TEST_RANGE(saddr, eaddr, size, pass) \
|
#define DO_TEST_RANGE(saddr, eaddr, size, pass) \
|
||||||
do { \
|
do { \
|
||||||
struct testRangeData data = { saddr, eaddr, size, pass }; \
|
struct testRangeData data = { saddr, eaddr, size, pass }; \
|
||||||
@ -216,6 +230,16 @@ mymain(void)
|
|||||||
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false);
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false);
|
||||||
DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false);
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false);
|
||||||
|
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.2", AF_INET, true);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.3", AF_INET, false);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("0", "0.0.0.0", AF_INET, true);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127", "0.0.0.127", AF_INET, true);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127", "127.0.0.0", AF_INET, false);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.0.0.2", AF_INET, true);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.2.0.0", AF_INET, false);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.0.3", AF_INET, true);
|
||||||
|
DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.3.0", AF_INET, false);
|
||||||
|
|
||||||
DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true);
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true);
|
||||||
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false);
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false);
|
||||||
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user