제 아이디어와 NodeJS에서 "ROHC"에 바인딩을 부여하게 된 과정을 소개하고 싶습니다.
웹 소켓을 통해 실행되는 VPN을 구현하고 싶었습니다. 장점은 서비스가 HTTPS를 통해 숨겨진다는 것입니다. HTTP3을 사용하면 더욱 최적화됩니다. 그래서 먼저 패치해야 했던 NodeJS용 TunTap2 모듈을 가지고 놀기 시작했습니다.
항상 무선 기술에 매료되어 어느 시점에서 "LoRa"와 "IP2Lora" 프로젝트를 접하게 되었습니다.
이미지 출처
이 프로젝트 “IP2Lora”에서는 IP 패킷을 단축하여 전송에 매우 중요한 40바이트를 절약했습니다. 434MHz 또는 868MHz의 무선 대역에서는 그다지 많은 양이 전송될 수 없습니다.
이미지 출처
그래픽에서 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
이제 프로젝트로 이동하여 모듈을 설치할 수 있습니다.
cd yourProject npm i node-rohc
이제 NodeJS 바인딩을 생성해야 합니다(이것은 각 CPU 아키텍처 자체에 대해 컴파일되어야 합니다).
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 ]
이제 모듈을 가져오고 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 }
압축 및 압축 해제에 대한 일반 정보입니다.
제 포스팅이 즐거웠기를 바랍니다. 저는 항상 개선의 여지가 있습니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3