diff --git a/cfg.mk b/cfg.mk index dcf44bb8c0..9759d87370 100644 --- a/cfg.mk +++ b/cfg.mk @@ -457,6 +457,12 @@ sc_prohibit_xmlGetProp: halt='use virXMLPropString, not xmlGetProp' \ $(_sc_search_regexp) +# xml(ParseURI|SaveUri) doesn't handle IPv6 URIs well +sc_prohibit_xmlURI: + @prohibit='\ -# include # include "internal.h" +# include "viruri.h" /* * List of registered drivers numbers */ diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index f5e1cc73d4..b6b22f8d42 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -44,6 +44,7 @@ #include "esx_vi.h" #include "esx_vi_methods.h" #include "esx_util.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_ESX @@ -3945,7 +3946,7 @@ esxDomainMigratePerform(virDomainPtr domain, { int result = -1; esxPrivate *priv = domain->conn->privateData; - xmlURIPtr parsedUri = NULL; + virURIPtr parsedUri = NULL; char *saveptr; char *path_resourcePool; char *path_hostSystem; @@ -3976,7 +3977,7 @@ esxDomainMigratePerform(virDomainPtr domain, } /* Parse migration URI */ - parsedUri = xmlParseURI(uri); + parsedUri = virURIParse(uri); if (parsedUri == NULL) { virReportOOMError(); diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c index 2c5ac1add0..7d4b9080e8 100644 --- a/src/esx/esx_util.c +++ b/src/esx/esx_util.c @@ -42,7 +42,7 @@ int -esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri) +esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURIPtr uri) { int result = -1; struct qparam_set *queryParamSet = NULL; diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h index 2bee51051a..a69b3f4590 100644 --- a/src/esx/esx_util.h +++ b/src/esx/esx_util.h @@ -22,9 +22,9 @@ #ifndef __ESX_UTIL_H__ # define __ESX_UTIL_H__ -# include # include # include "internal.h" +# include "viruri.h" typedef struct _esxUtil_ParsedUri esxUtil_ParsedUri; @@ -40,7 +40,7 @@ struct _esxUtil_ParsedUri { char *path; }; -int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri); +int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURIPtr uri); void esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri); diff --git a/src/hyperv/hyperv_util.c b/src/hyperv/hyperv_util.c index 298cfe0eef..2e6a2d4726 100644 --- a/src/hyperv/hyperv_util.c +++ b/src/hyperv/hyperv_util.c @@ -37,7 +37,7 @@ int -hypervParseUri(hypervParsedUri **parsedUri, xmlURIPtr uri) +hypervParseUri(hypervParsedUri **parsedUri, virURIPtr uri) { int result = -1; struct qparam_set *queryParamSet = NULL; diff --git a/src/hyperv/hyperv_util.h b/src/hyperv/hyperv_util.h index 9057f55c14..d9d1c84242 100644 --- a/src/hyperv/hyperv_util.h +++ b/src/hyperv/hyperv_util.h @@ -23,9 +23,8 @@ #ifndef __HYPERV_UTIL_H__ # define __HYPERV_UTIL_H__ -# include - # include "internal.h" +# include "viruri.h" typedef struct _hypervParsedUri hypervParsedUri; @@ -33,7 +32,7 @@ struct _hypervParsedUri { char *transport; }; -int hypervParseUri(hypervParsedUri **parsedUri, xmlURIPtr uri); +int hypervParseUri(hypervParsedUri **parsedUri, virURIPtr uri); void hypervFreeParsedUri(hypervParsedUri **parsedUri); diff --git a/src/libvirt.c b/src/libvirt.c index a3bd4f48a7..cbb41194c0 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -23,7 +23,6 @@ #include #include -#include #include "getpass.h" #ifdef HAVE_WINSOCK2_H @@ -44,6 +43,7 @@ #include "command.h" #include "virnodesuspend.h" #include "virrandom.h" +#include "viruri.h" #ifndef WITH_DRIVER_MODULES # ifdef WITH_TEST @@ -1127,7 +1127,7 @@ do_open (const char *name, virConnectOpenResolveURIAlias(name, &alias) < 0) goto failed; - ret->uri = xmlParseURI (alias ? alias : name); + ret->uri = virURIParse (alias ? alias : name); if (!ret->uri) { virLibConnError(VIR_ERR_INVALID_ARG, _("could not parse connection URI %s"), @@ -1729,7 +1729,7 @@ virConnectGetURI (virConnectPtr conn) return NULL; } - name = (char *)xmlSaveUri(conn->uri); + name = virURIFormat(conn->uri); if (!name) { virReportOOMError(); goto error; @@ -4952,7 +4952,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain, const char *uri, unsigned long bandwidth) { - xmlURIPtr tempuri = NULL; + virURIPtr tempuri = NULL; VIR_DOMAIN_DEBUG(domain, "xmlin=%s, flags=%lx, dname=%s, " "dconnuri=%s, uri=%s, bandwidth=%lu", NULLSTR(xmlin), flags, NULLSTR(dname), @@ -4964,7 +4964,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain, return -1; } - tempuri = xmlParseURI(dconnuri); + tempuri = virURIParse(dconnuri); if (!tempuri) { virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); virDispatchError(domain->conn); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 18a24e4854..310cd7d91e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1431,6 +1431,11 @@ virTypedParameterArrayValidate; virTypedParameterAssign; +# viruri.h +virURIFormat; +virURIParse; + + # xml.h virXMLChildElementCount; virXMLParseHelper; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 6cfc5eb0b4..6db33c25e0 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -44,6 +44,7 @@ #include "libxl_conf.h" #include "xen_xm.h" #include "virtypedparam.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -1043,7 +1044,7 @@ libxlOpen(virConnectPtr conn, if (libxl_driver == NULL) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI("xen:///"); + conn->uri = virURIParse("xen:///"); if (!conn->uri) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index b6962cf792..d77afcc4c2 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -60,6 +60,7 @@ #include "virnodesuspend.h" #include "virtime.h" #include "virtypedparam.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -139,7 +140,7 @@ static virDrvOpenStatus lxcOpen(virConnectPtr conn, if (lxc_driver == NULL) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI("lxc:///"); + conn->uri = virURIParse("lxc:///"); if (!conn->uri) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 833a98d34c..aef14915f1 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -56,6 +56,7 @@ #include "virfile.h" #include "logging.h" #include "command.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_OPENVZ @@ -1335,7 +1336,7 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn, if (access("/proc/vz", W_OK) < 0) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI("openvz:///system"); + conn->uri = virURIParse("openvz:///system"); if (conn->uri == NULL) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d3cf9ac5f6..b11d049166 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -857,7 +857,7 @@ static virDrvOpenStatus qemudOpen(virConnectPtr conn, if (qemu_driver == NULL) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI(qemu_driver->privileged ? + conn->uri = virURIParse(qemu_driver->privileged ? "qemu:///system" : "qemu:///session"); if (!conn->uri) { diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3f50136e26..7df2d4f8ce 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1,7 +1,7 @@ /* * qemu_migration.c: QEMU migration handling * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -46,6 +46,7 @@ #include "locking/domain_lock.h" #include "rpc/virnetsocket.h" #include "storage_file.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1792,7 +1793,7 @@ static int doNativeMigrate(struct qemud_driver *driver, virConnectPtr dconn) { qemuDomainObjPrivatePtr priv = vm->privateData; - xmlURIPtr uribits = NULL; + virURIPtr uribits = NULL; int ret = -1; qemuMigrationSpec spec; @@ -1808,10 +1809,10 @@ static int doNativeMigrate(struct qemud_driver *driver, virReportOOMError(); return -1; } - uribits = xmlParseURI(tmp); + uribits = virURIParse(tmp); VIR_FREE(tmp); } else { - uribits = xmlParseURI(uri); + uribits = virURIParse(uri); } if (!uribits) { qemuReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 2dacb70f63..bcd78eedb1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -26,8 +26,6 @@ #include #include -#include - #include "virnetclient.h" #include "virnetclientprogram.h" #include "virnetclientstream.h" @@ -47,6 +45,7 @@ #include "command.h" #include "intprops.h" #include "virtypedparam.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_REMOTE @@ -488,7 +487,7 @@ doRemoteOpen (virConnectPtr conn, /* Allow remote serve to probe */ name = strdup(""); } else { - xmlURI tmpuri = { + virURI tmpuri = { .scheme = conn->uri->scheme, #ifdef HAVE_XMLURI_QUERY_RAW .query_raw = qparam_get_query (vars), @@ -505,7 +504,7 @@ doRemoteOpen (virConnectPtr conn, transport_str[-1] = '\0'; } - name = (char *) xmlSaveUri (&tmpuri); + name = virURIFormat(&tmpuri); #ifdef HAVE_XMLURI_QUERY_RAW VIR_FREE(tmpuri.query_raw); @@ -719,7 +718,7 @@ doRemoteOpen (virConnectPtr conn, goto failed; VIR_DEBUG("Auto-probed URI is %s", uriret.uri); - conn->uri = xmlParseURI(uriret.uri); + conn->uri = virURIParse(uriret.uri); VIR_FREE(uriret.uri); if (!conn->uri) { virReportOOMError(); diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index a4cf9452a7..cbb2c0ed41 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -63,6 +63,7 @@ #include "configmake.h" #include "virnetdevtap.h" #include "virnodesuspend.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_UML @@ -1138,7 +1139,7 @@ static virDrvOpenStatus umlOpen(virConnectPtr conn, if (uml_driver == NULL) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI(uml_driver->privileged ? + conn->uri = virURIParse(uml_driver->privileged ? "uml:///system" : "uml:///session"); if (!conn->uri) { diff --git a/src/util/qparams.c b/src/util/qparams.c index f6d0713cc6..83b568e3d5 100644 --- a/src/util/qparams.c +++ b/src/util/qparams.c @@ -26,12 +26,11 @@ #include #include -#include - #include "virterror_internal.h" #include "buf.h" #include "memory.h" #include "qparams.h" +#include "viruri.h" #define VIR_FROM_THIS VIR_FROM_NONE diff --git a/src/util/viruri.c b/src/util/viruri.c new file mode 100644 index 0000000000..6c4dfe3c08 --- /dev/null +++ b/src/util/viruri.c @@ -0,0 +1,93 @@ +/* + * viruri.c: URI parsing wrappers for libxml2 functions + * + * Copyright (C) 2012 Red Hat, Inc. + * + * See COPYING.LIB for the License of this software + */ + +#include + +#include "viruri.h" + +#include "memory.h" +#include "util.h" + +/** + * virURIParse: + * @uri: URI to parse + * + * Wrapper for xmlParseURI + * + * Unfortunately there are few things that should be managed after + * parsing the URI. Fortunately there is only one thing now and its + * removing of square brackets around IPv6 addresses. + * + * @returns the parsed uri object with some fixes + */ +virURIPtr +virURIParse(const char *uri) +{ + virURIPtr ret = xmlParseURI(uri); + + /* First check: does it even make sense to jump inside */ + if (ret != NULL && + ret->server != NULL && + ret->server[0] == '[') { + size_t length = strlen(ret->server); + + /* We want to modify the server string only if there are + * square brackets on both ends and inside there is IPv6 + * address. Otherwise we could make a mistake by modifying + * something other than an IPv6 address. */ + if (ret->server[length - 1] == ']' && strchr(ret->server, ':')) { + memmove(&ret->server[0], &ret->server[1], length - 2); + ret->server[length - 2] = '\0'; + } + /* Even after such modification, it is completely ok to free + * the uri with xmlFreeURI() */ + } + + return ret; +} + +/** + * virURIFormat: + * @uri: URI to format + * + * Wrapper for xmlSaveUri + * + * This function constructs back everything that @ref virURIParse + * changes after parsing + * + * @returns the constructed uri as a string + */ +char * +virURIFormat(xmlURIPtr uri) +{ + char *backupserver = NULL; + char *tmpserver = NULL; + char *ret; + + /* First check: does it make sense to do anything */ + if (uri != NULL && + uri->server != NULL && + strchr(uri->server, ':') != NULL) { + + backupserver = uri->server; + if (virAsprintf(&tmpserver, "[%s]", uri->server) < 0) + return NULL; + + uri->server = tmpserver; + } + + ret = (char *) xmlSaveUri(uri); + + /* Put the fixed version back */ + if (tmpserver) { + uri->server = backupserver; + VIR_FREE(tmpserver); + } + + return ret; +} diff --git a/src/util/viruri.h b/src/util/viruri.h new file mode 100644 index 0000000000..5215e42d4f --- /dev/null +++ b/src/util/viruri.h @@ -0,0 +1,22 @@ +/* + * viruri.h: internal definitions used for URI parsing. + * + * Copyright (C) 2012 Red Hat, Inc. + * + * See COPYING.LIB for the License of this software + */ + +#ifndef __VIR_URI_H__ +# define __VIR_URI_H__ + +# include + +# include "internal.h" + +typedef xmlURI virURI; +typedef xmlURIPtr virURIPtr; + +virURIPtr virURIParse(const char *uri); +char *virURIFormat(virURIPtr uri); + +#endif /* __VIR_URI_H__ */ diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index b168c7db35..a39b5677b1 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -56,6 +56,7 @@ #include "configmake.h" #include "virfile.h" #include "fdstream.h" +#include "viruri.h" /* This one changes from version to version. */ #if VBOX_API_VERSION == 2002 @@ -980,7 +981,7 @@ static virDrvOpenStatus vboxOpen(virConnectPtr conn, virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); if (conn->uri == NULL) { - conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system"); + conn->uri = virURIParse(uid ? "vbox:///session" : "vbox:///system"); if (conn->uri == NULL) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 910bb0eb69..5a1aebd8e5 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -24,7 +24,6 @@ #include #include -#include #include "internal.h" #include "virterror_internal.h" @@ -33,6 +32,7 @@ #include "logging.h" #include "uuid.h" #include "vmx.h" +#include "viruri.h" /* @@ -2525,7 +2525,7 @@ virVMXParseSerial(virVMXContext *ctx, virConfPtr conf, int port, char network_endPoint_name[48] = ""; char *network_endPoint = NULL; - xmlURIPtr parsedUri = NULL; + virURIPtr parsedUri = NULL; if (def == NULL || *def != NULL) { VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); @@ -2615,7 +2615,7 @@ virVMXParseSerial(virVMXContext *ctx, virConfPtr conf, int port, (*def)->target.port = port; (*def)->source.type = VIR_DOMAIN_CHR_TYPE_TCP; - parsedUri = xmlParseURI(fileName); + parsedUri = virURIParse(fileName); if (parsedUri == NULL) { virReportOOMError(); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 635f4685b0..19ce7dae65 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "virterror_internal.h" #include "logging.h" @@ -50,6 +49,7 @@ #include "uuid.h" #include "fdstream.h" #include "virfile.h" +#include "viruri.h" #include "command.h" #include "virnodesuspend.h" @@ -270,7 +270,7 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) if (!xenUnifiedProbe()) return VIR_DRV_OPEN_DECLINED; - conn->uri = xmlParseURI("xen:///"); + conn->uri = virURIParse("xen:///"); if (!conn->uri) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 77c6f74725..55a99f15c3 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -11,11 +11,10 @@ #ifndef __VIR_XEN_INTERNAL_H__ # define __VIR_XEN_INTERNAL_H__ -# include - # include "internal.h" # include "capabilities.h" # include "driver.h" +# include "viruri.h" /* See xenHypervisorInit() for details. */ struct xenHypervisorVersions { diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 5c3838fe65..83bfac0f27 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "virterror_internal.h" @@ -46,6 +45,7 @@ #include "memory.h" #include "count-one-bits.h" #include "virfile.h" +#include "viruri.h" /* required for cpumap_t */ #include @@ -3224,7 +3224,7 @@ xenDaemonDomainMigratePerform (virDomainPtr domain, * "hostname", "hostname:port" or "xenmigr://hostname[:port]/". */ if (strstr (uri, "//")) { /* Full URI. */ - xmlURIPtr uriptr = xmlParseURI (uri); + virURIPtr uriptr = virURIParse (uri); if (!uriptr) { virXendError(VIR_ERR_INVALID_ARG, "%s", _("xenDaemonDomainMigrate: invalid URI")); diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index eee67b5a17..3f0b63d6ab 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -18,13 +18,13 @@ # include # include -# include # include "internal.h" # include "capabilities.h" # include "domain_conf.h" # include "driver.h" # include "buf.h" +# include "viruri.h" int xenDaemonOpen_unix(virConnectPtr conn, const char *path); diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index f877f671fb..94644ae025 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include "internal.h" @@ -37,6 +36,7 @@ #include "uuid.h" #include "memory.h" #include "buf.h" +#include "viruri.h" #include "xenapi_driver.h" #include "xenapi_driver_private.h" #include "xenapi_utils.h" diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c index ddc77366ae..943b6c0d24 100644 --- a/src/xenapi/xenapi_utils.c +++ b/src/xenapi/xenapi_utils.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "internal.h" #include "domain_conf.h" @@ -37,6 +36,7 @@ #include "buf.h" #include "logging.h" #include "qparams.h" +#include "viruri.h" #include "xenapi_driver_private.h" #include "xenapi_utils.h" @@ -94,7 +94,7 @@ xenapiUtil_RequestPassword(virConnectAuthPtr auth, const char *username, } int -xenapiUtil_ParseQuery(virConnectPtr conn, xmlURIPtr uri, int *noVerify) +xenapiUtil_ParseQuery(virConnectPtr conn, virURIPtr uri, int *noVerify) { int result = 0; int i; diff --git a/src/xenapi/xenapi_utils.h b/src/xenapi/xenapi_utils.h index 40506d5c37..aa1ff740d0 100644 --- a/src/xenapi/xenapi_utils.h +++ b/src/xenapi/xenapi_utils.h @@ -23,9 +23,9 @@ # define __VIR_XENAPI_UTILS__ # include -# include # include # include "internal.h" +# include "viruri.h" # include "domain_conf.h" # define NETWORK_DEVID_SIZE (12) @@ -40,7 +40,7 @@ xenapiUtil_RequestPassword(virConnectAuthPtr auth, const char *username, const char *hostname); int -xenapiUtil_ParseQuery(virConnectPtr conn, xmlURIPtr uri, int *noVerify); +xenapiUtil_ParseQuery(virConnectPtr conn, virURIPtr uri, int *noVerify); enum xen_on_normal_exit actionShutdownLibvirt2XenapiEnum(enum virDomainLifecycleAction action);