title: Sockets programming: DIG DNS Query Messages: Incorrect header length?
body: <h1>RFC Reference</h1>
  <p>I am working on a project which involves sockets programming and interpreting the output from DIG DNS queries.</p>
  <p>I'm using RFC 1035 as my reference. Although this is quite old now (1987) as far as I can tell from later RFCs (for example 8490) the DNS headers are still the same.</p>
  <p><a href="https://www.rfc-editor.org/rfc/rfc1035" rel="nofollow noreferrer">https://www.rfc-editor.org/rfc/rfc1035</a></p>
  <h1>Code Overview: IPv6 TCP query</h1>
  <p>I have written a short program in C which reads from a IPv6 TCP socket. I send data to this socket using DIG. (My program simply reads all data it sees on a socket, and prints it to <code>stdout</code>.)</p>
  <p>Note that there are two unusual things here:</p>
  <ul>
  <li>Firstly the use of IPv6</li>
  <li>Secondly the use of TCP (DNS messages are often UDP)</li>
  </ul>
  <p>Here is the command used:</p>
  <pre><code>dig @::1 -p 8053 duckduckgo.com +tcp
  </code></pre>
  <p>I am running dig version <code>DiG 9.16.13-Debian</code>, on Debian Testing. (cera 2021-May)</p>
  <h1>Output, Discussion and Question</h1>
  <p>Here is the hexadecimal and printable character output which is read from the socket:</p>
  <pre><code>Hex:
  00 37 61 78 01 20 00 01 00 00 00 00 00 01 0A 64 75 63 6B 64 75 63 6B 67 6F 03 63 6F 6D 00 00 01 00 01 00 00 29 10 00 00 00 00 00 00 0C 00 0A 00 08 00 7A 4* 48 2C 16 0* 33 
  Char:
  00  7 61  x 01 20 00 01 00 00 00 00 00 01 0A  d  u  c  k  d  u  c  k  g  o 03  c  o  m 00 00 01 00 01 00 00  ) 10 00 00 00 00 00 00 0C 00 0A 00 08 00  z 4*  H  , 16 0* 33 
  </code></pre>
  <p>If non-printable characters are encountered, the hex value is printed instead.</p>
  <p>Although this is a fairly long stream of data, the question relates to the length of the header.</p>
  <hr />
  <p>According to RFC 1035, the length of the header should be 12 bytes.</p>
  <pre><code>4.1.1. Header section format
  
  The header contains the following fields:
  
                                      1  1  1  1  1  1
        0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |                      ID                       |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |                    QDCOUNT                    |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |                    ANCOUNT                    |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |                    NSCOUNT                    |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
      |                    ARCOUNT                    |
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  </code></pre>
  <p>The header is followed by a <code>QUESTION SECTION</code>. The question section begins with a single byte which specifies the length.</p>
  <hr />
  <p>Inspecting the data stream above, we see that the byte at offset 12 has a value of 0. I repeat it below with offset numbers to make it clear. The data is in the <em>middle row</em>, the row above and below are <em>byte offsets</em>.</p>
  <pre><code> 0  1  2  3  4  5  6  7  8  9 10 11 &lt;- byte 12
  00 37 61 78 01 20 00 01 00 00 00 00 00 01 0A 64 75 63 6B ...
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 &lt;- byte 15
  </code></pre>
  <p>This clearly doesn't make any sense.</p>
  <p>Looking again at the stream, we can see that &quot;duckduckgo&quot; is preceeded by the byte <code>0A</code>. This is 10 in decimal and corresponds to the 10 characters of &quot;duckduckgo&quot;. This string is followed by a byte <code>03</code> which corresponds to the 3 bytes of &quot;com&quot;.</p>
  <p>The offset of the byte <code>0A</code> is 15. <em>Not 12</em>.</p>
  <p>I must have misunderstood the RFC specification. But what have I misunderstood? Does the header itself start at a different offset to what I think it is? (Byte zero.) Or is there perhaps some padding between the end of the header and the beginning of the first question section?</p>
  <h1>Existing Question on this site:</h1>
  <p>Comments: The below link states that <em>there is no padding</em>. This is the only answer on this question. The question is about <em>DNS responses rather than queries</em>, and does not ask about the header section of a query. (Although information from one should presumably apply to the other, but possibly does not.)</p>
  <p><a href="https://stackoverflow.com/questions/45858512/do-dns-messages-pad-names-to-an-even-number-of-bytes">Do DNS messages pad names to an even number of bytes?</a></p>
  <p>Comments: The below link asks about the best way to build a data structure to handle DNS data. Additionally, the answer notes that one has to be careful about network byte order and machine byte order. I am already aware of this and I use <code>ntohs()</code> to convert from network byte order to <code>x86_64</code> byte order before printing information to <code>stdout</code>. This is not the problem and does not explain why I see information about the dns query starting at byte 15 instead of 12, when the header should be a fixed size of 12 bytes.</p>
  <p><a href="https://stackoverflow.com/questions/26717644/implementing-a-dns-query-in-c-according-to-rfc-1035">Implementing a DNS Query in c++ according to RFC 1035</a></p>