「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > NodeJS + ROHC

NodeJS + ROHC

2024 年 7 月 31 日に公開
ブラウズ:360

アイデアから実装まで

私のアイデアと、NodeJS で「ROHC」にバインディングを与えることになった経緯を紹介したいと思います。

Web-Socket 上で動作する VPN を実装したいと考えていました。利点は、サービスが HTTPS 上で隠蔽されることです。 HTTP3 を使用すると、これはさらに最適化されます。そこで、NodeJS 用の TunTap2 モジュールをいじり始めました。最初にパッチを適用する必要がありました。

常にワイヤレス テクノロジーに魅了されてきた私は、ある時点で「LoRa」とそれを使ったプロジェクト「IP2Lora」に出会いました。

Image description

画像ソース

このプロジェクト「IP2Lora」では、転送に非常に重要な 40 バイトを節約するために IP パケットが短縮されました。 434 MHz または 868 MHz の無線帯域では、それほど多くのデータを転送できません。

NodeJS   ROHC

画像ソース

この図では、IP パケット サイズがどのように減少するかがはっきりとわかります。

残念ながら、Python のライブラリ バインディングは 1 つだけでした。

では、ノード ライブラリ バインディングを自分で書いてみませんか?

結果が表示されます。
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

インストールNPM

これで、プロジェクトに移動してモジュールをインストールできます。

cd yourProject
npm i node-rohc

次に、NodeJS バインディングを作成する必要があります (これは、各 CPU アーキテクチャ自体に対してコンパイルする必要があります)。

cd yourProject/node_modules/node-rohc
npm run build --loglevel verbose

インストールが完了しました。

コーディング/APIの使用法

次に、バイトを節約するために次のパケットに圧縮する 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
]

モジュールがインポートされ、圧縮のために IP パケットが Rhoc オブジェクトに与えられる Unit8Array がインポートされました。

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
]

重要なのは始まりです。最初のパケットは圧縮されて宛先に送信され、宛先がパケットを解凍すると、インスタンスが維持される必要があります。そのため、接続 ID は既知のままです。これは、プログラムがオブジェクト インスタンスを実行し続ける必要があることを意味します。 2 つのページのうち 1 つ (圧縮によるソースまたは解凍による宛先) が停止した場合は、両方のページを再起動する必要があります。

役立つ情報を含む追加機能:

前回の圧縮/解凍ステータス

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
}

圧縮と解凍に関する一般情報。

最後の言葉

私の小さな投稿を楽しんでいただければ幸いです。私は常に改善を歓迎します。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/stefanwerfling/nodejs-rohc-11k3?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3