Enviado por admin el
El SIP forking es una funcionalidad fundamental en los sistemas de telefonía IP que permite el timbre simultáneo en múltiples dispositivos, la implementación de Hunt Groups en sistemas de clase V (VPBX) y el failover entre múltiples gateways o carriers. En la práctica, un Hunt Group puede apuntar a 6-9 usuarios, cada uno con varios dispositivos registrados y posiblemente con Push Notification habilitado, lo que genera fácilmente 25 ramas (branches) por transacción. Si ese Hunt Group hace failover hacia otro grupo similar, se alcanzan unas 50 ramas. En escenarios de trunking con failover en cascada entre carriers y gateways, una sola llamada puede necesitar iterar de 40 a 60 gateways, generando transacciones INVITE con de 20 a 40 ramas.
OpenSIPS 3.6 arrastra un diseño de 25 años que limita a un máximo de 31 ramas por transacción. Esta limitación proviene del uso de un bitmask interno sobre un tipo de dato uint32. El problema afecta exclusivamente a las transacciones INVITE, ya que son las únicas que realizan forking; las peticiones BYE, por ejemplo, solo tienen una rama. Además, el número de ramas varía enormemente según el escenario y el tamaño de cada rama es considerable en memoria.
La primera solución implementada en OpenSIPS 4.0 es una reescritura completa del código de gestión de ramas. El bitmask fue reemplazado por una estructura de datos tipo array, eliminando cualquier limitación en el número máximo de ramas. El valor por defecto en el código es de 256 ramas máximas por transacción, aunque este valor se puede aumentar fácilmente modificando una sola definición en el código fuente.
El segundo problema es el consumo de memoria. Cada estructura de rama ocupa aproximadamente 0.5 KB. Con la configuración anterior de 12 ramas, una transacción ocupaba 6920 bytes. Con 64 ramas integradas se pasa a 34320 bytes y con 256 ramas a casi 134 KB por transacción. En un sistema que procesa 5000 llamadas por segundo, con un mínimo de 10000 transacciones por segundo y un tiempo de vida de 10 segundos por transacción (sumando ring time más time-to-delete), se mantienen unas 100000 transacciones simultáneas en memoria. Con 134 KB por transacción, eso supone 13.4 GB de memoria, en su mayoría desperdiciada porque no todas las transacciones INVITE necesitan tantas ramas.
La segunda solución en OpenSIPS 4.0 es la asignación dinámica y progresiva de ramas. En lugar de reservar siempre el número máximo de ramas al crear la transacción, se asignan bloques de 4 ramas según se necesiten. No se puede usar realloc convencional porque las ramas quedan enlazadas en diferentes listas de timers, lo que hace que sean sensibles a cambios de dirección en memoria, por eso se optó por chunks de tamaño fijo. El resultado es que OpenSIPS 4.0 elimina el límite de ramas por transacción sin penalización de memoria ni procesamiento, e incluso reduce la huella de memoria respecto a versiones anteriores.
Fuente: https://blog.opensips.org/2026/02/17/big-scale-sip-forking/
Comentarios recientes