예제 #1
0
        public void TestDomainSlice()
        {
            var actual   = new Domain("foo.example.com");
            var expected = new Domain("example.com");

            Assert.That(actual.Slice(1), Is.EqualTo(expected));
        }
예제 #2
0
파일: Domain.cs 프로젝트: adamnew123456/DNS
        /**
         * Returns true if the given Domain is below the current domain (i.e
         * they share a common suffix)
         */
        public bool IsSubdomain(Domain other)
        {
            var prefix_length = other.Length - this.Length;
            var other_tail    = other.Slice(prefix_length);

            return(other_tail == this);
        }
예제 #3
0
        /**
         * Converts a standard domain name into a series of bytes, possibly
         * compressed using domains seen so far.
         */
        public byte[] SerializeDomain(Domain domain)
        {
            var stream = new MemoryStream();

            if (domain[domain.Length - 1] != "")
            {
                throw new InvalidDataException("Domain name must end in 0 byte segment");
            }

            var idx = 0;

            foreach (var segment in domain)
            {
                Domain current_subdomain = domain.Slice(idx);

                // Avoid compressing on an empty domain, since it wastes a byte
                // of space and makes the decoder work harder for no reason
                if (segment != "" &&
                    domains_seen.ContainsKey(current_subdomain))
                {
                    // RFC specifies that top-2 bits must be 1
                    UInt16 compress_bits = (1 << 15) + (1 << 14);
                    UInt16 offset_bits   = domains_seen[current_subdomain];
                    UInt16 compress_ptr  = (UInt16)(compress_bits | offset_bits);
                    stream.WriteByte((byte)((compress_ptr >> 8) & 0xff));
                    stream.WriteByte((byte)(compress_ptr & 0xff));
                    MoveForward(2);
                    break;
                }
                else
                {
                    // Record the current domain for later compression, and
                    // then write it out (but only if it'll fit into the
                    // 14 bits we have to store the pointer in)
                    if (offset <= (1 << 14) - 1)
                    {
                        domains_seen[current_subdomain] = offset;
                    }

                    var segment_bytes = new byte[segment.Length];
                    for (int i = 0; i < segment.Length; i++)
                    {
                        segment_bytes[i] = (byte)segment[i];
                    }

                    stream.WriteByte((byte)segment_bytes.Length);
                    stream.Write(segment_bytes, 0, segment_bytes.Length);
                    MoveForward((UInt16)(1 + segment_bytes.Length));
                    idx++;
                }
            }

            return(stream.ToArray());
        }