Since -vnc uses ':' to separate the address from the port, raw
IPv6 addresses need to be escaped like [addr]:port
* src/qemu/qemu_command.c: Escape raw IPv6 addresses with []
* tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args,
tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml: Tweak
to test Ipv6 escaping
---
src/qemu/qemu_command.c | 63 ++++++++++++-------
.../qemuxml2argv-graphics-vnc.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml | 2 +-
3 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2828823..6fa401f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3893,11 +3893,14 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->data.vnc.socket);
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
- if (def->graphics[0]->data.vnc.listenAddr)
- virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1);
- else if (driver->vncListen)
- virBufferAdd(&opt, driver->vncListen, -1);
-
+ const char *addr = def->graphics[0]->data.vnc.listenAddr ?
+ def->graphics[0]->data.vnc.listenAddr :
+ driver->vncListen;
+ bool escapeAddr = strchr(addr, ':');
+ if (escapeAddr)
+ virBufferAsprintf(&opt, "[%s]", addr);
+ else
+ virBufferAdd(&opt, addr, -1);
virBufferAsprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900);
@@ -5734,32 +5737,46 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
if (STRPREFIX(val, "unix:")) {
+ /* -vnc unix:/some/big/path */
vnc->data.vnc.socket = strdup(val + 5);
if (!vnc->data.vnc.socket) {
VIR_FREE(vnc);
goto no_memory;
}
} else {
- tmp = strchr(val, ':');
- if (tmp) {
- char *opts;
- if (virStrToLong_i(tmp+1, &opts, 10,
- &vnc->data.vnc.port) < 0) {
- VIR_FREE(vnc);
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse VNC port
'%s'"), tmp+1);
- goto error;
- }
+ /*
+ * -vnc 127.0.0.1:4
+ * -vnc [2001:1:2:3:4:5:1234:1234]:4
+ * -vnc some.host.name:4
+ */
+ char *opts;
+ const char *sep = ":";
+ if (val[0] == '[')
+ sep = "]:";
+ tmp = strstr(val, sep);
+ if (!tmp) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing VNC port number in
'%s'"), val);
+ goto error;
+ }
+ if (virStrToLong_i(tmp+strlen(sep), &opts, 10,
+ &vnc->data.vnc.port) < 0) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse VNC port '%s'"),
tmp+1);
+ goto error;
+ }
+ if (val[0] == '[')
+ vnc->data.vnc.listenAddr = strndup(val+1, tmp-(val+1));
+ else
vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
- VIR_FREE(vnc);
- goto no_memory;
- }
- vnc->data.vnc.port += 5900;
- vnc->data.vnc.autoport = 0;
- } else {
- vnc->data.vnc.autoport = 1;
+ if (!vnc->data.vnc.listenAddr) {
+ VIR_FREE(vnc);
+ goto no_memory;
}
+ vnc->data.vnc.port += 5900;
+ vnc->data.vnc.autoport = 0;
}
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
index 13aa138..2af1540 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
@@ -1,4 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,\
nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none \
--parallel none -usb -vnc 127.0.0.1:3
+-parallel none -usb -vnc [2001:1:2:3:4:5:1234:1234]:3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
index eb6be7d..6304104 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
@@ -21,7 +21,7 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no'
listen='127.0.0.1'/>
+ <graphics type='vnc' port='5903' autoport='no'
listen='2001:1:2:3:4:5:1234:1234'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
--
1.7.4.4