Измерение пропускной способности

NTK_RFC 0002

Bandwidth measurement

Измерение пропускной способности

PDF

В этом документе описаны изменения протокола Npv7. Текст будет включен в окончательную документацию, а пока его можно изменять, контактируя с разработчиками.

Проблема измерения качества каналов

В текущей версии Npv7 радар (Radar) измеряет качество канала, используя лишь время кругового обхода rtt1 и потери пакетов. Это явно не оптимально, поскольку пропускная способность не учитывается и канал с малой пропускной способностью (например, 20 Кбит/с), но с небольшой задержкой окажется лучше широкополосного канала с умеренной задержкой.

Улучшение

Узел должен включать в пакеты трассировки (Tracer Packet) не только rtt пройденных каналов, но и текущую их пропускную способность (полосу). Это позволит формировать трафик с учетом реальной пропускной способности каналов.

Измерение пропускной способности

Измерение включает 2 фазы. В первой измеряется общая полоса новых каналов узлами перехвата и назначения, а вторая фаза обеспечивает постоянный мониторинг пропускной способности. Отслеживание используемой полосы выполняется с помощью библиотеки libpcap.

Общая доступная полоса

        A <--> B <--> C

Узел B «ловит» трафик между узлами A и C. В конце ловушки B измеряет общую доступную полосу каналов B—>C и B—>A. Имеются разные методы измерения пропускной способности каналов. Первый и простейший заключается в передаче неопределенного числа случайных пакетов в течение нескольких секунд по адресу получателя на канале. Скорость передачи контролируется с помощью libpcap и регистрируется максимальное число переданных в секунду байтов как доступнеая для выгрузки (upload) полоса данного канала. Этот метод очень эффективен и измеренная полоса является реальной, а не аппроксимированной. Побочным эффектом является полная загрузка канала на несколько секунд.

Другой вариант более изыскан и использует методы Packet Pair и Packet Train, описанные в http://perform.wpi.edu/downloads/wbest/README и http://www-static.cc.gatech.edu/fac/Constantinos.Dovrolis/bw.html.

Поскольку каналы могут быть асимметричными, измерения повторяются также для A—>B и C—>B. В результате будет получена пропускная способность каналов A->B, B->A, C->B, B->C.

Контроль полосы в реальном масштабе времени

С помощью библиотеки libpcap узел B может отслеживать использование полосы каналов.

Max_link_bw

Общая доступная пропускная способность канала.

nflows

Текущее число потоков в канале. Потоком считается множество (stream) пакетов, связанных с конкретным соединением.

Текущую доступную полосу канала можно аппроксимировать выражением

link_avail_bw   = Max_link_bw/(nflows+1)

Такая аппроксимация выбрана потому, что метод управления трафиком TCP похож на алгоритм max-min и при большом числе потоков link_avail_bw является хорошим приближением.

Если радар сообщает о значительных вариациях текущей доступной полосы, передается новый запрос QSPN.

Задержка rtt

Каждый узел сети будет задерживать пересылку полученного пакета Tracer (TP) на время, обратно пропорциональное link_avail_bw. Таким образом, пакеты TP будут приниматься для эффективности. Побочным эффектом этого правила является игнорирование крайних случаев, когда маршруты с очень низким значением rtt будут иметь очень малую полосу bw или маршруты с оптимальной полосой bw будут иметь обчень большое значение rtt. Однако в реальном мире такие ситуации достаточно редки, поскольку rtt и the зачастую связаны между собой.

Дополнительная информация об эффективности пакетов TP приведена в документе QSPN v2.

Пропускная способность маршрута

Пропускная способность маршрута из S в D обозначается bw(S -> D) и равна пропускной способности наихудшего канала в пути. Например, для маршрута

S --64Mb/s--> R --64Mb/s--> T --32Mb/s--> O --100Mb/s--> I --100Mb/s--> D

пропускная способность составит bw(S -> D) = 32 Мбит/с.

Пакет TP должен запомнить единственное значение пропускной способности (_one_ bw) и это будет bw() текущего маршрута. Например, если S передает TP, то по получении этого пакета узлом T, сохраненная в нем пропускная способность будет bw(S->R->T)=64, но при достижении узла O, она сменится на bw(S→R→T→O)=32.

Отметим, что каждое значение bw приблизительно соответствует доступной полосе соответствующего канала (link_avail_bw). Например, запись S —64Mb/s—> R показывает, что текущая пропускная способность канала S—>R составляет приблизительно 64 Мбит/с.

Асимметричные маршруты

QSPN v1 предоставляет каждому узлу наилучший маршрут загрузки трафика (download) с каждого другого узла. Рассмотрим в качестве примера узлы S и D.

       1:   ,--<-<-<---.
           /            \
         S                D
           \            / 
       2:   `-->->->---'

Маршруты типа 1 являются лучшими маршрутами выгрузки (upload) из D в S, а маршруты типа 2 — лучшими для противоположного направления. QSPN дает S только маршруты типа 1, а D знает только маршруты типа 2. Если маршруты не симметричны, S при выгрузке в D будет использовать маршрут типа 1, который может иметь низкую производительность.

Решение очень просто — S при выгрузке большого блока данных будет запрашивать у D его маршруты D->S (тип 2), т. е. лучшие маршруты выгрузки из S в D.

Демон Netsukuku, используя libpcap, будет отслеживать пакеты, исходящие от localhost. Если пакеты отправлялись более 16 секунд, демон будет запрашивать у целевого узла лучшие маршруты выгрузки (upload) и добавлять их в свою таблицу маршрутизации. Таким образом, маршруты выгрузки будут запрашиваться лишь при необходимости.

Отметим, что в QSPN v2 имеется встроенная поддержка асимметричной маршрутизации.

Задержка и полоса

Может возникнуть ситуация, когда канал с хорошей пропускной способностью имеет высокую задержку. Для некоторых приложений малая задержка важна — к таким приложениям относится, например, ssh, где не так важна высокая скорость как малая задержка, чтобы получать быстрый отклик при вводе команд.

Узлам Netsukuku следует поддерживать три типа таблиц маршрутизации:

  • маршруты с наилучшей пропускной способностью;

  • маршруты с наименьшей задержкой;

  • маршруты с эффективной комбинацией пропускной способности и задержки.

Если протокол приложения использует значения TOS в своих пакетах IP, можно добавить правила маршрутизации и выбрать для протокола подходящую таблицу (например, вторую для ssh).

Возможен вариант хранения в ядре лишь усредненной (третьей) таблицы, поскольку она применяется наиболее часто. Конкретные маршруты с наилучшей пропускной способностью и задержкой можно добавлять в ядро лишь в момент их использования. Например, при запуске bittorrent для загрузки с узлов A,B,C монитор ntkd будет добавлять в ядро маршруты с наилучшей пропускной способностью для A,B,C.

IGS

Шлюз inet-gw, позволяющий совместно использовать свое соединение с Internet, замеряет свою доступную полосу Internet-соединения. Максимальная пропускная способность в обоих направлениях известна, поскольку пользователь должен задать ее в конфигурационном файле netsukuku.conf. Таким образом, отслеживание устройства, используемого принятым по умолчанию маршрутом в Internet, позволяет легко узнать доступную полосу.

Балансировка нагрузки

Балансировка нагрузки будет применяться всегда, поскольку маршруты добавляются в ядро с использованием опции multipath. Пакеты, передаваемые узлу, будут использовать разные маршруты.

Балансировка нагрузки внутри Netsukuku не зависит от проблем балансировки на IGS. Узлы ntk согласованы между собой и не используют NAT для взаимодействия внутри сети.


Перевод на русский язык

Николай Малых

nmalykh@protocols.ru

1Round-trip time.




SNSD

NTK_RFC 0009

Scattered Name Service Disgregation

Распределенная служба имен

PDF

В этом документе описана распределенная служба имен (Scattered Name Service Disgregation) — расширение протокола ANDNA. Текст будет включен в окончательную документацию, а сейчас в него можно вносить правки, связавшись с разработчиками.

SNSD


Распределенная служба имен SNSD является эквивалентом ANDNA для записи SRV Record в Internet DNS1, определенной в [1] и кратко описанной в [2].

SNSD отличается от SRV Record и имеет свои уникальные свойства.

С помощью SNSD можно связать адреса IP и имена хостов с другим hostname.

Каждая назначенная запись имеет номер службы (service number), что позволяет группировать адреса IP и hostname с одинаковым номером в массив. При запросе распознавания (resolution request) клиент будет указывать номер, поэтому он получит запись для указанного номера, связанного с hostname.

Например, узел X имеет зарегистрированное имя хоста angelica и по умолчанию для этого имени выделен IP-адрес 1.2.3.4. X связывает имя хоста depausceve со службой http (номер 80) для имени хоста angelica, а также адрес 11.22.33.44 со службой ftp (номер 21) хоста angelica.

Когда Y обычным путем распознает адрес angelica, он получает 1.2.3.4, но при распознавании адреса из web-браузера он будет запрашивать запись, связанную со службой http, и запрос будет возвращать depausceve. Браузер будет распознавать адрес по имени depausceve и получит доступ к серверу. Когда клиент ftp хоста Y будет пытаться распознать адрес angelica, он получит 11.22.33.44. Если Y попытается распознать адрес для не связанной службы, он получит основной адрес хоста 1.2.3.4.

Узел, связанный с записью SNSD, называется узлом SNSD (SNSD node). В приведенном примере такими узлами являются depausceve и 11.22.33.44.

Узел, который регистрирует записи и сохраняет регистрацию основного имени хоста, всегда называют регистрирующим узлом (register node), но может также использоваться термин Zero SNSD node — фактически это соответствует наиболее общей записи SNSD для службы с номером 0.

Отметим, что SNSD полностью отменяет NTK_RFC 0004 [3].

Служба, приоритет, вес

Номер службы

Номер службы указывает область действия записи SNSD. Адрес IP, связанный со службой номер x, будет возвращаться только в ответ на запросы распознавания, содержащие этот номер. Номер службы — это номер порта, с которым связана соответствующая служба. Номера портов можно узнать из файла /etc/services. Служба с номером 0 соответствует обычной записи ANDNA и в ответ на базовый запрос распознавания будет возвращаться соответствующий адрес IP.

Приритет

Запись SNSD имеет также значение приоритета, которое определяет приоритет данной записи среди других записей внутри массива службы. Клиент будет взаимодействовать с первым узлом SNSD, имеющим наивысший приоритет, и только при недоступности этого узла станет обращаться к узлам с меньшим приоритетом.

Вес

Значение веса, связанное с записью SNSD, служит для выбора среди нескольких записей с одинаковым приоритетом. Клиент запрашивает у ANDNA распознавание и получает, например, 8 разных записей. Первая запись, используемая клиентом, выбирается псевдослучайным способом. Каждая запись может быть выбрана с вероятностью, пропорциональной ее весу. Отметим, что в случае одинакового приоритета у всех записей выбор становится полностью случайным.

Для запрета использования записи можно задать нулевой вес. Значения веса должны быть меньше 128.

Регистрация SNSD

Метод регистрации записи SNSD похож на описанный в [3]. С одной службой можно связать до 16 записей. Максимальное число зарегистрированных записей составляет 256.

Регистрация записей SNSD выполняется одним узлом register_node. Узел hash_node, получающий регистрацию, не будет связываться с counter_node, поскольку имя хоста уже зарегистрировано и его не нужно проверять. Остается проверить лишь действительность подписи.

Регистрирующий узел может также выбрать необязательную функцию SNSD, чтобы убедиться в том, что имя хоста SNSD всегда связано с доверенной машиной. В этом случае узлу register_node нужен открытый ключ ANDNA узла SNSD для передачи узлу периодических запросов. Если узел не отвечает, register_node будет передавать ANDNA для удаления соответствующей записи SNSD.

Регистрация записей SNSD для имен хостов, которые лишь помещены в очередь andna_queue, отвергается. Практические действия по регистрации записи SNSD показаны ниже.

 * Изменение файла /etc/netsukuku/snsd_nodes.
{{{
register_node# cd /etc/netsukuku/ 
register_node# cat snsd_nodes
#
# Файл узлов SNSD
#
# В формате
# hostname:snsd_hostname:service:priority:weight[:pub_key_file]
# или
# hostname:snsd_ip:service:priority:weight[:pub_key_file]
#
# Параметр pub_key_file является необязательным. При его наличии NetsukukuD будет
# периодически проверять snsd_hostname и контролировать принадлежность имени к
# одной машине. При смене машины соответствующая запись snsd будет удаляться.
#

depausceve:pippo:http:1
depausceve:1.2.3.4:21:0

angelica:frenzu:ssh:1:/etc/netsukuku/snsd/frenzu.pubk

register_node#
register_node# scp frenzu:/usr/share/andna_lcl_keyring snsd/frenzu.pubk
}}}
 * Передача сигнала SIGHUP демону NetsukukuD на регистрирующем узле.
{{{
register_node# killall -HUP ntkd
# или 
register_node# rc.ntk reload
}}}

Нулевое значение SNSD IP

Основной адрес IP, связанный с обычным hostname, имеет по умолчанию приведенные ниже значения.

{{{
IP       = register_node IP     # Это значение нельзя изменить
service  = 0
priority = 16
weight   = 1
}}}

Можно связать другие записи SNSD со службой 0, но не разрешается менять основной адрес IP, в качестве которого может служить только IP-адрес узла register_node. Хотя нет возможности установить другую привязку для основного адреса IP, его можно «отключить», установив вес 0.

Строка, применяемая для смены значений веса и приоритета основного IP, имеет вид

{{{
hostname:hostname:0:priority:weight

# Например,
register_node# echo depausceve:depausceve:0:23:12 >> /etc/netsukuku/snsd_nodes
}}}

Цепочка SNSD

Поскольку для нулевой записи можно задать разные псевдонимы и резервные адреса IP, можно создавать цепочки SNSD. Например,

{{{
depausceve registers: depausceve:80 --> pippo
pippo registers:      pippo:0  --> frenzu
frenzu registers:     frenzu:0 --> angelica
}}}

Однако цепочки SNSD игнорируются и пригодным считается лишь первое преобразование. Поскольку для службы 0 всегда имеется основной адрес IP, распознавание выполняется всегда. В приведенном случае (depausceve:80 —> pippo:0) распознавание будет возвращать основной IP-адрес pippo:0.

Отклик на запрос преобразования для службы 0 всегда возвращает адреса IP, а не имена хостов.


[1] http://www.ietf.org/rfc/rfc2782.txt

[2] http://en.wikipedia.org/wiki/SRV_record

[3] Mail Exchange request, http://netsukuku.freaknet.org/main_doc/ntk_rfc/Ntk_MX_request

Перевод на русский язык

Николай Малых

nmalykh@protocols.ru

1Domain Name System — служба доменных имен.




Протокол ANDNS

PDF

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

Перевод на русский язык

Николай Малых

nmalykh@protocols.ru