Я хочу ответить на запрос CNAME на моем DNS-сервере node.js, и я хочу поместить свой раздел ответа в буфер ответа. Я пробовал этот буфер для раздела ответов и протестировал его с помощью модуля dig в Windows и получил следующий ответ:

    ;; Got bad packet: bad label type
    53 bytes
    0d c4 85 80 00 01 00 01 00 00 00 00 04 74 65 73          .............tes
    74 03 63 6f 6d 00 00 05 00 01 c0 0c 00 05 00 01          t.com...........
    00 00 00 00 00 0a 73 65 63 6f 6e 64 54 65 73 74          ......secondTest
    03 63 6f 6d 00                                           .com.

Я отправил этот буфер клиенту в качестве раздела ответа:

[170,254,133,128,0,1,0,1,0,0,0,0,4,116,101,115,116,3,99,111,109,0,0,5,0,1,192,12,0,5,0,1,0,0,0,0,0,10,115,101,99,111,110,100,84,101,115,116,3,99,111,109,0]

Я не могу понять, что в этом плохого?

0
sajad khosravi 21 Окт 2019 в 11:14

1 ответ

Лучший ответ

Если вы посмотрите исходный код раскопок на https://salsa.debian.org/dns-team/bind9/blob/debian/master/lib/dns/name.c вы увидите, что ошибка «неправильный тип метки» - DNS_R_BADLABELTYPE и происходит, только если байт имеет значение 91 10 или любое значение от 64 10 включительно до 192 10 , потому что все они обозначают проблемы при кодировании имени .

Из вашего буфера:

  • 0d c4, 16-битный идентификатор для идентификации сообщения
  • 85 80 равно 1 0000 1 0 1 1 000 0000, что означает:
    • 1: сообщение - это ответ
    • 0000: стандартный запрос
    • 1: AA, авторитетный ответ
    • 0: TC, НЕ усеченный
    • 1: RD, требуется рекурсия
    • 1: RA, доступна рекурсия
    • 000: Z, должно быть нулем.
    • 0000: RCODE, без ошибок
  • 00 01 QDCOUNT, 1 запись в разделе вопросов
  • 00 01 ANCOUNT, 1 запись в разделе ответов
  • 00 00 NSCOUNT, 0 записей в разделе полномочий
  • 00 00 ARCOUNT, 0 записей в дополнительном разделе

Теперь вопрос:

  • 04 метка размером 4 байта
  • 74 65 73 74, который равен test
  • 03 метка из 3 байтов
  • 63 6f 6d, который равен com
  • 00 метка из 0 байт, то есть корневая
  • 00 05 тип, CNAME
  • 00 01 класс, IN

А теперь входим в раздел ответов:

  • c0 0c означает указатель (для первого байта установлено 2 первых бита) на позицию 0c, которая равна 13 10 . В этой позиции мы снова находим test.com как 74 65 73 74 03 63 6f 6d 00
  • 00 05 тип, CNAME
  • 00 01 класс, IN,
  • 00 00 00 00 TTL, 0
  • 00 0a RDLENGTH, размер следующих данных, 10 байт
  • для типа записи CNAME RDATA, следующая за значением RDLENGTH, снова является именем
  • поэтому 10 байтов, которые необходимо принять во внимание, это 73 65 63 6f 6e 64 54 65 73 74, первые 1 или 2 байта должны быть размером или указателем, но 73 16 это 115 10 , следовательно, вы попадаете в описанную выше ситуацию, которая приводит к сообщению об ошибке, потому что байт начинается с 01 2 , а в RFC 1035 четко сказано: "(Комбинации 10 и 01 являются зарезервировано для использования в будущем.)

Если вы хотите test.com. 0 IN CNAME secondTest.com, это должно создать следующий буфер (без сжатия имени): 04 74 65 73 74 03 63 6f 6d 00 00 05 00 01 00 00 00 00 00 10 0a 73 65 63 6f 6e 64 74 65 73 74 03 63 6f 6d 00

Так что на самом деле вам нужно заменить 0,10,115,101,99,111,110,100,84,101,115,116,3,99,111,109,0 на 0,16,10,115,101,99,111,110,100,116,101,115,116,3,99,111,109,0

То есть вам не хватает первого байта 16. (позже разница между 84 и 116 будет в том, хотите ли вы T или t в первом t из secondTest)

0
Patrick Mevzek 22 Окт 2019 в 05:23