"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > NodeJS + ROHC

NodeJS + ROHC

Publicado el 2024-07-31
Navegar:838

De la idea a la implementación

Me gustaría presentarles mi idea y cómo surgió darle a “ROHC” un enlace en NodeJS.

Quería implementar una VPN que se ejecutara a través de Web-Socket. Las ventajas serían que el servicio estaría oculto a través de HTTPS. Con HTTP3 esto estaría aún más optimizado. Así que comencé a jugar con el módulo TunTap2 para NodeJS, al que primero tuve que parchear.

Siempre fascinado por la tecnología inalámbrica, en algún momento me encontré con “LoRa” y con él un proyecto “IP2Lora”.

Image description

Fuente de imagen

En este proyecto “IP2Lora”, los paquetes IP se acortaron para ahorrar 40 bytes, lo cual es muy importante para la transferencia; con una banda de radio de 434 MHz u 868 MHz, no se puede transferir mucho.

NodeJS   ROHC

Fuente de imagen

En el gráfico se puede ver claramente como el tamaño del paquete IP disminuye.

Desafortunadamente, solo había un enlace de biblioteca para Python.

Entonces, ¿por qué no escribir una biblioteca de nodo vinculante tú mismo?

El resultado ahora se puede ver.
https://www.npmjs.com/package/node-rohc

Puedes conocer más sobre cómo funciona ROHC en los enlaces al proyecto o simplemente buscarlo. No lo explicaré aquí para no alargar mucho el post.

Biblioteca de instalación

Lo instalé en Linux Debian/Mint. Creo que esto debería ser similar a otras versiones de Linux.

(Por cierto, también tuve que parchear ROHC-lib para el nuevo kernel).

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

Instalación NPM

Ahora podemos ingresar a nuestro proyecto e instalar el módulo.

cd yourProject
npm i node-rohc

Ahora tenemos que crear el enlace NodeJS (esto debe compilarse para cada arquitectura de CPU).

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

La instalación está completa.

Codificación/uso de API

Ahora supongamos que obtenemos un paquete IP que queremos comprimir en los siguientes paquetes para ahorrar bytes.

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
]

El módulo ahora se importa y el Unit8Array en el que se entrega el paquete IP al objeto Rhoc para su compresión.

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
]

En el constructor del objeto Rohc especificamos los perfiles que se deben utilizar para la compresión en un array.

Luego viene la compresión. En el resultado vemos el nuevo paquete. ¿Pero por qué no es más pequeño?

El primer paquete todavía contiene información sobre el puerto/dirección IP, etc. Sólo los siguientes paquetes se vuelven significativamente más pequeños.

Para convertir el paquete Rohc nuevamente en un paquete IP normal usamos descomprimir.

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
]

Lo importante es el comienzo, el primer paquete se comprime y se transmite al destino y el destino ha descomprimido el paquete, se debe mantener la instancia. Para que el ID de la conexión siga siendo conocido. Esto significa que el programa debe mantener la instancia del objeto en ejecución. Si una de las dos páginas (origen con compresión o destino con descompresión) se detiene, se deben reiniciar ambas páginas.

Función adicional con información útil:

Estado de la última compresión/descompresión

import {Rohc, RohcStatus} from 'node-rohc';

    if (r.getLastStatus() === RohcStatus.ROHC_OK) {
      console.log('All OK');
    }

Durante la compresión o descompresión, se recuerda el estado; esto se puede consultar nuevamente inmediatamente después para obtener información más detallada sobre lo sucedido.

Información del último paquete comprimido/descomprimido

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
}

Información sobre la última compresión o descompresión.

Información general sobre comprimir/descomprimir

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
}

Información general sobre compresión y descompresión.

Palabra final

Espero que hayas disfrutado de mi pequeña publicación. Siempre estoy abierto a mejoras.

Declaración de liberación Este artículo se reproduce en: https://dev.to/stefanwerfling/nodejs-rohc-11k3?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3