Números comerciales y menús telefónicos para Estados Unidos y Canadá. ENFR(510) 288-6288[email protected]Iniciar sesión

Inicio › VoIP de código abierto › OpenSIPS

VoIP de código abierto

OpenSIPS en profundidad: el servidor SIP, sus módulos y un balanceador de carga funcional.

OpenSIPS no es un sistema telefónico. Es un enrutador SIP programable que se coloca delante de sistemas telefónicos, operadores y redes de controladores de borde, y decide adónde va cada solicitud. Esta guía explica cómo funciona según la documentación y el código del propio proyecto, indica qué versión conviene ejecutar hoy y recorre una configuración completa que reparte las llamadas entrantes entre dos servidores de medios.

Revisado el 26 de octubre de 2026 · 50 fuentes citadas · 24 min de lectura

A SIP load balancer

Qué es OpenSIPS y qué no es

OpenSIPS se describe a sí mismo como "an Open Source SIP proxy/server for voice, video, IM, presence and any other SIP extensions" (un proxy o servidor SIP de código abierto para voz, video, mensajería, presencia y cualquier otra extensión SIP).2 Su propia lista de funciones es más larga de lo que sugiere esa frase: registrador SIP, enrutador o proxy, servidor de redirección, agente de presencia, agente de usuario back-to-back, servidor de mensajería, balanceador de carga o dispatcher, un "SIP front end for gateways/asterisk" (front end SIP para gateways y Asterisk), unidad de traversal de NAT y servidor de aplicaciones.1 Está escrito en C y se publica bajo la GNU GPL versión 2.56

El modelo mental útil es el de nuestra visión general del VoIP de código abierto: OpenSIPS trabaja en la capa de señalización. Recibe solicitudes SIP, decide qué hacer con ellas según un script que usted escribe, y las reenvía, las responde o las rechaza. No reproduce mensajes, no graba llamadas ni administra un buzón de voz. Esas tareas corresponden a un servidor de medios o a una central telefónica (PBX) como Asterisk o FreeSWITCH, y en la mayoría de las instalaciones OpenSIPS se coloca delante de varios de ellos.

El audio es el único terreno donde esa línea se ha difuminado. Tradicionalmente, OpenSIPS dirige los medios a través de un relé externo (RTPProxy o Sipwise rtpengine) que controla mediante un protocolo sencillo.31 La versión 3.6 agregó rtp.io, que realiza "RTP relaying and processing directly inside the OpenSIPS process" (la retransmisión y el procesamiento de RTP directamente dentro del proceso de OpenSIPS), con lo que en algunos diseños ya no hace falta un relé externo.10

Nuestra opinión: piense en OpenSIPS como un enrutador con un lenguaje de scripts, no como un producto. No ocurre nada que el script no indique. Eso lo hace rápido y flexible, y también es la razón por la que una configuración copiada de un foro sin entenderla es la forma más común de terminar con un relé abierto o con una factura por fraude telefónico.

De dónde viene: SER, OpenSER y luego dos proyectos

OpenSIPS y Kamailio comparten un ancestro, y la cronología explica por qué sus archivos de configuración todavía se parecen.

  • 2001 a 2002, SER. El proyecto SIP Express Router lo inició el instituto de investigación FhG Fokus, en Berlín, el 2 de septiembre de 2001, y se publicó como código abierto bajo la GPL en el otoño de 2002.7 El archivo de licencia de OpenSIPS todavía dice que "OpenSIPS software is derived from SER (SIP Express Router) project developed by FhG FOKUS" (el software OpenSIPS deriva del proyecto SER desarrollado por FhG FOKUS).6
  • Junio de 2005, OpenSER. "OpenSER project started on the 14th June, 2005" (el proyecto OpenSER comenzó el 14 de junio de 2005).7
  • Julio y agosto de 2008, la división. El 28 de julio de 2008, OpenSER pasó a llamarse Kamailio "due to trademark issues" (por problemas de marca registrada).7 Una semana después, el 4 de agosto de 2008, Voice System, la empresa que había sido la principal colaboradora de OpenSER, anunció OpenSIPS junto con su primera versión, 1.4.0. El anuncio decía que OpenSIPS "is a continuation of the OpenSER project" (es una continuación del proyecto OpenSER) y citaba como motivos los retrasos en las versiones, el deterioro del control de calidad y la falta de coordinación del proyecto. Su diagrama resumen era sencillamente OpenSER ramificándose en Kamailio y OpenSIPS.8 La página de versiones confirma 1.4.x como la primera versión de OpenSIPS, con fecha del 4 de agosto de 2008.3
  • 2010 a 2012, Kamailio y SER vuelven a unirse. Kamailio 3.0.0, publicado el 11 de enero de 2010, fue la primera versión construida a partir de un único árbol de código con SER, y la integración se declaró completa el 20 de diciembre de 2012.7

Desde 2008, los dos proyectos se desarrollaron por separado. La sintaxis del script, los nombres de los módulos (tm, rr, dispatcher, usrloc) y la forma general de un script de enrutamiento siguen siendo reconociblemente comunes. Las firmas de las funciones, los parámetros y subsistemas enteros ya no lo son.

Consecuencia práctica

Una respuesta sobre OpenSIPS no es una respuesta sobre Kamailio, ni al revés. Un ejemplo de dispatcher escrito para uno suele cargarse en el analizador del otro y luego comportarse mal, o fallar en una función que solo existe en uno de ellos. Consulte siempre la documentación del proyecto y la rama exactos que ejecuta. OpenSIPS publica un manual distinto para cada versión (3.6 y 4.0 más abajo), y las páginas de los módulos indican en qué versión apareció cada comportamiento.

Arquitectura: procesos, memoria, transacciones y diálogos

Procesos y memoria

OpenSIPS es un servidor de múltiples procesos. Para UDP, cada interfaz de escucha recibe su propio grupo de procesos de trabajo: udp_workers fija el número "for each UDP or SCTP interface" (para cada interfaz UDP o SCTP), su valor predeterminado es 8, y una línea socket individual puede reemplazarlo.12 Los transportes basados en TCP (TCP, TLS, WebSocket) tienen su propio grupo tcp_workers, también con 8 por defecto, y existen procesos de temporizador dedicados (timer_workers, 1 por defecto).12 Cualquiera de estos grupos puede regirse por un auto_scaling_profile que crea o termina procesos según la carga.12

La versión 4.0 cambió sustancialmente el lado TCP. Antes de 4.0, un proceso TCP principal entregaba las conexiones a procesos de trabajo TCP, de modo que "connections had to be passed back and forth between the TCP Main process and the TCP workers" (las conexiones debían pasarse de un lado a otro entre el proceso TCP principal y los procesos de trabajo). En 4.0, un único proceso dedicado es dueño de todas las conexiones TCP y TLS y usa hilos para la entrada y salida de los sockets. Los mensajes SIP completos se pasan a los procesos de trabajo, y estos devuelven las escrituras como tareas asíncronas.11 El manual de 4.0 describe el nuevo parámetro tcp_threads, cuyo valor predeterminado es el número de CPU en línea.13 El proyecto afirma que el rediseño elimina el manejo especial de OpenSSL que exigía el modelo multiproceso.9

Todos los procesos comparten un único bloque de memoria compartida, cuyo tamaño se fija en megabytes con la opción de línea de comandos -m.16 La documentación del núcleo da 32 MB como tamaño predeterminado de memoria compartida.12 Cada proceso tiene además memoria privada para el mensaje que está procesando. La distinción importa: el módulo TM "copies clones of received SIP messages in shared memory" (copia clones de los mensajes SIP recibidos en memoria compartida), mientras que "non-TM functions operate over the received message in private memory" (las funciones que no son de TM operan sobre el mensaje recibido en memoria privada).17

Sin estado, con estado de transacción y con estado de diálogo

OpenSIPS puede manejar una solicitud en tres niveles de memoria, y elegir el nivel es una decisión de diseño que usted toma en el script.

  • Sin estado. El módulo SL responde solicitudes "without keeping state" (sin guardar estado), lo que la documentación recomienda cuando "wish not to burden server’s memory and scale well" (se quiere no sobrecargar la memoria del servidor y escalar bien).18
  • Con estado de transacción. TM sigue una solicitud y sus respuestas. t_relay() crea la transacción, absorbe las retransmisiones del lado de origen, genera retransmisiones hacia el destino y asocia las respuestas con las solicitudes. La bifurcación (forking) y la conmutación por error deben tener estado. La documentación señala que esto cuesta memoria y latencia a cambio de no repetir trabajo como las consultas DNS.17
  • Con estado de diálogo. El módulo dialog sigue toda la llamada, desde el INVITE creado con create_dialog() hasta el BYE. Si no llega ningún BYE, default_timeout da por terminado el diálogo. El estado del diálogo permite perfiles ("¿cuántas llamadas tiene este cliente activas?"), variables por llamada y terminación iniciada por el proxy.23 Varios módulos de nivel superior lo requieren, entre ellos load_balancer, fraud_detection y rtp_relay.384332

El script de enrutamiento

Todo lo que hace OpenSIPS se controla desde opensips.cfg. El archivo incluido en el repositorio tiene tres partes: parámetros globales, una sección de módulos (líneas loadmodule y modparam) y la lógica de enrutamiento.30 La lógica de enrutamiento es un conjunto de bloques de ruta, cada uno activado por un evento distinto:14

BloqueSe activa porValor predeterminado al terminar el bloque
route { }Cada solicitud SIP recibida de la redLa solicitud se descarta, salvo que se haya reenviado o respondido
route[name]Llamado desde otras rutas con route(name)Regresa a quien lo llamó
branch_routeUna rama nueva está lista pero aún no se ha enviado (se activa con t_on_branch())La rama se envía, a menos que se descarte
onreply_routeLlega una respuesta (global, o activada por transacción o rama con t_on_reply())La respuesta pasa al motor de transacciones
failure_routeTodas las ramas terminaron con una respuesta negativa (se activa con t_on_failure())La respuesta negativa ganadora se devuelve a quien llamó
error_routeUn error de análisis o un assert fallidoLa solicitud se descarta
local_routeTM genera una solicitud internamenteLa solicitud se envía
startup_route, timer_route, event_routeEl arranque, un intervalo fijo o un evento con nombre de la Event InterfaceNo interviene ningún mensaje SIP

Desplace la tabla hacia los lados para ver todas las columnas.

Dos detalles confunden a quienes empiezan. Primero, una failure_route procesa "the original SIP request (that was sent out)" (la solicitud SIP original, la que se envió), no la respuesta que falló.14 Segundo, las variables de script ($var) persisten solo durante una ejecución de una ruta de nivel superior, pero pueden contener basura dejada por el mensaje anterior que procesó el mismo proceso. La documentación indica inicializarlas antes de usarlas.15

Los módulos que importan

El núcleo hace muy poco por sí solo: las funciones vienen de módulos cargados con loadmodule.30 Estos son los módulos en los que se apoya el resto de esta guía, descritos a partir de su propia documentación.

MóduloQué haceConviene saber
registrar y usrlocRegistrar procesa REGISTER "per RFC 3261" (según RFC 3261), con soporte de Path según RFC 3327.35 usrloc guarda las asociaciones de contacto.36Los contactos pueden vivir en memoria, en SQL o en NoSQL, o en memoria con sincronización SQL asíncrona. Desde 2.4, usrloc puede distribuirse en un clúster.36
auth_dbAutenticación digest contra una tabla de suscriptores.37Admite los algoritmos SHA-256 y SHA-512-256 de RFC 8760 desde 3.2.37
dispatcherElige un destino de un conjunto mediante algoritmos de hash, round-robin, aleatorio o definidos por script, y reescribe el URI de destino.24Sin estado, con "no guarantee of fair distribution" (sin garantía de reparto equitativo). Sondea con OPTIONS los destinos caídos. También puede tomar pesos dinámicos del Event Socket de FreeSWITCH.24
load_balancerEnruta por carga: cuenta las llamadas en curso por destino y recurso y elige "the destination with the largest available slot" (el destino con mayor capacidad disponible).38Necesita el módulo dialog. Úselo cuando sus servidores de medios tienen límites de capacidad estrictos.38
droutingEnrutamiento dinámico por prefijo, grupo de llamante, horario y prioridad, con "Least Cost Routing (LCR)" como "a special case" (un caso especial).39Incluye eliminación y adición de prefijos, selección de gateway por peso o aleatoria, bifurcación en serie y sondeo de gateways.39
dialogEstado a nivel de llamada, perfiles, tiempos de espera, terminación.23La base de load_balancer, del ocultamiento de topología con soporte de diálogo, de fraud_detection y de rtp_relay.38424332
rtpproxy, rtpengine, rtp_relayControlan un relé de medios externo. rtpengine reescribe el SDP para que los medios pasen por Sipwise rtpengine.31rtp_relay activa un relé una vez en el INVITE inicial y luego se ocupa solo del resto de la llamada. Desde 3.6 también tiene un motor interno "route" para manejar SDP personalizado.32
b2b_entities y b2b_logicEl B2BUA de OpenSIPS, construido en dos capas: las entidades implementan las funciones básicas de UAS y UAC, y la lógica implementa los servicios.4041Las sesiones pueden iniciarse desde el script o desde un comando MI (control de llamadas de terceros). La lógica de escenarios se ejecuta en rutas dedicadas.41
topology_hidingElimina y restaura las cabeceras Via, Record-Route y Route, y reemplaza el Contact por la dirección propia del proxy.42Las solicitudes dentro del diálogo ya no llevan cabeceras Route, así que el script debe llamar a topology_hiding_match() para encontrar su diálogo.42
fraud_detectionVigila el total de llamadas, las llamadas por minuto, las llamadas simultáneas, las llamadas consecutivas y la duración, por usuario y por prefijo marcado, frente a umbrales de advertencia y críticos.43Requiere drouting y dialog.43
clustererAgrupa instancias de OpenSIPS en clústeres que intercambian paquetes BIN para replicación y tareas compartidas.444.0 agregó la replicación cluster-bridge, que enlaza clústeres de distintos centros de datos sin malla completa.449
stir_shakenServicios de autenticación y verificación STIR/SHAKEN (RFC 8224, RFC 8588).45En 4.0 el módulo se compila por defecto con wolfSSL; OpenSSL sigue siendo una opción en tiempo de compilación.9

Desplace la tabla hacia los lados para ver todas las columnas.

¿Dispatcher o load_balancer? Dispatcher es la herramienta más ligera: sin estado de diálogo, muchos algoritmos, verificaciones de salud. load_balancer sabe cuántas llamadas lleva cada destino y no excederá una capacidad configurada, pero necesita seguir el diálogo de cada llamada.2438 Nuestra opinión: con dos o tres servidores de medios idénticos y sin límites de licencia, dispatcher basta, y es el que usa el ejemplo práctico de más abajo. Cuando los destinos difieren en tamaño, o un límite de canales es contractual, use load_balancer.

Versiones: cuál ejecutar en octubre de 2026

La política de versiones establece un ciclo mayor de un año. Las versiones estándar tienen "supported for 1.5 years after the initial release" (soporte durante 1,5 años después de la publicación inicial) y las LTS durante tres años. Las versiones LTS son "typically even-numbered" (normalmente de numeración par), con 3.0 (estándar) y 3.1 (LTS) citadas como excepciones.4 Cuando una versión deja de tener soporte, "it will not get any new bug fixes, re-packaging or new tarballs" (no recibirá correcciones de errores, reempaquetado ni nuevos tarballs).4

La página de versiones muestra el estado actual de cada rama:3

RamaTipoPublicadaÚltima versión menor (según la página de versiones)Soporte hasta
4.1.xDesarrollo (master)No publicada4.1.0-devNo aplica
4.0.xEstándar23 de junio de 20268 de septiembre de 2026 (4.0.2)Diciembre de 2027
3.6.xLTS23 de julio de 20258 de septiembre de 2026 (3.6.9)21 de mayo de 2028
3.5.xEstándar25 de julio de 202418 de diciembre de 202518 de diciembre de 2025 (terminado)
3.4.xLTS19 de julio de 20236 de mayo de 20266 de mayo de 2026 (terminado)

Desplace la tabla hacia los lados para ver todas las columnas.

Los números de versión menor provienen de las etiquetas del repositorio y de la página de noticias del proyecto, que registran 4.0.2 y 3.6.9 como publicadas el 8 de septiembre de 2026.52 La página dice actualmente: "Currently supported stable releases: 4.0 and 3.6 (LTS)." (versiones estables con soporte actual: 4.0 y 3.6 LTS).3

Dos cosas de esa página difieren de la política escrita. Primero, la política prevé una beta en la segunda mitad de marzo y una versión estable "around the beginning of May" (alrededor de principios de mayo).4 Todas las versiones estables de 3.1 a 3.6 salieron en realidad en julio, y 4.0 llegó el 23 de junio.3 La página de la política se modificó por última vez en 2020.4 Segundo, 4.0 tiene numeración par pero no está etiquetada como LTS: su fin de soporte en diciembre de 2027 corresponde a la ventana estándar de 18 meses.34 Es decir, 4.0 repite la excepción de 3.0, y la página de versiones todavía no nombra la próxima LTS.

Lo que trae 4.0, en palabras del propio proyecto, son "radical changes within the OpenSIPS design" (cambios radicales en el diseño de OpenSIPS).2 Entre ellos están la capa TCP y TLS multihilo descrita arriba, un marco de perfilado que exporta los tiempos de las rutas del script mediante OpenTelemetry, sockets "bond" que permiten al script elegir una interfaz incluso para destinos con FQDN, ramas de transacción asignadas bajo demanda (el límite anterior era 32, ampliable a 64), interoperabilidad de PRACK y UPDATE en el módulo dialog, soporte de Proxy Protocol y un módulo nuevo, auth_web3.9

Nuestra opinión: ejecute 3.6 LTS en producción, salvo que necesite algo que solo tiene 4.0. Tiene soporte hasta mayo de 2028, recibe el mismo ritmo de versiones menores que 4.0 y la documentación de sus módulos está completa. La reescritura de TCP y TLS de 4.0 es el motivo más sólido para cambiar: enlaces troncales TLS, clientes WebSocket, muchas conexiones persistentes. Si cambia, planifique la siguiente actualización dentro de 2027, porque el soporte de 4.0 termina en diciembre de ese año. Quien siga en 3.4 no tiene soporte: su última versión salió el 6 de mayo de 2026, dos semanas antes de que el proyecto publicara, el 20 de mayo, las versiones 3.6.6 y 4.0.0-rc1, centradas en seguridad.32

El OpenSIPS Control Panel

OpenSIPS no tiene interfaz gráfica incorporada. La respuesta del proyecto es el OpenSIPS Control Panel (OCP), "a PHP web portal" (un portal web en PHP) para aprovisionar, operar y monitorear uno o varios servidores OpenSIPS desde una sola instancia.46 Sus herramientas cubren cuentas SIP con alias y permisos, balanceo de carga y conjuntos de dispatcher, planes de marcación y enrutamiento dinámico, registros de llamadas (CDR), estadísticas y trazas SIP, además de integraciones con Monit y Homer.46 Es software GPL-2.0, y su repositorio habla de "more than 18 tools" (más de 18 herramientas).48

Las versiones de OCP están ligadas a las ramas de OpenSIPS: OCP 9.4.0 corresponde a OpenSIPS 4.0 y OCP 9.3.6 a 3.6, y ambas se mantienen.46 9.4.0 se comunica con 4.0 usando los comandos MI renombrados de 4.0. Su herramienta MI Commands pregunta al servidor qué comandos admite y qué conjuntos de parámetros acepta cada uno, y se niega a enviar una llamada que no puede tener éxito. El proyecto aclara que esta comprobación previa "is a usability safeguard, not an access control" (es una protección de usabilidad, no un control de acceso).47

Nuestra opinión: OCP es útil justamente para las tablas de las que trata esta guía: conjuntos de dispatcher, reglas de drouting, suscriptores. Trátelo como una consola administrativa con control total de su enrutamiento SIP y manténgalo fuera de internet público, detrás de una VPN o de un proxy de acceso. Muchos equipos prefieren editar las tablas directamente y mantenerlas bajo control de versiones. Ambos enfoques funcionan, siempre que elija uno de forma deliberada.

Instalaciones típicas

  • Balanceador de carga delante de Asterisk o FreeSWITCH. Es la primera instalación más común y la que la lista de funciones nombra directamente ("SIP front end for gateways/asterisk").1 OpenSIPS recibe todo el tráfico en una dirección, reparte las llamadas nuevas con dispatcher o load_balancer, saca de rotación los equipos caídos y conmuta las llamadas por error. La plantilla incluida loadbalancer.m4 es un punto de partida para este diseño.29
  • Enrutamiento de operadores y mayoristas. drouting elige gateways por prefijo, grupo de llamante, horario y prioridad, y se ocupa del LCR y de la conmutación en serie entre operadores.39 Agregue fraud_detection para umbrales por cliente y stir_shaken para la autenticación de llamadas.4345
  • Controlador de sesión de borde (SBC). topology_hiding oculta la red interna, rtpengine o rtp.io ancla los medios, los módulos B2BUA terminan y reoriginan las llamadas cuando el simple proxy no basta, y 4.0 agrega interoperabilidad de PRACK y UPDATE para operadores orientados a IMS.423110419
  • Registrador y proxy de borde a gran escala. registrar, usrloc y auth_db atienden a grandes cantidades de teléfonos. Con el módulo clusterer, usrloc puede compartir o federar contactos entre nodos.353644

OpenSIPS no contiene nada específico de Estados Unidos ni de Canadá. Los formatos de número, las obligaciones del 911 y la política de STIR/SHAKEN las aplican su script y su operador, no el servidor.

Ejemplo práctico: dos servidores de medios detrás de dispatcher y rtpengine

El escenario: un operador entrega las llamadas entrantes de sus números a una única dirección pública. Detrás hay dos servidores de medios en una red privada, Asterisk o FreeSWITCH, que ejecutan el menú telefónico. OpenSIPS reparte las llamadas nuevas entre ellos, reintenta con el otro servidor si uno falla, saca de rotación a un servidor caído hasta que vuelva a responder a las verificaciones de salud, y retransmite el audio mediante rtpengine. Así, los servidores de medios nunca necesitan una dirección pública.

FunciónDirección (ejemplo)
OpenSIPS y rtpengine, lado público203.0.113.10
OpenSIPS y rtpengine, lado privado10.0.0.10
Servidor de medios A, servidor de medios B10.0.0.21, 10.0.0.22
Direcciones de señalización del operador198.51.100.5, 198.51.100.6

Desplace la tabla hacia los lados para ver todas las columnas.

La configuración está pensada para OpenSIPS 3.6 LTS. Comparamos cada función y cada parámetro de módulo que usa con la documentación de módulos de 4.0 y encontramos las mismas firmas. La única diferencia de 4.0 que afecta a esta guía son los nombres de los comandos MI, que se tratan al final.2425 La construimos a partir de la documentación de los módulos y de las plantillas incluidas. No la hemos ejecutado con un operador real, así que verifíquela con opensips -C y pruébela con su propio tráfico antes de confiar en ella.

1. rtpengine: dos interfaces con nombre

# /etc/rtpengine/rtpengine.conf on the proxy host
[rtpengine]
interface = priv/10.0.0.10;pub/203.0.113.10
listen-ng = 127.0.0.1:2223

La opción interface de rtpengine acepta [NAME/]IP. En el archivo de configuración, varias interfaces van en una misma línea, separadas por punto y coma.33 Las llamamos priv y pub y no internal y external, a propósito. Si no hay interfaces configuradas con esos dos nombres, rtpengine trata los nombres como selectores heredados de IPv4/IPv6, de modo que un error tipográfico fallaría sin mostrar ningún error.34 listen-ng es el socket de control. El manual recomienda enlazarlo a 127.0.0.1.33 Abra UDP 30000 a 40000 en el lado público, el rango de puertos de medios predeterminado de rtpengine.33

2. Los conjuntos de destinos

# /etc/opensips/dbtext/version
table_name(string) table_version(int)
dispatcher:9

# /etc/opensips/dbtext/dispatcher
id(int,auto) setid(int) destination(string) socket(string,null) state(int) probe_mode(int) weight(string) priority(int) attrs(string,null) description(string,null)
1:1:sip\:10.0.0.21\:5060::0:1:1:0::media-a
2:1:sip\:10.0.0.22\:5060::0:1:1:0::media-b
3:2:sip\:198.51.100.5\:5060::0:0:1:0::carrier-1
4:2:sip\:198.51.100.6\:5060::0:0:1:0::carrier-2

Desde que se eliminó el aprovisionamiento antiguo por archivo de texto, dispatcher lee sus destinos únicamente de una base de datos. Para una lista pequeña y estática, la documentación sugiere el controlador db_text, que emula una base de datos con archivos de texto.24 Cada tabla es un archivo. La primera línea declara las columnas, los campos se separan con :, y un dos puntos literal dentro de un valor debe escaparse, de ahí sip\:10.0.0.21\:5060.28 La lista de columnas y la versión de tabla 9 están copiadas del esquema db_text del árbol de código de 3.6, y dispatcher exige la fila version correspondiente.2724

  • El conjunto 1 contiene los dos servidores de medios y el conjunto 2 las direcciones del operador. El conjunto 2 nunca se usa para enrutar. Sirve como lista de permitidos para ds_is_in_list(), de modo que un solo módulo cubre ambas tareas.
  • state 0 significa activo (1 es inactivo y 2 es en sondeo). probe_mode 1 hace que dispatcher envíe pings a ese destino de forma continua, no solo después de un fallo. Lo activamos en los servidores de medios y lo dejamos en 0 para el operador, cuyas direcciones no tenemos motivo para sondear.26
  • Con pesos de 1, el round-robin alterna una llamada para cada uno. Con el algoritmo 4, un destino se elige tantas veces seguidas como su peso.24

3. Parámetros globales y sockets

####### Global parameters #######
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0

udp_workers=4

socket=udp:203.0.113.10:5060     # public: the carrier sends calls here
socket=udp:10.0.0.10:5060        # private: faces the two media servers

Las líneas de registro son los valores predeterminados incluidos: nivel de registro 3, escrito en la facilidad de syslog LOG_LOCAL0.30 udp_workers=4 da cuatro procesos de trabajo por interfaz UDP, es decir ocho aquí, más que suficiente para un clúster de dos servidores.12 Cada línea socket sigue el formato protocolo:dirección[:puerto]. socket reemplazó a listen en 3.1 con el mismo formato, así que los tutoriales antiguos que usan listen= describen lo mismo.12

4. Módulos

####### Modules #######
mpath="/usr/local/lib/opensips/modules/"   # use your package's path

loadmodule "proto_udp.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)

loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"

loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")

loadmodule "db_text.so"
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "text:///etc/opensips/dbtext")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_ping_from", "sip:[email protected]")
modparam("dispatcher", "ds_probing_threshold", 2)

loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223")
  • proto_udp, signaling, sl, tm, rr, maxfwd y sipmsgops son el mismo conjunto básico que cargan las plantillas incluidas.3029
  • fr_timeout 5 y fr_inv_timeout 30 son los valores de la plantilla, no los predeterminados del módulo (30 y 120 segundos).1729 fr_timeout se activa cuando no ha llegado ninguna respuesta final. fr_inv_timeout comienza cuando ya llegó una respuesta provisional, de modo que "fast failover (no 100 trying from gateway) can be achieved by setting fr_timeout to low values" (se puede lograr una conmutación rápida, sin 100 Trying del gateway, fijando fr_timeout en valores bajos).17 En la práctica, un servidor de medios caído produce un 408 en menos de cinco segundos y la llamada pasa al otro.
  • mi_fifo es la interfaz de administración con la que habla opensips-cli. La ruta del FIFO es la de la configuración predeterminada incluida.30
  • ds_ping_interval 10 envía un ping OPTIONS cada diez segundos. El valor predeterminado, 0, desactiva el envío de pings.24 ds_ping_from fija la cabecera From de esos pings.24 ds_probing_threshold es el número de fallos necesarios para que un destino pase a sondeo (3 por defecto). Usamos 2, de modo que dos pings fallidos consecutivos, o llamadas fallidas marcadas en la ruta de fallo, sacan a un servidor de rotación.2426 El servidor vuelve solo: una respuesta 200 a un ping borra el estado de sondeo y reinicia el contador de fallos.26
  • rtpengine_sock apunta al socket listen-ng de rtpengine.31

5. La ruta principal de solicitudes

####### Routing logic #######
route {
    if (!mf_process_maxfwd_header(10)) {
        send_reply(483, "Too Many Hops");
        exit;
    }

    # Who sent this? Set 2 = carrier, set 1 = our media servers.
    $var(from_carrier) = 0;
    if (ds_is_in_list($si, 0, 2)) {
        $var(from_carrier) = 1;
    } else if (!ds_is_in_list($si, 0, 1)) {
        xlog("L_WARN", "dropping $rm from unknown source $si\n");
        exit;
    }

    if (has_totag()) {
        route(in_dialog);
        exit;
    }

    if (is_method("CANCEL")) {
        if (t_check_trans())
            t_relay();
        exit;
    }

    t_check_trans();

    if (is_method("OPTIONS")) {
        send_reply(200, "OK");
        exit;
    }

    if (!is_method("INVITE") || $var(from_carrier) != 1) {
        send_reply(403, "Forbidden");
        exit;
    }

    if ($rU == NULL) {
        send_reply(484, "Address Incomplete");
        exit;
    }

    record_route();

    if (!ds_select_dst(1, 4, "f")) {
        send_reply(503, "No media server available");
        exit;
    }
    $socket_out = "udp:10.0.0.10:5060";

    if (has_body_part("application/sdp"))
        rtpengine_offer("in-iface=pub out-iface=priv replace-origin replace-session-connection");

    t_on_reply("media_answer");
    t_on_failure("next_media_server");
    if (!t_relay())
        send_reply(500, "Internal Error");
    exit;
}
  • mf_process_maxfwd_header(10) agrega una cabecera Max-Forwards de 10 si no hay ninguna; si la hay, la decrementa, y devuelve falso cuando ya es cero, caso que respondemos con 483; esto detiene los bucles de enrutamiento.22 Es la primera verificación de los scripts incluidos.3029
  • Clasificación del origen. ds_is_in_list($si, 0, 2) es verdadero cuando la IP de origen ($si) coincide con una dirección del conjunto 2 en cualquier puerto.2415 Las solicitudes de cualquier dirección que no esté en ninguno de los dos conjuntos se descartan en silencio con exit. Una solicitud que no se reenvía ni se responde se descarta al final de la ruta, y no enviar ninguna respuesta no le da nada a los escáneres SIP.14 $var(from_carrier) se reinicia primero porque las variables de script pueden arrastrar valores del mensaje anterior que procesó el mismo proceso.15
  • has_totag() identifica las solicitudes dentro del diálogo (ACK, BYE, re-INVITE), que van a route[in_dialog].21
  • El CANCEL se retransmite solo si coincide con una transacción que conocemos, como en los scripts incluidos.30 Luego t_check_trans() absorbe las retransmisiones de solicitudes que ya se están procesando.1730
  • Un OPTIONS de cualquiera de los dos lados se responde con un 200, lo que mantiene contentas las verificaciones de salud del operador y de los servidores de medios. Cualquier otra solicitud inicial debe ser un INVITE del operador. Este proxy acepta solo llamadas entrantes, de modo que un servidor de medios comprometido no puede usarlo para hacer llamadas salientes.
  • record_route() mantiene al proxy en la ruta de todas las solicitudes posteriores de la llamada.20 La llamada entra por una interfaz y sale por la otra, así que el módulo rr inserta dos cabeceras Record-Route. enable_double_rr vale 1 por defecto para "two disconnected networks" (dos redes desconectadas).20
  • ds_select_dst(1, 4, "f") elige del conjunto 1 con el algoritmo 4 (round-robin ponderado) y fija el URI de destino. El indicador f guarda los destinos restantes para que ds_next_dst() pueda probarlos después. Sin él no hay a dónde conmutar.24 Los destinos marcados como inactivos o en sondeo se omiten.24
  • $socket_out es escribible, y mientras no se fije, el socket de salida es el de entrada.15 Fijamos explícitamente el socket privado para que el INVITE salga por 10.0.0.10.
  • rtpengine_offer() reescribe el SDP para que el servidor de medios envíe su audio a la dirección privada de rtpengine.31 in-iface y out-iface nombran la interfaz por la que entró el mensaje y por la que sale.31 La dirección solo hay que indicarla en la oferta inicial, porque rtpengine la recuerda durante el resto de la llamada.34 replace-origin y replace-session-connection reescriben además la línea o= del SDP y la línea c= de nivel de sesión.31 Primero comprobamos has_body_part("application/sdp").21
  • t_on_reply() y t_on_failure() activan las rutas de respuesta y de fallo. t_relay() crea la transacción y reenvía la solicitud.17 Si el reenvío falla de inmediato, respondemos 500. send_reply() está permitido en una ruta de solicitud.19

6. Solicitudes dentro del diálogo

route[in_dialog] {
    if (is_method("ACK") && t_check_trans()) {
        t_relay();
        exit;
    }

    if (!loose_route()) {
        send_reply(404, "Not here");
        exit;
    }

    if ($var(from_carrier) == 1)
        $socket_out = "udp:10.0.0.10:5060";
    else
        $socket_out = "udp:203.0.113.10:5060";

    if (is_method("BYE")) {
        rtpengine_delete();
    } else if (is_method("INVITE") && has_body_part("application/sdp")) {
        rtpengine_offer("replace-origin replace-session-connection");
        t_on_reply("media_answer");
    }

    if (!t_relay())
        send_reply(500, "Internal Error");
}
  • El orden ACK y luego loose_route() es el modo habitual de los scripts incluidos. Un ACK que coincide con una transacción es un ACK salto a salto para una respuesta negativa. Cualquier otra solicitud dentro del diálogo debe llevar nuestras cabeceras Route, o recibe un 404.3020
  • El socket de salida se fija según la dirección de la solicitud en lugar de deducirse: las solicitudes del operador salen por el lado privado y las de un servidor de medios salen por el lado público.15
  • Un BYE desmonta la sesión de rtpengine.31 Un re-INVITE con SDP (retención o cambio de códec) es una oferta nueva, y su respuesta pasa por la misma ruta de respuesta.

7. Respuestas y conmutación por error

onreply_route[media_answer] {
    if (has_body_part("application/sdp"))
        rtpengine_answer("replace-origin replace-session-connection");
}

failure_route[next_media_server] {
    if (t_was_cancelled()) {
        rtpengine_delete();
        exit;
    }

    if (t_check_status("(408)|(5[0-9][0-9])")) {
        if (t_check_status("408"))
            ds_mark_dst("p");

        if (ds_next_dst()) {
            $socket_out = "udp:10.0.0.10:5060";
            t_on_reply("media_answer");
            t_on_failure("next_media_server");
            t_relay();
            exit;
        }
    }

    rtpengine_delete();
}
  • rtpengine_answer() se ejecuta en cualquier respuesta con SDP (183 o 200) y reescribe la respuesta del servidor de medios para que el operador envíe el audio a la dirección pública de rtpengine.31
  • En la ruta de fallo, t_was_cancelled() significa que quien llamaba colgó antes de que se contestara, así que limpiamos la sesión de medios y nos detenemos.17
  • t_check_status() compara la respuesta negativa ganadora.17 Ante un tiempo de espera (408) o cualquier 5xx probamos con el siguiente servidor de medios. Solo el tiempo de espera cuenta en contra del servidor mediante ds_mark_dst("p"), porque un 503 puede ser un rechazo deliberado de un equipo que sigue vivo.24
  • ds_next_dst() carga el siguiente destino guardado por el indicador f.24 La ruta de fallo trabaja sobre la solicitud original tal como se envió, así que el segundo intento lleva el mismo SDP reescrito y la misma sesión de rtpengine se completa cuando B contesta.14 Volvemos a activar la ruta de fallo, como hace la plantilla incluida, para que un segundo fallo también se maneje.29
  • Para cualquier otra respuesta negativa (486 ocupado, 404, o ambos servidores fallaron), se elimina la sesión de medios y la ruta termina. Por defecto, la respuesta negativa ganadora vuelve entonces al operador.14 send_reply() no está permitido en una ruta de fallo. Si quiere una respuesta final personalizada allí, use t_reply().1917

8. Verificación y operación

# check the script without starting the server
opensips -C -f /etc/opensips/opensips.cfg

# once running: list the destinations and their state (3.6 name)
opensips-cli -x mi ds_list

# take media-b out of rotation for maintenance, then bring it back
opensips-cli -x mi ds_set_state i 1 sip:10.0.0.22:5060
opensips-cli -x mi ds_set_state a 1 sip:10.0.0.22:5060

# after editing the dispatcher table
opensips-cli -x mi ds_reload

-c verifica el archivo de configuración. -C comprueba además que cada función se use solo en rutas que lo permiten, lo que detecta errores como llamar a send_reply() en una ruta de fallo.16 En 3.6, los comandos MI de dispatcher son ds_list, ds_set_state y ds_reload. En 4.0 son dispatcher:list, dispatcher:set_state y dispatcher:reload, y los nombres antiguos están documentados como obsoletos.2425 ds_reload conserva el estado actual de los destinos, a menos que se pase inherit_state=n.24

En los servidores de medios, acepte llamadas solo desde 10.0.0.10 y trate esa dirección como su troncal. Verán cada llamada llegar desde el proxy, con el audio proveniente de la dirección privada de rtpengine.

Lo que este ejemplo deja fuera deliberadamente

TLS y SRTP hacia el operador, llamadas con oferta tardía (un INVITE sin SDP, cuya oferta llega en el 200 y cuya respuesta llega en el ACK, algo que las funciones de rtpengine también admiten),31 autenticación digest del operador, limitación de tasa, CDR con acc y alta disponibilidad. Un solo equipo proxy es un punto único de fallo. Para alta disponibilidad, empareje dos equipos con una dirección flotante y replique el estado de dispatcher con el módulo clusterer.2444 Si prefiere no manejar usted mismo la oferta y la respuesta, rtp_relay_engage("rtpengine") en el INVITE inicial entrega toda la sesión de medios al módulo rtp_relay. Requiere el módulo dialog.32

Una nota sobre la plantilla incluida

Leímos la plantilla loadbalancer.m4 incluida en la rama 3.6 mientras escribíamos esto, y encontramos dos problemas que conviene conocer si parte de ella. En modo dispatcher llama a ds_select_dst(1,4) sin el indicador f, pero su ruta de fallo depende de ds_next_dst(). Además define DISABLE_PINGING mientras que las condicionales comprueban DISABLE_PROBING, de modo que el interruptor de "sin pings" no tiene efecto.29 Según la documentación de dispatcher, el primer problema significa que la conmutación por error no tiene un destino alternativo al que pasar.24 Las mismas líneas están presentes hoy en la rama master.5

OpenSIPS y Kamailio: mismas raíces, distinto rumbo

Kamailio se llama a sí mismo el "successor of former OpenSER and SER" (sucesor de los antiguos OpenSER y SER) y tiene licencia GPLv2+. Su última versión es la 6.1.5, con fecha del 15 de octubre de 2026.49 OpenSIPS se describe como la continuación de OpenSER.8 Ambas afirmaciones son históricamente defendibles.

Las diferencias tienen que ver sobre todo con dónde ha puesto su esfuerzo cada proyecto. Estas son las que podemos documentar con fuentes de primera mano:

  • Scripts. El marco KEMI de Kamailio, introducido en 5.0.0, permite escribir la lógica de enrutamiento en JavaScript, Lua, Python, Ruby o Squirrel en lugar del lenguaje de configuración nativo.50 El enrutamiento de OpenSIPS se escribe en su lenguaje de script nativo, como todo lo de esta guía.
  • Funciones de aplicación incorporadas. OpenSIPS tiene un B2BUA de dos capas en el árbol principal, un relé RTP dentro del proceso desde 3.6 y un panel de control web oficial que se mantiene junto con cada versión.401046
  • Disciplina de versiones. OpenSIPS publica un calendario escrito con ramas LTS de tres años e indica en una sola página qué ramas tienen soporte y hasta cuándo.43

Nuestra opinión: elija según el equipo y el ecosistema, no según una prueba de rendimiento. Si sus ingenieros prefieren escribir el enrutamiento en Python o Lua, KEMI de Kamailio es una ventaja real. Si quiere funciones de B2BUA, un panel y una fecha LTS predecible en un solo proyecto, OpenSIPS es el paquete más completo. Creemos que el proxy rara vez es el cuello de botella con cualquiera de los dos proyectos; lo son los servidores de medios que están detrás.

Cuando OpenSIPS no es la herramienta adecuada

  • Una central, una sede. Un solo equipo Asterisk o FreeSWITCH puede registrar sus propios teléfonos y hablar con su propia troncal. Agregar un proxy delante duplica la cantidad de cosas que hay que proteger y depurar, y no aporta ningún beneficio hasta que tenga más de un servidor de medios o un borde hacia el operador que proteger.
  • Necesita IVR, buzón de voz o grabación. OpenSIPS enruta señalización. No contesta llamadas con mensajes grabados. Eso es tarea de una central, de un servidor de medios o de un servicio alojado.
  • Nadie en el equipo se hará cargo del script. Una configuración de OpenSIPS es código y exige el mismo cuidado: control de versiones, revisión, un entorno de pruebas y alguien que lea las notas de cada versión. El riesgo no es que OpenSIPS falle. Es un error de enrutamiento que nadie entiende lo bastante bien como para verlo.

Para una empresa que solo quiere que su número lo conteste un menú telefónico que envíe a quienes llaman con la persona indicada, cualquiera de estas pilas es más maquinaria de la que el problema necesita. Ese es el hueco que llena una operadora automática (auto attendant) alojada. La nuestra es una, y cómo funciona describe lo que hace.

Fuentes

Cada afirmación sobre normas o precios en esta página enlaza a su fuente primaria, a menudo en inglés. Las normas y los precios cambian: verifique antes de confiar en una cifra.

  1. Proyecto OpenSIPS, "About OpenSIPS" (la lista de funciones: registrador, proxy, servidor de redirección, agente de presencia, agente de usuario back-to-back, balanceador de carga, front end para Asterisk, unidad de traversal de NAT, servidor de aplicaciones). Consultado el 26 de octubre de 2026
    https://opensips.org/About/About
  2. Página principal del proyecto OpenSIPS (autodescripción; noticias de la versión estable 4.0.0 del 23 de junio de 2026, de 4.0.0-rc1 y 3.6.6, centradas en seguridad, del 20 de mayo de 2026, y de 4.0.2 y 3.6.9 del 8 de septiembre de 2026). Consultado el 26 de octubre de 2026
    https://www.opensips.org/
  3. Proyecto OpenSIPS, "Available versions" (fechas de publicación, etiquetas LTS, última versión y fin del soporte de cada rama; 4.1.0-dev en master). Consultado el 26 de octubre de 2026
    https://opensips.org/About/AvailableVersions
  4. Proyecto OpenSIPS, política de versiones (ciclo mayor de un año, versiones estándar con soporte de 1,5 años, LTS de 3 años, numeración par/impar y sus excepciones). Página modificada por última vez el 6 de noviembre de 2020. Consultado el 26 de octubre de 2026
    https://opensips.org/Development/Development
  5. Repositorio de código de OpenSIPS en GitHub (descripción del repositorio, código en C, ramas 1.4 a 4.0 más master, etiquetas hasta 4.0.2 y 3.6.9). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips
  6. Repositorio de OpenSIPS, COPYING (GNU GPL versión 2; "OpenSIPS software is derived from SER (SIP Express Router) project developed by FhG FOKUS"). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/blob/master/COPYING
  7. Proyecto Kamailio, "History" (SER nació el 2 de septiembre de 2001 en FhG Fokus, se publicó bajo GPL en otoño de 2002, OpenSER comenzó el 14 de junio de 2005, se rebautizó Kamailio el 28 de julio de 2008, la bifurcación OpenSIPS, Kamailio 3.0.0 el 11 de enero de 2010, integración de SER completada el 20 de diciembre de 2012). Consultado el 26 de octubre de 2026
    https://www.kamailio.org/w/history/
  8. Archivo de la lista de correo de usuarios de Kamailio, "OpenSIPS project", 4 de agosto de 2008: el fundador de OpenSIPS en Voice System anuncia el nuevo proyecto y su primera versión, 1.4.0. 4 de agosto de 2008; consultado el 26 de octubre de 2026 mediante nuestro router de extracción web (el archivo de la lista de opensips.org devolvió HTTP 502)
    https://lists.kamailio.org/pipermail/users/2008-August/018804.html
  9. Proyecto OpenSIPS, "Version overview 4.0.0" (TCP multihilo, TLS, perfilado, sockets bond, ramas dinámicas de TM, PRACK/UPDATE, Proxy Protocol, auth_web3, replicación cluster-bridge, wolfSSL como opción predeterminada de stir_shaken). Consultado el 26 de octubre de 2026
    https://opensips.org/About/Version-Overview-4-0-0
  10. Proyecto OpenSIPS, "Version overview 3.6.0" (LTS; sockets dinámicos, retransmisión de medios rtp.io dentro del proceso, variables $config, Redis, AWS, Janus, ramificación unificada, SDP estructurado). Consultado el 26 de octubre de 2026
    https://opensips.org/About/Version-Overview-3-6-0
  11. Blog de OpenSIPS, "TCP/TLS rework in OpenSIPS 4.0", 8 de abril de 2026. 8 de abril de 2026
    https://blog.opensips.org/2026/04/08/tcp-tls-rework-in-opensips-4-0/
  12. Manual de OpenSIPS 3.6, Core parameters (socket, udp_workers, tcp_workers, timer_workers, auto_scaling_profile, log_level, mpath; listen reemplazado por socket en 3.1; 32 MB de memoria compartida por defecto). La página de 4.0 agrega tcp_threads. Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/script-coreparameters/
  13. Manual de OpenSIPS 4.0, Core parameters (tcp_workers y tcp_threads bajo el diseño TCP de 4.0). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/script-coreparameters/
  14. Manual de OpenSIPS 3.6, Script routes (route, branch_route, failure_route, onreply_route, error_route, local_route, startup_route, timer_route, event_route; disparadores y acciones predeterminadas). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/script-routes/
  15. Manual de OpenSIPS 3.6, Core variables (alcance e inicialización de $var, $si, $socket_in, $socket_out de lectura y escritura). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/script-corevar/
  16. Repositorio de OpenSIPS, página de manual opensips.8, rama 3.6 (-f, -c, -C, -m). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/blob/3.6/opensips.8
  17. Documentación del módulo TM de OpenSIPS 3.6 (procesamiento con estado, clones en memoria compartida, t_relay, t_reply, t_check_status, t_was_cancelled, t_on_failure, valores predeterminados de fr_timeout y fr_inv_timeout). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/tm/
  18. Documentación del módulo SL de OpenSIPS 3.6 (respuestas sin estado). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/sl/
  19. Documentación del módulo SIGNALING de OpenSIPS 3.6 (send_reply y las rutas desde las que puede usarse). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/signaling/
  20. Documentación del módulo RR de OpenSIPS 3.6 (record_route, loose_route, enable_double_rr con valor predeterminado 1). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/rr/
  21. Documentación del módulo SIPMSGOPS de OpenSIPS 3.6 (is_method, has_totag, has_body_part). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/sipmsgops/
  22. Documentación del módulo MAXFWD de OpenSIPS 3.6 (mf_process_maxfwd_header agrega la cabecera si falta, la decrementa y devuelve falso al llegar a 0). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/maxfwd/
  23. Documentación del módulo DIALOG de OpenSIPS 4.0 (create_dialog, terminación por BYE o default_timeout, perfilado). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/dialog/
  24. Documentación del módulo DISPATCHER de OpenSIPS 3.6 (algoritmos 0 a 10, flags, ds_next_dst, ds_mark_dst, ds_is_in_list, parámetros de sondeo, pesos por FreeSWITCH ESL, comandos MI ds_list y ds_reload, aprovisionamiento con db_text). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/dispatcher/
  25. Documentación del módulo DISPATCHER de OpenSIPS 4.0 (mismas funciones y parámetros; comandos MI renombrados dispatcher:list, dispatcher:reload, dispatcher:set_state). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/dispatcher/
  26. Código de OpenSIPS, modules/dispatcher/dispatch.c, rama 3.6 (valores de las columnas state y probe_mode; manejo de la respuesta a OPTIONS que devuelve un destino a activo; el umbral de sondeo). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/blob/3.6/modules/dispatcher/dispatch.c
  27. Código de OpenSIPS, scripts/dbtext/opensips/dispatcher y scripts/dbtext/opensips/version, rama 3.6 (columnas de la tabla dispatcher; versión de tabla 9). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/tree/3.6/scripts/dbtext/opensips
  28. Documentación del módulo DB_TEXT de OpenSIPS 3.6 (URL text://, formato de archivo de tabla, escape de ":"). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/db_text/
  29. Código de OpenSIPS, examples/templates/loadbalancer.m4, rama 3.6 (la plantilla de balanceador de carga incluida). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/blob/3.6/examples/templates/loadbalancer.m4
  30. Código de OpenSIPS, etc/opensips.cfg, rama 3.6 (el script residencial incluido: estructura de secciones, modo de manejar las solicitudes dentro del diálogo). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips/blob/3.6/etc/opensips.cfg
  31. Documentación del módulo RTPENGINE de OpenSIPS 3.6 (rtpengine_sock, conjuntos y conmutación por error, rtpengine_offer/answer/delete/manage, in-iface y out-iface, replace-origin, replace-session-connection). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/3-6/modules/rtpengine/
  32. Documentación del módulo RTP_RELAY de OpenSIPS 4.0 (rtp_relay_engage, dependencia del diálogo, el motor interno "route" agregado en 3.6). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/rtp_relay/
  33. Manual de Sipwise rtpengine (sintaxis --interface NAME/IP y su forma en archivo de configuración, --listen-ng, valores predeterminados de port-min y port-max: 30000 y 40000). Consultado el 26 de octubre de 2026 (también leído en rtpengine.readthedocs.io)
    https://github.com/sipwise/rtpengine/blob/master/docs/rtpengine.md
  34. Sipwise rtpengine, "ng control protocol" (la dirección solo se necesita en la oferta inicial; significado heredado de los nombres internal y external). Consultado el 26 de octubre de 2026
    https://rtpengine.readthedocs.io/en/latest/ng_control_protocol.html
  35. Documentación del módulo REGISTRAR de OpenSIPS 4.0 (procesamiento de REGISTER según RFC 3261, soporte de Path según RFC 3327). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/registrar/
  36. Documentación del módulo USRLOC de OpenSIPS 4.0 (almacenamiento en memoria, SQL o NoSQL; working_mode_preset; ubicación de usuarios distribuida desde 2.4). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/usrloc/
  37. Documentación del módulo AUTH_DB de OpenSIPS 4.0 (autenticación digest respaldada por base de datos; SHA-256 y SHA-512-256 de RFC 8760 desde 3.2). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/auth_db/
  38. Documentación del módulo LOAD_BALANCER de OpenSIPS 4.0 (enrutamiento por carga según el mayor espacio disponible, modos de sondeo, dependencia del diálogo). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/load_balancer/
  39. Documentación del módulo DROUTING de OpenSIPS 4.0 (reglas por prefijo, grupo de llamante, horario y prioridad; enrutamiento de menor costo como caso especial; sondeo de gateways). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/drouting/
  40. Documentación del módulo B2B_ENTITIES de OpenSIPS 4.0 (la capa inferior del B2BUA: entidades de servidor y de cliente). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/b2b_entities/
  41. Documentación del módulo B2B_LOGIC de OpenSIPS 4.0 (la capa superior del B2BUA, escenarios dirigidos por script, control de llamadas de terceros por MI). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/b2b_logic/
  42. Documentación del módulo TOPOLOGY_HIDING de OpenSIPS 4.0 (eliminación de Via, Record-Route y Route; topology_hiding_match para solicitudes dentro del diálogo). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/topology_hiding/
  43. Documentación del módulo FRAUD_DETECTION de OpenSIPS 4.0 (cinco parámetros monitoreados por usuario y prefijo, umbrales de advertencia y críticos; depende de drouting y dialog). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/fraud_detection/
  44. Documentación del módulo CLUSTERER de OpenSIPS 4.0 (malla de nodos a nivel BIN, capacidades y sincronización de datos, replicación cluster-bridge agregada en 4.0). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/clusterer/
  45. Documentación del módulo STIR_SHAKEN de OpenSIPS 4.0 (servicios de autenticación y verificación, RFC 8224 y RFC 8588). Consultado el 26 de octubre de 2026
    https://docs.opensips.org/manual/4-0/modules/stir_shaken/
  46. Sitio de OpenSIPS Control Panel (portal PHP para aprovisionar y monitorear varios servidores OpenSIPS; tabla de compatibilidad de versiones; lista de herramientas). Consultado el 26 de octubre de 2026
    https://controlpanel.opensips.org/
  47. Blog de OpenSIPS, "The MI Commands tool in Control Panel 9.4.0", 12 de agosto de 2026. 12 de agosto de 2026
    https://blog.opensips.org/2026/08/12/the-mi-commands-tool-in-control-panel-9-4-0/
  48. Repositorio de código de OpenSIPS Control Panel en GitHub (licencia GPL-2.0; "more than 18 tools"). Consultado el 26 de octubre de 2026
    https://github.com/OpenSIPS/opensips-cp
  49. Página principal del proyecto Kamailio ("successor of former OpenSER and SER", GPLv2+, última versión 6.1.5 del 15 de octubre de 2026). Consultado el 26 de octubre de 2026
    https://www.kamailio.org/w/
  50. Kamailio, tutorial "KEMI framework" (lógica de enrutamiento en JavaScript, Lua, Python, Ruby o Squirrel; introducido en Kamailio 5.0.0). Consultado el 26 de octubre de 2026
    https://kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/