示例#1
0
        public void DnsSerialization_NameCompression()
        {
            DnsMessage message = new DnsMessage();
            Dictionary <string, int> namePtrs = new Dictionary <string, int>();
            int offset;

            byte[] packet;
            string name;

            message.SetNamePtrs(namePtrs);

            // Verify that labels greater than 63 characters throw
            // an exception.

            try
            {
                namePtrs.Clear();
                packet = new byte[512];
                offset = 0;
                message.WriteName(packet, ref offset, new String('a', 64) + ".com.");
                Assert.Fail("Exception expected");
            }
            catch
            {
            }

            // Verify that zero length internal labels throw
            // an exception.

            try
            {
                namePtrs.Clear();
                packet = new byte[512];
                offset = 0;
                message.WriteName(packet, ref offset, "test..com.");
                Assert.Fail("Exception expected");
            }
            catch
            {
            }

            // Verify that relative domain names throw an exception.

            try
            {
                namePtrs.Clear();
                packet = new byte[512];
                offset = 0;
                message.WriteName(packet, ref offset, "test.com");
                Assert.Fail("Exception expected");
            }
            catch
            {
            }

            // Verify writing the root domain by itself.

            namePtrs.Clear();
            packet = new byte[512];
            offset = 0;
            message.WriteName(packet, ref offset, ".");
            Assert.AreEqual(1, offset);
            Assert.AreEqual(0, packet[0]);
            Assert.AreEqual(0, namePtrs.Count);

            // Verify writing a domain with a single label.

            namePtrs.Clear();
            packet = new byte[512];
            offset = 0;
            message.WriteName(packet, ref offset, "a.");
            Assert.AreEqual(3, offset);
            Assert.AreEqual(1, packet[0]);
            Assert.AreEqual('a', (char)packet[1]);
            Assert.AreEqual(0, packet[2]);
            Assert.AreEqual(1, namePtrs.Count);
            Assert.AreEqual(0, namePtrs["a"]);

            // Verify writing a domain with a three labels.

            namePtrs.Clear();
            packet = new byte[512];
            offset = 0;
            message.WriteName(packet, ref offset, "a.b.c.");
            Assert.AreEqual(7, offset);
            Assert.AreEqual(1, packet[0]);
            Assert.AreEqual('a', (char)packet[1]);
            Assert.AreEqual(1, packet[2]);
            Assert.AreEqual('b', (char)packet[3]);
            Assert.AreEqual(1, packet[4]);
            Assert.AreEqual('c', (char)packet[5]);
            Assert.AreEqual(0, packet[6]);

            Assert.AreEqual(3, namePtrs.Count);
            Assert.AreEqual(0, namePtrs["a.b.c"]);
            Assert.AreEqual(2, namePtrs["b.c"]);
            Assert.AreEqual(4, namePtrs["c"]);

            // Write the entire three label domain and verify
            // that only a pointer is written.

            namePtrs.Clear();
            packet = new byte[512];
            offset = 0;
            message.WriteName(packet, ref offset, "a.b.c.");
            message.WriteName(packet, ref offset, "a.b.c.");
            Assert.AreEqual(9, offset);
            Assert.AreEqual(0xC0, packet[7]);
            Assert.AreEqual(0, packet[8]);

            // Verify that after writing "a.b.c." and then
            // writing "z.b.c." that a pointer is written
            // for the "b.c." portion.

            namePtrs.Clear();
            packet = new byte[512];
            offset = 0;
            message.WriteName(packet, ref offset, "a.b.c.");
            message.WriteName(packet, ref offset, "z.b.c.");
            Assert.AreEqual(11, offset);
            Assert.AreEqual(1, packet[7]);
            Assert.AreEqual('z', (char)packet[8]);
            Assert.AreEqual(0xC0, packet[9]);
            Assert.AreEqual(2, packet[10]);

            // Verify that we can read the two domains just written.

            offset = 0;
            message.ReadName(packet, ref offset, out name);
            Assert.AreEqual("a.b.c.", name);
            message.ReadName(packet, ref offset, out name);
            Assert.AreEqual("z.b.c.", name);
        }