Я хотел бы познакомить вас с моей идеей и тем, как она пришла к созданию привязки «ROHC» в NodeJS.
Я хотел реализовать VPN, работающую через Web-Socket. Преимущество будет в том, что служба будет скрыта через HTTPS. С HTTP3 это было бы еще более оптимизировано. Поэтому я начал экспериментировать с модулем TunTap2 для NodeJS, который мне нужно было сначала исправить.
Всегда увлекавшийся беспроводными технологиями, в какой-то момент я наткнулся на «LoRa», а вместе с ним и на проект «IP2Lora».
Источник изображения
В этом проекте «IP2Lora» IP-пакеты были сокращены для экономии 40 байт, что очень важно для передачи; при радиодиапазоне 434 МГц или 868 МГц не так уж и много можно передать.
Источник изображения
На графике хорошо видно, как уменьшается размер IP-пакета.
К сожалению, для Python существовала только одна привязка библиотеки.
Так почему бы не написать привязку библиотеки узла самостоятельно!?
Теперь можно увидеть результат.
https://www.npmjs.com/package/node-rohc
Подробнее о том, как работает ROHC, вы можете узнать по ссылкам на проект или просто поискать его. Я не буду объяснять это здесь, чтобы не делать пост слишком длинным.
Я установил под Linux Debian/Mint. Я думаю, это должно быть похоже на другие версии Linux.
(Кстати, мне еще пришлось пропатчить ROHC-lib под новое ядро.)
sudo apt-get install autotools-dev sudo apt-get install automake sudo apt-get install libtool sudo apt-get install libpcap-dev sudo apt-get install -y libcmocka-dev git clone https://github.com/stefanwerfling/rohc.git cd rohc ./autogen.sh --prefix=/usr make all sudo make install
Теперь мы можем зайти в наш проект и установить модуль.
cd yourProject npm i node-rohc
Теперь нам нужно создать привязку NodeJS (она должна быть скомпилирована для каждой архитектуры ЦП).
cd yourProject/node_modules/node-rohc npm run build --loglevel verbose
Установка завершена.
Теперь предположим, что мы получили IP-пакет, который мы хотим сжать в следующие пакеты для экономии байтов.
const ipU8Packet = new Uint8Array(ipPacketBufferWithContent); console.log(ipU8Packet);
Uint8Array(52) [ 69, 0, 0, 52, 0, 0, 0, 0, 64, 6, 249, 112, 192, 168, 0, 1, 192, 168, 0, 2, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
Теперь импортирован модуль и Unit8Array, в котором IP-пакет передается объекту Rhoc для сжатия.
import {Rohc} from 'node-rohc'; const r = new Rohc([ RohcProfiles.ROHC_PROFILE_UNCOMPRESSED, RohcProfiles.ROHC_PROFILE_IP, RohcProfiles.ROHC_PROFILE_TCP, RohcProfiles.ROHC_PROFILE_UDP, RohcProfiles.ROHC_PROFILE_ESP, RohcProfiles.ROHC_PROFILE_RTP ]); try { const compress = r.compress(ipU8Packet); console.log(compress); } catch (e) { console.error(e); }
Uint8Array(53) [ 253, 4, 69, 64, 6, 192, 168, 0, 1, 192, 168, 0, 2, 0, 64, 0, 0, 32, 0, 251, 103, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
В конструкторе объекта Rohc мы указываем профили, которые следует использовать для сжатия в массиве.
Затем следует сжатие. В выводе мы видим новый пакет. Но почему он не меньше?
Первый пакет по-прежнему содержит информацию о порте/IP-адресе и т. д. Только следующие пакеты становятся значительно меньше.
Чтобы преобразовать пакет Rohc обратно в обычный IP-пакет, мы используем распаковку.
try { const decompress = r.decompress(compress); console.log(decompress); } catch (e) { console.error(e); }
Uint8Array(52) [ 69, 0, 0, 52, 0, 0, 0, 0, 64, 6, 249, 112, 192, 168, 0, 1, 192, 168, 0, 2, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
Что важно, так это начало: первый пакет сжимается и передается пункту назначения, а пункт назначения распаковывает пакет, экземпляр необходимо поддерживать. Чтобы идентификатор соединения оставался известным. Это означает, что программа должна поддерживать работу экземпляра объекта. Если одна из двух страниц (исходная со сжатием или целевая с распаковкой) остановлена, обе страницы необходимо перезапустить.
Дополнительная функция с полезной информацией:
import {Rohc, RohcStatus} from 'node-rohc'; if (r.getLastStatus() === RohcStatus.ROHC_OK) { console.log('All OK'); }
Во время сжатия или распаковки статус запоминается; сразу же после этого его можно запросить еще раз, чтобы получить более подробную информацию о том, что произошло.
console.log(r.compressLastPacketInfo()); console.log(r.decompressLastPacketInfo());
{ version_major: 0, version_minor: 0, context_id: 0, is_context_init: true, context_mode: 1, context_state: 1, context_used: true, profile_id: 4, packet_type: 0, total_last_uncomp_size: 52, header_last_uncomp_size: 20, total_last_comp_size: 53, header_last_comp_size: 21 } { version_major: 0, version_minor: 0, context_mode: 2, context_state: 3, profile_id: 4, nr_lost_packets: 0, nr_misordered_packets: 0, is_duplicated: false, corrected_crc_failures: 11745388377929038000, corrected_sn_wraparounds: 14987979559889062000, corrected_wrong_sn_updates: 12105675798372346000, packet_type: 449595, total_last_comp_size: 18407961667527770000, header_last_comp_size: 1940628627783807, total_last_uncomp_size: 18407961667125117000, header_last_uncomp_size: 217316637802623 }
Информация о последнем сжатии или распаковке.
console.log(r.compressGeneralInfo()); console.log(r.decompressGeneralInfo());
{ version_major: 0, version_minor: 0, contexts_nr: 1, packets_nr: 1, uncomp_bytes_nr: 52, comp_bytes_nr: 53 } { version_major: 0, version_minor: 0, contexts_nr: 1, packets_nr: 1, comp_bytes_nr: 53, uncomp_bytes_nr: 52, corrected_crc_failures: 0, corrected_sn_wraparounds: 8518447232180027000, corrected_wrong_sn_updates: 4295000063 }
Общая информация о сжатии и распаковке.
Надеюсь, вам понравился мой небольшой пост. Я всегда открыт для улучшений.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3