Ejemplo n.º 1
0
        public ICollection <ArraySegment <byte> > ReadLabels()
        {
            var result = new List <ArraySegment <byte> >(10);

            // read the length byte for the label, then get the content from offset+1 to length
            // proceed till we reach zero length byte.
            byte length;

            while ((length = ReadByte()) != 0)
            {
                // respect the reference bit and lookup the name at the given position
                // the reader will advance only for the 2 bytes read.
                if ((length & ReferenceByte) != 0)
                {
                    int subIndex = (length & 0x3f) << 8 | ReadByte();
                    if (subIndex >= _data.Array.Length - 1)
                    {
                        // invalid length pointer, seems to be actual length of a label which exceeds 63 chars...
                        // get back one and continue other labels
                        _index--;
                        result.Add(_data.SubArray(_index, length));
                        Advance(length);
                        continue;
                    }

                    var subReader = new DnsDatagramReader(_data.SubArrayFromOriginal(subIndex));
                    var newLabels = subReader.ReadLabels();
                    result.AddRange(newLabels); // add range actually much faster than concat and equal to or faster than for-each.. (array copy would work maybe)
                    return(result);
                }

                if (_index + length >= _count)
                {
                    throw new DnsResponseParseException(
                              "Found invalid label position.", _data.ToArray(), _index, length);
                }

                var label = _data.SubArray(_index, length);

                // maybe store original bytes in this instance too?
                result.Add(label);

                Advance(length);
            }

            return(result);
        }