NodeJS + ROHC

WBOY
풀어 주다: 2024-07-31 07:05:33
원래의
595명이 탐색했습니다.

아이디어부터 구현까지

제 아이디어와 NodeJS에서 "ROHC"에 바인딩을 부여하게 된 과정을 소개하고 싶습니다.

웹 소켓을 통해 실행되는 VPN을 구현하고 싶었습니다. 장점은 서비스가 HTTPS를 통해 숨겨진다는 것입니다. HTTP3을 사용하면 더욱 최적화됩니다. 그래서 먼저 패치해야 했던 NodeJS용 TunTap2 모듈을 가지고 놀기 시작했습니다.

항상 무선 기술에 매료되다가 어느 순간 'LoRa'를 접하게 되었고, 이와 함께 'IP2Lora' 프로젝트가 탄생하게 되었습니다.

Image description

이미지 출처

이 프로젝트 “IP2Lora”에서는 IP 패킷을 단축하여 전송에 매우 중요한 40바이트를 절약했습니다. 434MHz 또는 868MHz의 무선 대역에서는 그다지 많은 양을 전송할 수 없습니다.

NodeJS + ROHC

이미지 출처

그래픽에서 IP 패킷 크기가 어떻게 감소하는지 명확하게 확인할 수 있습니다.

안타깝게도 Python용 lib 바인딩은 하나만 있었습니다.

그러면 직접 바인딩하는 노드 lib를 작성해 보는 것은 어떨까요!?

이제 결과를 보실 수 있습니다.
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가 알려진 상태로 유지됩니다. 이는 프로그램이 객체 인스턴스를 계속 실행해야 함을 의미합니다. 두 페이지(압축된 소스 또는 압축 해제된 대상) 중 하나가 중지되면 두 페이지를 모두 다시 시작해야 합니다.

유용한 정보가 포함된 추가 기능:

마지막 압축/압축 해제 상태

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿