Javier Valencia Javier Valencia
Ilustración minimalista de dos teléfonos unidos por dos líneas separadas, una gris de señalización y otra terracota de audio, que no siguen el mismo camino

El viaje de una llamada: qué pasa de verdad cuando marcas

Javier Valencia · · 8 min de lectura · 3 visitas · Desarrollo
voip sip asterisk kamailio redes telecomunicaciones desarrollo tutorial

Llevo la mitad de mi vida profesional metido en telefonía sobre IP y sigo encontrándome con la misma escena. Un desarrollador competente, que sabe de sobra cómo funciona HTTP, se sienta delante de un problema de VoIP y se queda bloqueado en el mismo sitio: la llamada se establece perfectamente y no se oye nada. Y entonces mira los logs de señalización, los ve limpios, y concluye que ahí no hay ningún problema.

Ahí está el problema. La conclusión correcta es la contraria: si la señalización está impecable y no hay audio, es que la señalización no tiene nada que ver con el audio. Van por caminos distintos, por protocolos distintos, y muy a menudo por rutas de red distintas. Todo el resto de este post sale de esa frase.

Vamos a seguir una llamada desde que alguien marca hasta que cuelga, y luego a romperla de las cuatro maneras en que se rompe en el mundo real.

SIP se parece a HTTP más de lo que crees

Lo primero que tranquiliza a un desarrollador es descubrir que SIP es texto plano y con una estructura casi idéntica a HTTP. Peticiones con un método, cabeceras Nombre: valor, un cuerpo opcional, y respuestas con código numérico. Si sabes leer una petición HTTP, sabes leer una SIP en cinco minutos.

Los métodos que importan son pocos. REGISTER, que es como un teléfono le dice a la centralita dónde está. INVITE, que inicia una llamada. ACK, que la confirma. BYE, que la termina. CANCEL, para abortar un INVITE que aún no ha sido respondido. OPTIONS, que en la práctica se usa como un ping.

Y los códigos de respuesta te van a sonar de casa, con una salvedad importante: en SIP los 1xx son provisionales y puedes recibir varios antes de la respuesta final. 100 Trying («te he oído, estoy en ello»), 180 Ringing («está sonando»), 183 Session Progress («te mando ya algo de audio»). Después llegan los definitivos: 200 OK, o un 401/407 pidiendo autenticación, un 404, un 486 Busy Here, un 487 Request Terminated si alguien canceló, o un 603 Decline.

La llamada, paso a paso

Marco un número. Mi teléfono manda un INVITE a la centralita. Y ese INVITE lleva un cuerpo que es donde está toda la chicha, porque es donde se negocia el audio.

Ese cuerpo es SDP, y es una descripción de sesión, no un protocolo de transporte. En cristiano, mi teléfono está diciendo: «voy a escuchar audio en esta dirección IP, en este puerto UDP, y sé hablar estos codecs, en este orden de preferencia». Es una oferta. El otro extremo responderá con una respuesta en el mismo formato, quedándose con los codecs que también entiende y diciendo dónde quiere recibir él.

La secuencia completa de una llamada que va bien es esta:

Llamante                    Centralita                   Llamado
   |------------ INVITE (oferta SDP) ------>|
   |<----------- 100 Trying ----------------|
   |                        |------------ INVITE -------->|
   |<----------- 180 Ringing ---------------|<-- 180 -----|
   |<----------- 200 OK (respuesta SDP) ----|<-- 200 OK --|
   |------------ ACK ---------------------->|---- ACK --->|
   |                                                       |
   |<========== RTP: audio bidireccional ==================>|
   |                                                       |
   |------------ BYE ---------------------->|---- BYE ---->|
   |<----------- 200 OK --------------------|<-- 200 OK ---|

Fíjate en dos cosas de este diagrama, que son las que a mí me parecen las importantes de todo el protocolo.

La primera: el establecimiento es un saludo de tres pasos, INVITE → 200 OK → ACK, exactamente por la misma razón que TCP hace el suyo. Sin ese ACK final, el que respondió no sabe si su respuesta llegó.

La segunda, y es la buena: la línea del audio es otra línea. Cuando el ACK termina, la señalización SIP ha hecho su trabajo y se calla hasta que alguien cuelgue. El audio empieza entonces a fluir por RTP, normalmente sobre UDP, entre las direcciones y puertos que se acordaron en el SDP. Puede pasar por la centralita o no pasar. Puede ir por otra ruta de red completamente distinta. SIP no transporta voz: solo negocia por dónde va a ir la voz.

Por eso la escena del principio. Los logs de señalización dicen que todo fue bien porque todo fue bien: hubo acuerdo. Que después los paquetes de audio no lleguen a la dirección acordada es un problema de otro plano, y no se ve en los logs de SIP.

Rotura número uno: NAT

Aquí está, sin discusión posible, la causa de la mitad de las incidencias de VoIP que he visto en veinticinco años.

Recuerda lo que decía el SDP: «mándame el audio a esta IP y este puerto». Ahora piensa en un teléfono detrás del router de una casa. La IP que ese teléfono conoce de sí mismo es 192.168.1.40. Así que anuncia, tan tranquilo, que el audio se lo manden a 192.168.1.40.

El operador recibe esa dirección. Y 192.168.1.40 no significa nada en internet. El audio se envía a ninguna parte. La señalización, en cambio, ha funcionado sin problema, porque viajó por una conexión que el propio teléfono inició y el NAT sabía devolver.

El resultado clásico es el audio en un solo sentido: uno oye y el otro no. Y hay una variante todavía más desconcertante, la llamada que se corta exactamente a los treinta segundos, que casi siempre significa que el agujero que el NAT abrió para la señalización se cerró por inactividad y el BYE no encontró el camino de vuelta.

Las soluciones existen y son todas parches razonables. Reescribir en el servidor la IP anunciada por la que se ve de verdad venir. Los mecanismos de la familia STUN/TURN/ICE, que es como lo resuelve WebRTC en el navegador. Mantener el agujero abierto con paquetes de keepalive. Y la que en telefonía de operador se acaba usando casi siempre: meter un relé de medios en medio, un proceso que recibe el RTP de los dos lados y lo reenvía, de forma que ninguno de los dos necesita saber la dirección real del otro.

Ese relé es cómodo y es caro: cada llamada te consume ancho de banda simétrico en tu propia máquina, y multiplicar eso por miles de llamadas simultáneas es una partida de infraestructura seria.

Rotura número dos: confundir un proxy con una centralita

Esta es más conceptual y te ahorra dimensionar mal una plataforma entera.

Un proxy SIP —el ejemplo canónico es Kamailio— encamina señalización. Recibe un INVITE, decide adónde mandarlo, lo manda y se aparta. No termina la llamada, no participa en ella y, salvo que se lo pidas expresamente, no toca el audio en absoluto. Por eso una máquina modesta con Kamailio maneja volúmenes de señalización que parecen mentira: está moviendo mensajes de texto, no voz.

Un B2BUA —Asterisk es el ejemplo que todo el mundo conoce— hace otra cosa completamente distinta. Termina la llamada que le llega y origina una nueva hacia el destino. Se pone en medio de verdad. Y como está en medio, puede hacer todo lo que la gente quiere de una centralita: menús de voz, grabación, colas, transferencias, música en espera, transcodificar entre codecs. El precio es que cada llamada consume recursos reales en esa máquina, y el techo de capacidad baja en un orden de magnitud o dos.

La arquitectura que acaba montando todo el mundo cuando crece es la combinación de las dos: el proxy delante como frontera y balanceador, los B2BUA detrás haciendo el trabajo de aplicación. Poner Asterisk a hacer de frontera de internet para diez mil abonados es un error caro, y ponerle a Kamailio la responsabilidad de un IVR es pedirle algo que no es.

Rotura número tres: los codecs

Un codec es cómo se comprime la voz, y la elección tiene consecuencias que se ven en la factura.

G.711 es la referencia: sin compresión real, unos 64 kbps por sentido, calidad de telefonía clásica y coste de CPU prácticamente nulo. G.729 comprime muchísimo más, alrededor de 8 kbps, a costa de calidad y de un poco de CPU. Opus es el moderno, se adapta al ancho de banda disponible y suena claramente mejor, y es lo que usa WebRTC.

El problema no es elegir uno. El problema es la transcodificación: cuando un lado habla G.711 y el otro solo entiende G.729, alguien en medio tiene que descomprimir y volver a comprimir cada paquete, cada veinte milisegundos, para cada llamada. Eso deja de ser gratis rapidísimo. He visto plataformas enteras arrodillarse por una configuración de codecs mal puesta que obligaba a transcodificar llamadas que podrían haber pasado de largo.

La regla práctica: si consigues que los dos extremos se pongan de acuerdo en el mismo codec, la centralita solo mueve paquetes. Y mover paquetes es baratísimo comparado con procesarlos.

Rotura número cuatro: creer lo que dice la cabecera

Y la última, que hoy tiene además consecuencias regulatorias.

En un INVITE, el número que aparece como llamante viaja en cabeceras que el que origina la llamada rellena a voluntad. El protocolo no tiene, de origen, ninguna manera de verificar que quien dice llamar desde un número tiene derecho a usarlo. Sobre esa debilidad de diseño se ha construido la industria entera del fraude telefónico, y de ahí vienen las obligaciones de bloqueo que ya comenté al hablar de la Orden TDF/149/2025.

Para un desarrollador que integra telefonía, la traducción es corta y conviene tatuársela: el número llamante que te llega es un dato de entrada no confiable. Tratarlo como una identidad es el mismo error que confiarse de una cabecera HTTP que manda el cliente.

Cómo se depura esto

Termino con lo práctico, que es lo que a mí me habría gustado que alguien me dijera en 2002.

Captura siempre los dos planos a la vez. Un tcpdump que se quede solo con el puerto de señalización te va a enseñar una llamada perfecta y no vas a ver el problema. Captura la señalización y el RTP, y ábrelo con una herramienta que sepa reconstruir el flujo: verás el diagrama de arriba dibujado solo, y verás si hay paquetes de audio y en qué dirección.

Lee el SDP antes que ninguna otra cosa. Nueve de cada diez incidencias de «no se oye» se resuelven mirando qué dirección IP se anunció en el SDP y preguntándose si esa dirección es alcanzable desde el otro extremo. Si ahí ves una IP privada, ya has terminado de depurar.

Cuenta paquetes, no llamadas. La métrica que de verdad predice la calidad no es cuántas llamadas hay, es el jitter y la pérdida de paquetes del RTP. Un uno por ciento de pérdida ya se oye. Instrumenta eso, como cualquier otro servicio, y tendrás un cuadro de mando que dice la verdad en vez de un teléfono sonando con un cliente enfadado.

Y sobre todo, la idea que abre y cierra este post: la señalización y el audio son dos mundos. El día que interiorizas eso, la telefonía sobre IP deja de ser magia negra y se convierte en lo que es: dos protocolos sencillos, uno de los cuales lleva treinta años sufriendo el NAT con paciencia franciscana.