Signed-off-by: Shi Lei <shi_lei(a)massclouds.com>
---
docs/schemas/network.rng | 13 ++-
src/conf/network_conf.c | 218 +++++++++++++++++++++++++--------------
2 files changed, 152 insertions(+), 79 deletions(-)
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index c902f7e..14561d9 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -302,7 +302,18 @@
<zeroOrMore>
<!-- VIRT:DIRECTIVE {
"structure": {"output":
"src/conf/network_conf"},
- "clearfunc": {"output":
"src/conf/network_conf"}
+ "clearfunc": {"output":
"src/conf/network_conf"},
+ "parsefunc": {
+ "post": true,
+ "args.instname": true,
+ "args": [
+ {"name": "partialOkay", "type":
"Bool"}
+ ]
+ },
+ "members": [
+ {"id": "service", "opt": true},
+ {"id": "protocol", "opt": true}
+ ]
} -->
<element name="srv">
<attribute
name="service"><text/></attribute>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 6f0722a..3913cb4 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -214,6 +214,123 @@ virNetworkDefFree(virNetworkDefPtr def)
}
+/* This includes all characters used in the names of current
+ * /etc/services and /etc/protocols files (on Fedora 20), except ".",
+ * which we can't allow because it would conflict with the use of "."
+ * as a field separator in the SRV record, there appears to be no way
+ * to escape it in, and the protocols/services that use "." in the
+ * name are obscure and unlikely to be used anyway.
+ */
+#define PROTOCOL_CHARS \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
+ "-+/"
+
+#define SERVICE_CHARS \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
+ "_-+/*"
+
+static int
+virNetworkDNSSrvDefParseXMLPost(xmlNodePtr curnode G_GNUC_UNUSED,
+ virNetworkDNSSrvDefPtr def,
+ xmlXPathContextPtr ctxt G_GNUC_UNUSED,
+ const char *networkName,
+ bool partialOkay,
+ const char *serviceStr G_GNUC_UNUSED,
+ const char *protocolStr G_GNUC_UNUSED,
+ const char *domainStr G_GNUC_UNUSED,
+ const char *targetStr G_GNUC_UNUSED,
+ bool has_port,
+ bool has_priority,
+ bool has_weight)
+{
+ if (!def->service && !partialOkay) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("missing required service attribute in DNS SRV record
"
+ "of network '%s'"), networkName);
+ return -1;
+ }
+ if (def->service) {
+ if (strlen(def->service) > DNS_RECORD_LENGTH_SRV) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("service attribute '%s' in network '%s'
is too long, "
+ "limit is %d bytes"),
+ def->service, networkName, DNS_RECORD_LENGTH_SRV);
+ return -1;
+ }
+ if (strspn(def->service, SERVICE_CHARS) < strlen(def->service)) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid character in service attribute '%s'
"
+ "in DNS SRV record of network '%s'"),
+ def->service, networkName);
+ return -1;
+ }
+ }
+
+ if (!def->protocol && !partialOkay) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("missing required protocol attribute "
+ "in DNS SRV record '%s' of network
'%s'"),
+ def->service, networkName);
+ return -1;
+ }
+ if (def->protocol &&
+ strspn(def->protocol, PROTOCOL_CHARS) < strlen(def->protocol)) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid character in protocol attribute '%s'
"
+ "in DNS SRV record of network '%s'"),
+ def->protocol, networkName);
+ return -1;
+ }
+
+ if (has_port && !def->target) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("DNS SRV port attribute not permitted without "
+ "target for service '%s' in network
'%s'"),
+ def->service, networkName);
+ return -1;
+ }
+ if (has_port && (def->port < 1 || def->port > 65535)) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid DNS SRV port attribute "
+ "for service '%s' in network '%s'"),
+ def->service, networkName);
+ return -1;
+ }
+
+ if (has_priority && !def->target) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("DNS SRV priority attribute not permitted without "
+ "target for service '%s' in network
'%s'"),
+ def->service, networkName);
+ return -1;
+ }
+ if (has_priority && def->priority > 65535) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("Invalid DNS SRV priority attribute "
+ "for service '%s' in network '%s'"),
+ def->service, networkName);
+ return -1;
+ }
+
+ if (has_weight && !def->target) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("DNS SRV weight attribute not permitted without "
+ "target for service '%s' in network
'%s'"),
+ def->service, networkName);
+ return -1;
+ }
+ if (has_weight && def->weight > 65535) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid DNS SRV weight attribute "
+ "for service '%s' in network '%s'"),
+ def->service, networkName);
+ return -1;
+ }
+
+ return 0;
+}
+
+
/*
* virNetworkDefCopy:
* @def: NetworkDef to copy
@@ -594,21 +711,7 @@ virNetworkDNSHostDefParseXMLPost(xmlNodePtr curnode G_GNUC_UNUSED,
}
-/* This includes all characters used in the names of current
- * /etc/services and /etc/protocols files (on Fedora 20), except ".",
- * which we can't allow because it would conflict with the use of "."
- * as a field separator in the SRV record, there appears to be no way
- * to escape it in, and the protocols/services that use "." in the
- * name are obscure and unlikely to be used anyway.
- */
-#define PROTOCOL_CHARS \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
- "-+/"
-
-#define SERVICE_CHARS \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
- "_-+/*"
-
+/* virNetworkDNSSrvDefParseXML will be replaced by generated namesake */
static int
virNetworkDNSSrvDefParseXML(const char *networkName,
xmlNodePtr node,
@@ -617,62 +720,23 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
bool partialOkay)
{
int ret;
+ bool has_port = false;
+ bool has_priority = false;
+ bool has_weight = false;
xmlNodePtr save_ctxt = ctxt->node;
-
ctxt->node = node;
- if (!(def->service = virXMLPropString(node, "service")) &&
!partialOkay) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("missing required service attribute in DNS SRV record
"
- "of network '%s'"), networkName);
- goto error;
- }
- if (def->service) {
- if (strlen(def->service) > DNS_RECORD_LENGTH_SRV) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("service attribute '%s' in network '%s'
is too long, "
- "limit is %d bytes"),
- def->service, networkName, DNS_RECORD_LENGTH_SRV);
- goto error;
- }
- if (strspn(def->service, SERVICE_CHARS) < strlen(def->service)) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("invalid character in service attribute '%s'
"
- "in DNS SRV record of network '%s'"),
- def->service, networkName);
- goto error;
- }
- }
-
- if (!(def->protocol = virXMLPropString(node, "protocol")) &&
!partialOkay) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("missing required protocol attribute "
- "in DNS SRV record '%s' of network
'%s'"),
- def->service, networkName);
- goto error;
- }
- if (def->protocol &&
- strspn(def->protocol, PROTOCOL_CHARS) < strlen(def->protocol)) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("invalid character in protocol attribute '%s'
"
- "in DNS SRV record of network '%s'"),
- def->protocol, networkName);
- goto error;
- }
+ def->service = virXMLPropString(node, "service");
+ def->protocol = virXMLPropString(node, "protocol");
/* Following attributes are optional */
def->domain = virXMLPropString(node, "domain");
def->target = virXMLPropString(node, "target");
ret = virXPathUInt("string(./@port)", ctxt, &def->port);
- if (ret >= 0 && !def->target) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("DNS SRV port attribute not permitted without "
- "target for service '%s' in network
'%s'"),
- def->service, networkName);
- goto error;
- }
- if (ret == -2 || (ret >= 0 && (def->port < 1 || def->port >
65535))) {
+ if (ret >= 0) {
+ has_port = true;
+ } else if (ret == -2) {
virReportError(VIR_ERR_XML_DETAIL,
_("invalid DNS SRV port attribute "
"for service '%s' in network '%s'"),
@@ -681,14 +745,9 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
}
ret = virXPathUInt("string(./@priority)", ctxt, &def->priority);
- if (ret >= 0 && !def->target) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("DNS SRV priority attribute not permitted without "
- "target for service '%s' in network
'%s'"),
- def->service, networkName);
- goto error;
- }
- if (ret == -2 || (ret >= 0 && def->priority > 65535)) {
+ if (ret >= 0) {
+ has_priority = true;
+ } else if (ret == -2) {
virReportError(VIR_ERR_XML_DETAIL,
_("Invalid DNS SRV priority attribute "
"for service '%s' in network '%s'"),
@@ -697,14 +756,9 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
}
ret = virXPathUInt("string(./@weight)", ctxt, &def->weight);
- if (ret >= 0 && !def->target) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("DNS SRV weight attribute not permitted without "
- "target for service '%s' in network
'%s'"),
- def->service, networkName);
- goto error;
- }
- if (ret == -2 || (ret >= 0 && def->weight > 65535)) {
+ if (ret >= 0) {
+ has_weight = true;
+ } else if (ret == -2) {
virReportError(VIR_ERR_XML_DETAIL,
_("invalid DNS SRV weight attribute "
"for service '%s' in network '%s'"),
@@ -712,6 +766,14 @@ virNetworkDNSSrvDefParseXML(const char *networkName,
goto error;
}
+ if (virNetworkDNSSrvDefParseXMLPost(node, def, ctxt,
+ networkName, partialOkay,
+ def->service, def->protocol,
+ def->domain, def->target,
+ has_port, has_priority,
+ has_weight) < 0)
+ goto error;
+
ctxt->node = save_ctxt;
return 0;
--
2.17.1