[PATCH 1/2] Network: Add TXT record support for virtual DNS service

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
this is the patch to add support for adding TXT records to the
DNS service running on the virtual network. This has been tested
on Fedora-14 i386 box and tests are also added to RelaxNG schema
and test XML files.

It's been tested and checked/syntax-checked and everything was
working fine.

Also, the formatnetwork HTML document has been altered to
include those information about new DNS tag.

Michal

Signed-off-by: Michal Novotny <minovotn@xxxxxxxxxx>
---
 docs/formatnetwork.html.in                         |   26 ++++++++-
 docs/schemas/network.rng                           |   12 ++++
 src/conf/network_conf.c                            |   65 ++++++++++++++++++++
 src/conf/network_conf.h                            |   16 +++++
 src/network/bridge_driver.c                        |   27 ++++++++
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 tests/networkxml2xmltest.c                         |    1 +
 8 files changed, 194 insertions(+), 1 deletions(-)
 create mode 100644 tests/networkxml2xmlin/nat-network-dns-txt-record.xml
 create mode 100644 tests/networkxml2xmlout/nat-network-dns-txt-record.xml

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index c6969eb..2d76d3d 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -108,7 +108,10 @@
       The final set of elements define the addresses (IPv4 and/or
       IPv6, as well as MAC) to be assigned to the bridge device
       associated with the virtual network, and optionally enable DHCP
-      services.
+      services. The network creation also supports the TXT record in
+      the DNS to expose some information to the guest using this
+      record. This feature could be used in the similar way like DKIM
+      uses TXT records of DNS to expose public key.
     </p>
 
     <pre>
@@ -120,6 +123,9 @@
             &lt;host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" /&gt;
             &lt;host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" /&gt;
           &lt;/dhcp&gt;
+          &lt;dns&gt;
+            &lt;txt-record name="example name" value="example value" /&gt;
+          &lt;/dns&gt;
         &lt;/ip&gt;
       &lt;/network&gt;</pre>
 
@@ -199,6 +205,24 @@
         element is used.  The BOOTP options currently have to be the same
         for all address ranges and statically assigned addresses.<span
         class="since">Since 0.7.1 (<code>server</code> since 0.7.3).</span>
+      </dd><dt><code>dns</code></dt><dd>Also within the <code>ip</code> element
+        there is an optional <code>dns</code> element. The presence of this element
+        enables configuration and exposal of records in the DNS service on the
+        virtual network. It will further contain one or more <code>txt-record</code>
+        elements. The <code>dns</code> element is supported for both IPv4 and IPv6
+        networks. <span class="since">Since 0.9.0</span>
+      </dd>
+      <dt><code>txt-record</code></dt>
+      <dd>The <code>txt-record</code> element is the definition of TXT record for the
+        DNS service. There are two attributes that both have to be used for the TXT
+        record definition: <code>name</code> and <code>value</code>. The <code>name
+        </code>attribute doesn't support commas in it's value and therefore you should
+        avoid using them since they are automatically replaced by spaces, e.g. <code>
+        name, clarification</code> value of the <code>name</code> tag will be replaced
+        to be <code>name clarification</code> instead. This rule doesn't apply to the
+        record <code>value</code> contents since it supports multiple values separated
+        by commas.
+        <span class="since">Since 0.9.0</span>
       </dd>
     </dl>
 
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 6d01b06..e27dace 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -136,6 +136,18 @@
                 </optional>
               </element>
             </optional>
+            <optional>
+              <!-- Define the DNS related elements like TXT records
+                   and other features -->
+              <element name="dns">
+                <zeroOrMore>
+                  <element name="txt-record">
+                    <attribute name="name"><text/></attribute>
+                    <attribute name="value"><text/></attribute>
+                  </element>
+                </zeroOrMore>
+              </element>
+            </optional>
           </element>
         </zeroOrMore>
       </interleave>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index dcab9de..145ae20 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -435,6 +435,54 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
 }
 
 static int
+virNetworkDNSDefParseXML(virNetworkIpDefPtr def,
+                         xmlNodePtr node)
+{
+
+    xmlNodePtr cur;
+    int result = -1;
+
+    if (VIR_ALLOC(def->dns))
+        goto oom_error;
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "txt-record")) {
+            char *name, *value;
+
+            if (!(name = virXMLPropString(cur, "name"))) {
+                cur = cur->next;
+                continue;
+            }
+            if (!(value = virXMLPropString(cur, "value"))) {
+                VIR_FREE(name);
+                cur = cur->next;
+                continue;
+            }
+
+            if (VIR_REALLOC_N(def->dns->txtrecords, def->dns->ntxtrecords + 1) < 0)
+                goto oom_error;
+
+            def->dns->txtrecords[def->dns->ntxtrecords].name = strdup(name);
+            def->dns->txtrecords[def->dns->ntxtrecords].value = strdup(value);
+            def->dns->ntxtrecords++;
+
+            VIR_FREE(name);
+            VIR_FREE(value);
+        }
+
+        cur = cur->next;
+    }
+
+    return 0;
+
+oom_error:
+    virReportOOMError();
+    return result;
+}
+
+static int
 virNetworkIPParseXML(const char *networkName,
                      virNetworkIpDefPtr def,
                      xmlNodePtr node,
@@ -550,6 +598,12 @@ virNetworkIPParseXML(const char *networkName,
                     goto error;
 
             } else if (cur->type == XML_ELEMENT_NODE &&
+                       xmlStrEqual(cur->name, BAD_CAST "dns")) {
+                result = virNetworkDNSDefParseXML(def, cur);
+                if (result)
+                    goto error;
+
+            } else if (cur->type == XML_ELEMENT_NODE &&
                        xmlStrEqual(cur->name, BAD_CAST "tftp")) {
                 char *root;
 
@@ -828,6 +882,17 @@ virNetworkIpDefFormat(virBufferPtr buf,
 
         virBufferAddLit(buf, "    </dhcp>\n");
     }
+    if ((def->dns != NULL) && (def->dns->ntxtrecords)) {
+        int ii;
+
+        virBufferAddLit(buf, "    <dns>\n");
+        for (ii = 0 ; ii < def->dns->ntxtrecords ; ii++) {
+            virBufferVSprintf(buf, "      <txt-record name='%s' value='%s' />\n",
+                              def->dns->txtrecords[ii].name,
+                              def->dns->txtrecords[ii].value);
+        }
+        virBufferAddLit(buf, "    </dns>\n");
+    }
 
     virBufferAddLit(buf, "  </ip>\n");
 
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 281124b..5f47595 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -57,6 +57,20 @@ struct _virNetworkDHCPHostDef {
     virSocketAddr ip;
 };
 
+typedef struct _virNetworkDNSTxtRecordsDef virNetworkDNSTxtRecordsDef;
+typedef virNetworkDNSTxtRecordsDef *virNetworkDNSTxtRecordsDefPtr;
+struct _virNetworkDNSTxtRecordsDef {
+    char *name;
+    char *value;
+};
+
+struct virNetworkDNSDef {
+    unsigned int ntxtrecords;
+    virNetworkDNSTxtRecordsDefPtr txtrecords;
+} virNetworkDNSDef;
+
+typedef struct virNetworkDNSDef *virNetworkDNSDefPtr;
+
 typedef struct _virNetworkIpDef virNetworkIpDef;
 typedef virNetworkIpDef *virNetworkIpDefPtr;
 struct _virNetworkIpDef {
@@ -75,6 +89,8 @@ struct _virNetworkIpDef {
     unsigned int nranges;        /* Zero or more dhcp ranges */
     virNetworkDHCPRangeDefPtr ranges;
 
+    virNetworkDNSDefPtr dns;     /* DNS related settings for DNSMasq */
+
     unsigned int nhosts;         /* Zero or more dhcp hosts */
     virNetworkDHCPHostDefPtr hosts;
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ea2bfd4..5d901ff 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -442,6 +442,18 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
     return 0;
 }
 
+static char *
+replace_all(char *input, int chr1, int chr2)
+{
+    char *tmp;
+    char *out;
+
+    out = strdup(input);
+    while ((tmp = strchr(out, chr1)) != NULL)
+        out[ strlen(input) - strlen(tmp) ] = chr2;
+
+    return out;
+}
 
 static int
 networkBuildDnsmasqArgv(virNetworkObjPtr network,
@@ -497,6 +509,21 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
     if (network->def->forwardType == VIR_NETWORK_FORWARD_NONE)
         virCommandAddArg(cmd, "--dhcp-option=3");
 
+    if (ipdef->dns != NULL) {
+        int i;
+
+        for (i = 0; i < ipdef->dns->ntxtrecords; i++) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+            virBufferVSprintf(&buf, "%s,%s",
+                              replace_all(ipdef->dns->txtrecords[i].name, ',', ' '),
+                              ipdef->dns->txtrecords[i].value);
+
+            virCommandAddArgPair(cmd, "--txt-record", virBufferContentAndReset(&buf));
+            VIR_FREE(buf);
+        }
+    }
+
     /*
      * --interface does not actually work with dnsmasq < 2.47,
      * due to DAD for ipv6 addresses on the interface.
diff --git a/tests/networkxml2xmlin/nat-network-dns-txt-record.xml b/tests/networkxml2xmlin/nat-network-dns-txt-record.xml
new file mode 100644
index 0000000..d3cdbd5
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-txt-record.xml
@@ -0,0 +1,24 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0' />
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254' />
+      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+    </dhcp>
+    <dns>
+      <txt-record name='example name' value='example value' />
+    </dns>
+  </ip>
+  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+  </ip>
+  <ip family='ipv4' address='10.24.10.1'>
+  </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-dns-txt-record.xml b/tests/networkxml2xmlout/nat-network-dns-txt-record.xml
new file mode 100644
index 0000000..d3cdbd5
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-txt-record.xml
@@ -0,0 +1,24 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0' />
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254' />
+      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+    </dhcp>
+    <dns>
+      <txt-record name='example name' value='example value' />
+    </dns>
+  </ip>
+  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+  </ip>
+  <ip family='ipv4' address='10.24.10.1'>
+  </ip>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 7805548..beb00ef 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -90,6 +90,7 @@ mymain(int argc, char **argv)
     DO_TEST("nat-network");
     DO_TEST("netboot-network");
     DO_TEST("netboot-proxy-network");
+    DO_TEST("nat-network-dns-txt-record");
 
     return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
-- 
1.7.3.2

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]