0. Введение
В этом документе описан протокол, применяемый для коммуникаций с ANDNA. Протокол используется для запросов в сфере internet. Например, можно запросить google.it в internet или depausceve в сети netsukuku.
В случае запросов internet элемент dns_wrapper будет взаимодействовать с серверами dns, заданными в файле /etc/resolv.conf, когда модуль ntkd загружен.
1. Обозначения
Далее на рисунках байты представляются в виде
1 2 3 4 5 6 7 8 +--+--+--+--+--+--+--+--+ | | +--+--+--+--+--+--+--+--+
Числа указывают номера битов. Двухбайтовое слово представляется в форме
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
2. Заголовки
Заголовки имеют размер 4 байта и показанный на рисунке формат
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| P| Z| QT | ANCOUNT |I | NK| RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
ID
Двухбайтовый идентификатор запроса. Значение ID выбирается случайным образом и в ответах должно применяться то же значение ID.
R
Бит рекурсии, при установке которого запросы SNSD, имеющие имя хоста в качестве распознавания, будут распознаваться (если это возможно).
QR
0 для вопросов, 1 для ответов.
P
Если запрос является h2ip и связан с ntk, P задает протокол: 0 для TCP, 1 для UDP и 0 в остальных случаях.
Z
Сжатие zlib. При z=1 содержимое пакета (кроме заголовков) сжимается с помощью zlib (см. 8. Сжатие).
QT
Тип запроса (см. 3. Типы запросов). В откликах это поле должно сохраняться неизменным.
ANCOUNT
Счетчик ответов. Поле устанавливается только при QR=1 (пакет содержит ответы) и указывает число ответов в этом пакете.
I
Бит версии IP, использованной для содержимого пакета. Все адреса в пакете являются IPv4 (4 байта), если I=0 и IPv6 (16 байтов), если I=1. Этот бит полезен лишь в вопросах. Сервер будет возвращать ответ NO SUCH DOMAIN (нет такого домена), если на его узле применяется иная версия протокола IP. При совпадении версий в ответе будет использоваться та же версия протокола.
NK
Биты Netsukuku, позволяющий задать область запроса (query realm). При NK=1 областью запроса является netsukuku, при NK=2 – internet. Значение NK=0 указывает, что пакет не кодируется данным протоколом и содержит обычный протокол DNS (см. 4. Область запроса). В ответах это поле должно сохраняться.
RCODE
Результат запроса. Для пакетов с вопросами устанавливается RCODE = 0. В случае ошибок устанавливается ANCOUNT = 0.
3. Типы запросов
Имеется несколько типов запросов.
QTYPE = 0
Это классическое преобразование hostname -> ip (gethostbyname). Этот тип запросов применяется также для распознавания SNSD [1]. Можно указать сервис и общая форма представления такого запроса имеет вид
hostname:service -> ip
Если сервис не указан, будет применяться 0-service.
Например, если нужно найти адрес хостинга сервиса http хоста depausceve, запрос может иметь вид
depausceve:80
Формирование запросов описано в 6. Вопросы.
QTYPE = 1
Обратное преобразование ip -> host.
QTYPE =2
Глобальный запрос для всех служб указанного хоста. Областью запроса является Ntk.
4. Область запроса
Запрос можно сформулировать для поиска того или иного объекта в сети netsukuku или internet. При использовании протокола ANDNS область запроса указывается битами NK (см. 2. Заголовки).
Если используется протокол DNS, нужно формулировать запрос с неким суффиксом. Если запрос сделан для google.it.int (или google.it.INT), он будет относиться к internet. Запрос google.it.ntk (или google.it.NTK) будет относиться к сети netsukuku. Если суффикс не задан, по умолчанию областью запроса служит Netsukuku
Элемент dns_wrapper сначала определяет суффикс для корректного выбора области запроса. Найденный суффикс удаляется и запрос выполняется в соответствующей области.
5. RCODE
Это поле содержит код результата выполнения запроса. В пакетах с вопросом поле всегда имеет значение 0. Возможные коды в ответах перечислены ниже.
RCODE = 0 No Error
Пакет содержит ответы (ANSWERS), число которых указывается полем ANCOUNT (см. 2. Заголовки).
RCODE = 1 Interpretation Error
Сервер не понял запроса (запрос сформирован некорректно).
RCODE = 2 Server Fail
Сервер столкнулся с ошибкой при обработке корректного запроса.
RCODE = 3 No Such Domain
Искомого объекта не существует.
RCODE = 4 Not Implemented
Данный тип запросов не реализован на этом сервере.
RCODE = 5 Refused
Сервер отказывается взаимодействовать с вами.
Отметим, что выражение (RCODE XOR ANCOUNT) всегда истинно. Если RCODE содержит ту или иную ошибку (RCODE!=0), в пакете не будет ответа. Если же RCODE = 0 (нет ошибок), пакет содержит тот или иной ответ.
6. Вопросы
Формат вопроса зависит от QTYPE.
Case QTYPE = 0 (h2ip) и Realm=NTK
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERVICE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | | | | | HOSTNAME | | HASH | | (HH) | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
SERVICE – 2-байтовое поле, представляющее значение сервиса SNSD [1].
HH – 16-байтовое хэш-значение имени хоста (hostname).
QTYPE = 0 (h2ip) и Realm=INET
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERVICE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | RDLENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | \ \ \ RDATA \ | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
SERVICE – 2-байтовое поле, представляющее значение сервиса SNSD [1]. В данный момент для преобразований INET сервис ограничен значением 25 (предполагается TCP) или 0.
RDLENGTH – размер RDATA.
RDATA – строка имени хоста с учетом strlen(RDATA)=RDLENGTH.
QTYPE = 1 (ip2h)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / RDATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
RDATA – адрес IP в двоичном формате. Размер поля (4 или 16 байтов) зависит от поля I в заголовке.
QTYPE = 2 (глобальный запрос)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | | | | | HOSTNAME | | HASH | | (HH) | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
HH – 16-байтовое хэш-значение имени хоста (hostname).
7. Ответы
QTYPE=0 (h2ip)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | T| WG | PRIO | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / RDATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Бит T устанавливается (1), если ответ содержит IP. T = 0 говорит о том, что ответ содержит хэш hostname.
WG указывает «вес» ответа [1].
PRIO – приоритет [1].
RDATA содержит двоичный адрес IP, размер которого определяется битом I в заголовке, или хэш hostname.
QTYPE=1 (ip2h)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | RDLENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / RDATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
RDLENGTH – размер RDATA (RDATA – имя хоста).
RDATA – распознанное имя хоста.
QTYPE=2 (глобальный запрос)
При QTYPE=2 перед ответом помещается дополнительное поле заголовка
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Эти 2 байта указывают число ответов, порожденных запросом. Отметим, что поле ANCOUNT в основном заголовке будет иметь значение 1, если RCODE=0, и 0 в противном случае. Эти два байта указывают реальное число ответов для случая QTYPE=2.
После дополнительного заголовка размещаются ответы в показанном на рисунке формате.
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | M| T| P| WG | PRIO | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERVICE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / DATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Бит T указывает тип DATA (T для Hostname и 1 для IP).
Бит M устанавливается при установленном бите T и показывает, что это MAIN_IP для hostname.
P – протокол (0 для TCP, 1 для UDP).
При T=1 версия IP указывается в основном заголовке. Если T=0, данные имеют формат
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | | | | | HOSTNAME | | HASH | | (HH) | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
HH – 16-байтовое хэш-значение SNSD hostname.
При T=1 данные имеют показанный на рисунке формат
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / RDATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
RDATA – двоичное представление IP, размер которого зависит от бита I в основном заголовке (4 для IPv4, 16 для IPv6).
8. Сжатие
Формат сжатого пакета показан на рисунке.
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| P| Z| QT | ANCOUNT |I | NK| RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | USIZE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / DATA / / / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Заголовки остаются не сжатыми. Содержимое пакета, вопрос и ответы сжимаются с помощью zlib. Буфером, для сжатия является DATA. Поле USIZE показывает исходный размер содержимого пакета (вопрос и ответы). Для сжатого пакета устанавливается Z=1.
[1] NTC_RFC 0009 http://netsukuku.freaknet.org/main_doc/ntk_rfc/Ntk_SNSD
Перевод на русский язык
Николай Малых