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); }