NodeJS + ROHC

WBOY
WBOYオリジナル
2024-07-31 07:05:33537ブラウズ

アイデアから実装まで

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

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

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

Image description

画像ソース

このプロジェクト「IP2Lora」では、IP パケットを短縮して 40 バイトを節約しました。これは転送にとって非常に重要です。 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
}

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

最後の言葉

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

以上がNodeJS + ROHCの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。