Está en la página 1de 24

Cuarta Parte – Archivo de Configuración y Arquitectura de Kamailio

En la segunda parte de este modulo semanal hemos visto una primera configuración de Kamailio. En la
presente parte se completará la información intentando explicar más detenidamente como está
organizado y como funciona el archivo de configuración.

Como se ha dicho anteriormente, el archivo se divide en tres bloques:

• el primer bloque es donde se configuran los parámetros globales de Kamailio


• el segundo bloque es donde se configuran los módulos con relativos parámetros
• el tercer bloque es el script que procesará cada petición SIP que llegue o salga del servidor
(routing block)

Hay que aclarar que para aplicar cualquier cambio realizado en el archivo de configuración
kamailio.cfg, hay que reiniciar el Proxy SIP. Siendo esta una limitación muy importante, los
desarrolladores de Kamailio han creado un Framework, KEMI, que permite escribir la lógica de routing
de las solicitudes SIP utilizando distintos lenguajes de programación. Para cada lenguaje se ha creado
un modulo dedicado; ejemplo, para el lenguaje LUA el modulo es APP_LUA. Utilizando KEMI, en el
archivo kamailio.cfg quedará solamente la configuración de los:

• parámetros globales
• módulos y respectivos parámetros

pues solamente si se modificarán estos datos será obligatorio reiniciar Kamailio sino no; esto porque
KEMI permite leer la lógica de enrutamiento escrita en uno de los lenguajes de programación
soportados, cada vez que se necesite.

En el primer bloque es también donde se declaran unas sentencias que definirán que módulos, variables
y que partes del script de Kamailio se activarán/utilizarán. Este sistema es muy cómodo porque con
solo añadir/comentar una linea, se activan/desactivan parámetros globales, se activan/desactivan
módulos, se activan/desactivan piezas del script donde se procesan las solicitudes SIP. Las sentencias
que se pueden utilizar son:

• #!define NAME – Para definir un palabra clave


• #!define NAME VALUE – Para asociar a una palabra clave un determinado valor
• #!ifdef NAME – Para averiguar si una palabra clave ha sido definida
• #!ifndef - Para averiguar si una palabra clave no ha sido definida
• #!else – si una condición no se verifica en una declaración #!ifdef o #!ifndef se procesa el
bloque que inicia con esta sentencia, si presente
• #!endif – Para terminar el procesamiento de un bloque que se ha iniciado con una sentencia
#ifdef o #!ifndef
• #!trydef – Para añadir una sentencia si no ha sido ya definida
• #!redefine – Para forzar una nueva definición de una sentencia aunque ya ha sido definida
• #!substdef – Sustituye el valor de una cadena con un valor. Ejemplo: #!substdef
"/IPPRIVADA/192.168.1.1/" El Valor de IPPRIVADA será 192.168.1.1

1
Tomamos algunos ejemplos presentes en el archivo de configuración predefinido de Kamailio. El
primero que encontramos (Linea 24) es él que nos indica que si queremos trabajar en modo DEBUG,
útil cuando se quiere localizar/resolver un problema de funcionamiento, tenemos que crear la sentencia:

#!define WITH_DEBUG

Si esa sentencia está presente luego en este bloque (desde la linea 132):

#!ifdef WITH_DEBUG
#!define DBGLEVEL 3
#!else
#!define DBGLEVEL 2
#!endif

se aplicará la siguiente lógica: si la sentencia WTH_DEBUG está definida/activada se iniciará


Kamailio en modo debug 3 y los errores se enviarán a la salida estándar de Linux para los errores; si la
sentencia WITH_DEBUG no está definida (#!else) el nivel de debug será 2 y no se enviarán los errores
a la salida estándar de Linux. Con #!endif se termina el procesamiento del bloque.

Otro bloque interesante es (desde la linea 138):

#!ifdef WITH_MYSQL
# - database URL - used to connect to database server by modules such
# as: auth_db, acc, usrloc, a.s.o.
#!trydef DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
#!endif

que se activará solamente si la sentencia:

#!define WITH_MYSQL

está presente antes de ese bloque. La lógica es: si la sentencia WITH_MYSQL está definida se procesa
el bloque a seguir donde si la sentencia DBURL no está definida, #!ifndef, se define indicando que a la
palabra clave DBURL se asocia la URL para la conexión a la base de datos de kamailio que se ha
creado anteriormente. A seguir se utilizan dos #!endif, uno para cerrar la sentencia #!ifdef y otro para
cerrar la sentencia #!ifndef. De esta forma en la configuración de los módulos que pueden trabajar con
la base de datos, en lugar de indicar la URL de conexión completa, es suficiente poner (ejemplo para el
modulo USRLOC, linea 408):

modparam("usrloc", "db_url", DBURL)

Veremos más ejemplos a lo largo de la configuración de Kamailio. Analizamos ahora los parámetros
globales más importantes que aparecen en nuestro archivo de configuración teniendo en cuenta también
las sentencias ya definidas (Linea 127):

import_file "kamailio-local.cfg"

2
Importa el contenido del archivo indicado antes de analizar la sintaxis (parsear) el archivo de
configuración principal. Si el archivo indicado no existe, no devuelve ningún error. Desde la linea 154:

#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3
#!define FLT_NATS 5

#!define FLB_NATB 6
#!define FLB_NATSIPPING 7

Se declaran una serie de sentencias para asociar a una palabra clave un valor. En este caso FLT está en
lugar de bandera de transacción y FLB está en lugar de bandera de branch. Más adelante se explicará
de forma detallada como funcionan y como se utilizan los distintos tipos de banderas. Desde la linea
132:

#!ifdef WITH_DEBUG
#!define DBGLEVEL 3
#!else
#!define DBGLEVEL 2
#!endif

Como la sentencia WITH_DEBUG no está definida, el nivel de debug será 2 y no se enviarán los
errores a la salida estándar de Linux. El significado de los diferentes niveles de error:

• -5 ALERTA
• -4 BUG
• -3 CRITICO2
• -2 CRITICO
• -1 ERROR
• 0 ADVERTENCIA
• 1 NOTICIA
• 2 INFO
• 3 o más DEBUG

Lineas 170,171:

memdbg=5
memlog=5

• el primer parámetro define a que nivel de debug se activará el LOG de todos los mensajes de
debug relacionados con el uso de memoria por parte de Kamailio Si este valor es mayor al valor
del parámetro debug (que en este caso es 2) no se registrará ningún mensaje
• el segundo parámetro es parecido al primero pero está relacionado con las estadísticas de uso de
la memoria por parte de Kamailio

Linea 173:

3
log_facility=LOG_LOCAL0

se utiliza para definir un nivel de LOG de Kamailio que luego puede ser configurado en el programa
RSYSLOG y de esta forma tener los registros de LOG de Kamailio en una archivo dedicado. Este tipo
de configuración ya se ha realizado en la segunda parte de este modulo semanal.

Linea 178:

children=8

numero de proceso hijos que se se utilizarán para el enrutamiento de las solicitudes SIP en Kamailio.
Con:

ps aux | grep kamailio

veremos los procesos activos y con:

kamctl ps

veremos de que se ocupa cada proceso. Si se fijan hay ochos relacionados con el protocolo UDP sobre
la IP y puerto de escucha como es de esperarse ya que el parámetro children está en 8:

{
"IDX": 1,
"PID": 2921,
DSC": "udp receiver child=7 sock=108.61.86.103:5060"
}

Linea 181:

# disable_tcp=yes

Este parámetro, que está comentado es decir no activado, se utiliza para desactivar el uso del protocolo
TCP como protocolo de transporte de la señalización SIP.

Linea 188:

4
auto_aliases=no

Kamailio no buscará eventuales alias del dominio donde está escuchando si en el parámetro listen se
ha configurado un nombre de dominio en lugar de una IP. Al mismo tiempo no realizará una consulta
de tipo “Reverse DNS” si en el parámetro listen se ha configurado una IP. El Reverse DNS permite
conocer el dominio asociado a una IP siempre y cuando sea correctamente configurado en el servidor
DNS

Linea 197:

listen=udp:IPPublica:5060

Con este parámetro se indica protocolo de transporte, IP y puerto de escucha. Se pueden indicar más
lineas de este tipo modificando protocolo de transporte, IP y/o puerto de escucha. Es uno de los
parámetros más importantes de la configuración de Kamailio.

Si no se configura diversamente, cuando Kamailio contestará un mensaje SIP actuando como un UAs
(User Agent Server) la cabecera Server: presente en el mensaje SIP aparecerá de la siguiente forma:

Server: kamailio (5.4.4 (x86_64/linux))

Cuando actuará como UAc (User Agent Client) es decir cuando enviará una solicitud SIP inicial:

User-Agent: kamailio (5.4.4 (x86_64/linux))

Si no se quiere que aparezca el tipo y versión del Proxy que se está utilizando, se pueden añadir dos
nuevas entradas en el bloque de los parámetros globales de la configuración de Kamailio. Se abre el
archivo:

kacfg

y después de esta linea (201):

tcp_connection_lifetime=3605

se añaden las lineas que siguen:

user_agent_header="User-Agent: Curso Kamailio Proxy Agent"


server_header="Server: Curso Kamailio Proxy Server"

Antes de guardar los cambios, personalizar los valores. Luego se reinicia Kamailio:

systemctl restart kamailio

Encuentran todos los parámetros globales que se pueden configurar en la documentación oficial de
Kamailio:

5
Bloque Módulos

En este bloque (Modules Section) se configuran los módulos cuyas funciones se utilizarán en el tercer
bloque del archivo de configuración de Kamailio.

El bloque inicia con (Desde la linea 255):

#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif

cuyo significado es: si la sentencia WITH_MYSQL está definida antes de este bloque, cargar el modulo
db_mysql sino no. Ese modulo es él que permite trabajar con la base de datos con nombre kamailio
creada anteriormente en MariaDB.

Luego aparece una larga lista de módulos a cargar; algunos se cargarán solamente si determinadas
sentencias han sido definidas. Al cargar los módulos hay que respetar las dependencias que cada uno
tiene. Esto quiere decir que no se puede cargar un modulo antes del modulo de que depende.

Desde la linea “setting module-specific parameters” (330) aparecerán los parámetros configurados por
cada modulo agrupados por modulo. La mayoría de los parámetros disponibles para cada modulo, si no
se definen, tomarán como valor el predefinido.

Como en la primera parte del próximo modulo semanal vamos a hablar del modulo REGISTRAR,
tomamos este modulo como ejemplo. En la documentación oficial de Kamailio cada modulo viene con
un documento dedicado que normalmente se divide en:

1. Una descripción del modulo y sus funcionalidades principales


2. Las dependencias del modulo. En el caso del modulo REGISTRAR:
• el modulo USRLOC que permite guardar los datos de los dispositivos que se registran
en Kamailio en la caché de memoria y/o en la base de datos kamailio que se ha creado
anteriormente (Location Service)
• el modulo SL que es utilizado para enviar respuestas SIP en la mayoría de los casos en
modo stateless
3. Los parámetros que se pueden configurar con el modulo. Algunos ejemplos para el modulo
REGISTRAR:
• max_expires el numero máximo de segundos que un dispositivo quedará registrado
antes que tenga que volver a registrarse. Si el valor enviado por el dispositivo es más
alto al indicado en este parámetro, Kamailio “obligará” el dispositivo a registrarse
nuevamente después del numero de segundos indicados en este parámetro. Si para un
parámetro de un modulo no se indica un valor, en la mayoría de los casos, tomará el
valor predefinido.
• max_contacts indica el numero máximo de dispositivos que se podrán registrar
utilizando las mismas credenciales. Ejemplo: si se crea el usuario 1000 y en este
parámetro se indica 5, se podrán registrar hasta 5 dispositivos a la vez utilizando las

6
credenciales del usuario 1000. Cuando llegue una llamada para el usuario 1000,
timbrarán los cinco dispositivos (configuración predefinida)
4. Las funciones que se activarán cargando el modulo y que se podrán utilizar en el script de
configuración de Kamailio
5. Si el modulo genera o no eventos que luego se pueden configurar/utilizar en una ruta de tipo
evento.
6. El tipo de estadísticas generadas por el modulo que luego se pueden visualizar utilizando el
programa kamcmd. Ejemplo: kamcmd stats.get_statistics registrar para ver todas las
estadísticas del modulo: kamcmd stats.get_statistics max_expires para ver el valor del
parámetro max_expires que es el tiempo máximo de registro aceptado por Kamailio. Para ver
la lista completa de comandos que se pueden utilizar con el programa kamcmd: kamcmd help
7. Por ultimo una parte dedicada a las pseudo-variables exportadas por el modulo Las pseudo-
variables son variables donde se almacenan determinados valores relacionados con el
procesamiento de las peticiones SIP, con el funcionamiento interno de Kamailio y de sus
funciones o, como es el caso del modulo REGISTRAR, generadas por los módulos.
Normalmente son de sola lectura y solamente en algunos casos de lectura/escritura.

Una vez cargados y configurados todos los módulos que se utilizarán, inicia el tercer bloque de
configuración de Kamailio que es donde se procesarán todas las peticiones SIP recibidas/enviadas.

Bloque SCRIPT

El bloque SCRIPT inicia con la linea (506):

request_route {

En este bloque se pueden configurar dos tipos distintos de rutas:


• top routes (rutas principales). Estas rutas se utilizan para procesar las peticiones SIP, las
repuestas y los eventuales errores generados por una transacción
• sub-routes (rutas secundarias o sub-rutas). Estas rutas se utilizan “llamándolas” desde una ruta
principal o son activadas al verificarse un determinado evento.

Si miramos el contenido del script, veremos que el primer bloque presente es (desde la linea 508):

# per request initial checks


route(REQINIT);

la primera linea es un comentario; la segunda se utiliza para llamar una subruta que en este caso se
llama REQINIT y, como se puede intuir, es donde se procesarán todas las solicitudes iniciales
recibidas. Si las sentencias que activan algunas partes de esta subruta están declaradas, este bloque se
encargará de:

• detectar y mitigar ataques DoS y DdoS bloqueando las IPs involucradas


• bloquear las solicitudes SIP que procedan de programas que normalmente se utilizan para
hackear y/o escanear sistemas SIP. Esto se realiza comparando el nombre contenido en la
cabecera User-Agent de la solicitud SIP recibida, con los nombres de los programas utilizados

7
con este fin. Esta parte no es indispensable ya que este tipo de bloqueo se ha realizado a
nivel de IPtables.
• evitar que las solicitudes que creen un bucle puedan afectar el funcionamiento del Proxy
• procesar correctamente la solicitudes SIP de tipo OPTIONS
• revisar si las solicitudes SIP recibidas tienen una sintaxis correcta
• lista blancas y listas negras
• bloquear/aceptar las solicitudes procedentes de determinado países
• bloquear ataques de inyección SQL

El archivo sigue con (desde la linea 511):

# NAT detection
route(NATDETECT);

donde se llamará la subruta NATDETECT para realizar una serie de operaciones sobre la solicitudes
recibidas para averiguar si proceden desde dispositivos que Kamailio detecta que se encuentran detrás
de un NAT. Desde la linea 514:

# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
}
exit;
}

en este bloque se revisa si la solicitud SIP recibida es de tipo CANCEL y si ese CANCEL pertenece a
una transacción SIP existente; si así fuera se procesa a través de la subruta RELAY sino se descarta.
Desde la linea 522:

# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}

En este bloque se aplica la siguiente lógica: si el método SIP de la solicitud recibida no es ACK y la
solicitud es parte de una transacción existente, se capturan eventuales retransmisiones. Un ejemplo de
retransmisión es, por ejemplo: llega un INVITE y antes que Kamailio conteste la solicitud, llega un
segundo INVITE, replica del primero. El Segundo INVITE sera descartado y no recibirá ninguna
respuesta por parte de Kamailio ya que es una retransmisión. Desde la linea 531:

# handle requests within SIP dialogs


route(WITHINDLG);

8
Con este bloque se llama la subruta WITHINDLG donde se procesarán todas las solicitudes SIP que
pertenecen a un dialogo existente. El script continua con (desde la linea 536):

# authentication
route(AUTH);

Con este bloque se llama la subruta AUTH donde se autentican las solicitudes SIP recibidas que
queremos autenticar. Se necesita/utiliza este tipo de procesamiento sobre todo para REGISTER e
INVITE; desde la linea 539:

# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE")) {
record_route();
}

Como todavía se está procesando una solicitud SIP inicial, se elimina cualquier cabecera Route
presente en la solicitud; luego si el método SIP es INVITE o SUBSCRIBE, se añade a la solicitud,
antes de ser reenviada, una cabecera de tipo Record_Route. Esto facilitará la recepción de las
respuestas relacionadas con el mismo dialogo; desde la linea 546:

# account only INVITEs


if (is_method("INVITE")) {
setflag(FLT_ACC); # do accounting
}

Este bloque se utiliza para guardar en la base de datos de Kamailio algunos datos relacionados con los
INVITE. Veremos más adelante como funciona; desde la linea 551:

# dispatch requests to foreign domains


route(SIPOUT);

Con este bloque se llama la subruta SIPOUT donde se procesarán todas las solicitudes SIP cuyo destino
no es este Proxy SIP (esto si no se modifica la configuración); desde la linea 556:

# handle presence related requests


route(PRESENCE);

en este bloque se llama la subruta PRESENCE que se utilizará para procesar solicitudes SIP
relacionadas con estado y presencia de las extensiones (métodos SIP SUBSCRIBE y PUBLISH); desde
la linea 559:

# handle registrations
route(REGISTRAR);

9
desde aquí se llama la subruta REGISTRAR donde se procesarán las solicitudes SIP de tipo
REGISTER y donde se guardarán los datos de registro de las extensiones una vez que las solicitudes
SIP de tipo REGISTER hayan sido autenticadas; el registro de la extensión se guardará en la memoria
de caché de Kamailio o en la base de datos kamailio dependiendo de la configuración del modulo
USRLOC. Desde la linea 562:

if ($rU==$null) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}

Si la parte usuario de la Request URI (antes de la arroba) está vacía/nula se descarta la solicitud SIP;
desde la linea 568:

# dispatch destinations to PSTN


route(PSTN);

En la subruta PSTN llamada desde este bloque, se procesan las llamadas con destino números
telefónicos (fijos/celulares); desde la linea 571:

# user location service


route(LOCATION);

con este bloque se llama la subruta LOCATION donde se procesarán las solicitudes SIP que tienen
como destino otra extensiones presentes/configuradas en el sistema.

La parte que queda del SCRIPT está compuesta por subrutas llamadas desde distintos puntos del script.
La subruta más importante es (desde la linea 576):

route[RELAY] {

# enable additional event routes for forwarded requests


# - serial forking, RTP relaying handling, a.s.o.
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}

if (!t_relay()) {
sl_reply_error();
}

10
exit;
}

que es utilizada para reenviar las solicitudes SIP una vez que hayan sido autenticadas/procesadas
correctamente. El primer bloque:

if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}

se lee: si el método SIP de la solicitud es un INVITE, BYE, SUBSCRIBE o UPDATE y no hay un ruta
d tipo BRANCH creada para la solicitud, enviar la solicitud a la subruta de tipo branch cuyo nombre es
MANAGE_BRANCH. Las operaciones que se pueden realizar en un ruta de tipo branch son muy
limitadas. En este caso desde la ruta branch se envía la solicitud SIP a la subruta NATMANAGE
donde se realizarán toda una serie de operaciones dedicadas al NAT que veremos en la tercera parte del
próximo modulo semanal. El segundo bloque:

if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}

se lee: si el método SIP de la solicitud es un INVITE, SUBSCRIBE o UPDATE y no hay un ruta de


tipo onreply creada para la solicitud, enviar la solicitud a la subruta de tipo onreply cuyo nombre será
MANAGE_REPLY. Las operaciones realizadas en un ruta de tipo onreply aplican a respuestas
parciales o finales de solicitudes SIP (ejemplo 200 OK). En este caso, en la ruta MANAGE_REPLY,
si el código de la respuesta empieza con un 1 o con un 2 y siguen dos cifras más que pueden contener
un valor entre 0 y 9 cada una, se envía la respuesta a la subruta NATMANAGE donde se realizarán
toda una serie de operaciones dedicadas al NAT que veremos en la tercera parte del próximo modulo
semanal El tercer bloque:

if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}

se lee: si el método SIP de la solicitud es un INVITE y no hay una ruta de tipo failure creada, enviar la
solicitud a la sub ruta de tipo failure cuyo nombre es MANAGE_FAILURE. A la ruta de tipo failure
llegan las transaccione SIP cuya respuesta final es = o mayor a 300. Normalmente en una ruta de tipo
failure se revisa el tipo de error SIP recibido y en base a ese valor se envía una respuesta determinada
y/o se envía la solicitud SIP al buzón de voz (por ejemplo). En el cuarto bloque:

if (!t_relay()) {
sl_reply_error();
}
exit;

11
se lee: si no se puede procesar la solicitud SIP con la función t_relay activada por el modulo TM,
devolver el relativo error y terminar el procesamiento de la solicitud. La función t_relay retransmite la
solicitud SIP de forma Stateful y de esta forma Kamailio se queda en el medio de la señalización SIP.

Arquitectura de Kamailio

Kamailio se basa en un corazón que además de ser el punto de partida del arranque de Kamailio,
alberga algunos componentes imprescindibles:

• un interprete de la configuración
• el parser de la señalización SIP
• el gestor de la memoria de trabajo
• el gestor de las variables de sistema

Además de eso, el core de Kamailio se encarga de cargar los distintos módulos configurados con
relativos parámetros, leyendo el archivo de configuración

Al iniciar Kamailio se crean distintos procesos, según configuración, relacionados con el protocolo de
trasporte, temporizadores del core y de los módulos que los utilizan, control de procesos y procesador
de operaciones asíncrona. El comando para ver los procesos activados, que ya vimos anteriormente, es:

kamctl ps

cuyo resultado:

proceso principal;

12
protocolos de trasporte;

13
temporizadores;

controles de proceso. La memoria de trabajo de Kamailio se asigna el iniciar el Proxy y no varia a lo


largo de su funcionamiento. En nuestro caso la configuración de la cantidad de memoria reservada para
Kamailio se encuentra en el siguiente archivo:

nano /usr/src/kamailio/pkg/kamailio/obs/kamailio.service

en estas dos lineas:

Environment='SHM_MEMORY=64'
Environment='PKG_MEMORY=4'

14
que representan los valores predefinidos; el primero la memoria compartida, el segundo la memoria
privada. Otra forma de realizar la configuración es eliminar las dos lineas indicadas y realizar la
configuración en el archivo:

nano /etc/sysconfig/kamailio

descomentando y asignando un valor a estás dos lineas:

#SHM_MEMORY=64
#PKG_MEMORY=4

La ventaja de utilizar este tipo de arquitectura:

• memoria optimizada para el enrutamiento SIP


• fácil acceso a la zona de memoria compartida
• eventuales problemas de memoria no estarían afectando el sistema operativo
• Kamailio nunca intentará utilizar más memoria de la que tiene asignada

Estos valores de memoria normalmente son más que suficientes pero se pueden aumentar en cualquier
momento. Ahora pasamos a describir algunos parámetros importantes para la
configuración/funcionamiento de Kamailio.

Parámetros – Core CookBook Kamailio

Al cargar el corazón de Kamailio se activarán una serie de:

• Palabras clave
• Valores
• Parámetros

Todos estos valores se encuentran en el Core Cookbook de la documentación de Kamailio y se podrán


utilizar en el script de configuración de Kamailio. Algunos ejemplos de palabras claves que se
utilizarán en este curso:

• method es la variable que permite conocer el método SIP utilizado por la solicitud que se está
procesando:

if(method=="REGISTER")
{
log("La solicitud SIP es de tipo REGISTER \n");
}

Los valores presentes en el corazón de Kamailio se pueden utilizar en sentencias (if) para realizar
consultas contra las palabras claves de Kamailio:

15
• myself hace referencia a todos los dominios, direcciones IP y alias configurados en el bloque de
los parámetros globales del archivo de configuración de Kamailio.

if(uri==myself) {
log("La solicitud SIP es para ser procesada localmente \n");
}

Si la parte después de la arroba de la Request URI es una por las cuales Kamailio es responsable, la
solicitud será procesada localmente.

Los parámetros son aquellos que se pueden configurar en el primer bloque del archivo de
configuración de Kamailio dedicado a los parámetros globales. Algunos ejemplos:

disable_tcp= yes

para desactivar el protocolo tcp como método de transporte de la señalización SIP:

debug=3

para configurar el nivel de detalle que se quiere activar en los registros de LOG.

Parámetros DNS - Core Cookbook Kamailio

Kamailio tiene un servidor DNS interno que puede resolver direcciones IP desde dominios y dominios
asociados a las direcciones IP. Este DNS viene con una caché donde es posible guardar los resultados
de las consultas por un determinado tiempo.

De forma predefinida el DNS de Kamailio está activado. Esto significa que las consultas no se
realizarán utilizando el DNS del sistema operativo ni el archivo /etc/hosts donde normalmente están
presentes asociaciones entre IP y nombres de dominios que son usadas de forma predefinida.

Cuando Kamailio se inicia, hasta que el modulo del DNS interno sea cargado completamente, utilizará
el sistema DNS presente a nivel de sistema operativo.

Para desactivar el DNS interno de Kamailio, en la parte dedicada a los parámetros globales hay que
añadir esta linea:

use_dns_cache=no

Funciones – Core CookBook Kamailio

Al cargar el corazón de Kamailio se activan todas una serie de funciones que se pueden utilizar en el
tercer bloque del archivo de configuración de Kamailio. Algunos ejemplos:

16
• break() Se utiliza dentro de una declaración Switch, que veremos más adelante, o dentro de una
declaración While, para terminar la ejecución del script
• drop() Se utiliza para terminar la ejecución del script de procesamiento de las peticiones SIP y
modificar cualquier tipo de acción que implícitamente se debería ejecutar. Si se utiliza en una
ruta de tipo branch el branch (la nueva transacción) creado será descartado. Si se utiliza en una
ruta de tipo onreply_route cualquier tipo de respuesta provisional a una petición SIP recibida
será descartada
• exit() Termina la ejecución del script de procesamiento de las peticiones SIP. Ejemplo:

if ($rU==NULL) {
sl_send_reply("484","Address Incomplete");
xlog("L_ERROR", "El usuario $rU no es valido");
exit;
}

Si la parte usuario de la Request URI está vacía, Kamailio enviará la respuesta “488 Dirección no
completa” enviará el texto presente en la tercera linea al archivo de LOG de Kamailio y terminará la
ejecución del script.

• force_rport() añade el parámetro rport (RFC3581), sino está presente, en la primera cabecera
Via presente en la solicitud SIP recibida. De esta forma todas las sucesivas solicitudes
generadas dentro de las misma transacción o dialogo, tendrán ese valor configurado.
Normalmente se utiliza cuando la solicitud llega de un dispositivo que se encuentra detrás de un
NAT

• return(int) devuelve un valor numérico desde una sub-ruta que luego se puede utilizar en la
ruta principal ya que se recibirá en la variable $retcode. return(0) es los mismo que exit().
Ejemplo:

route {
if (route(2)) {
xlog("L_NOTICE","method $rm is INVITE\n");
} else {
xlog("L_NOTICE","method $rm is REGISTER\n");
};
}

route[2] {
if (is_method("INVITE")) {
return(1);
} else if (is_method("REGISTER")) {
return(-1);
} else {
return(0);
};
}

17
Si la petición SIP es un INVITE, la ruta [2] devolverá un 1 (verdadero) pues se ejecutará la primera
parte (el if) de la ruta principal. Si la petición es un REGISTER, la ruta [2] devolverá un -1 pues se
ejecutará el else de la ruta principal.

• setflag(name) permite crear un flag (bandera) para la petición SIP que se está procesando de
forma que en cualquier parte de script se podrá consultar su existencia y valor. Normalmente se
utiliza para temas de registro de las llamadas y de NAT

• strip(int) quita el numero de caracteres indicados entre paréntesis en la parte usuario de la


Request URI. Ejemplo si la Request URI es 9573101234567@voztovoice.org, strip(1)
devolverá 573101234567@voztovoice.org

• strip_tail(int) parecido al anterior pero quita el numero de caracteres indicados empezando


desde el final del usuario. En el mismo ejemplo de arriba strip_tail(1) devolverá
957310123456@voztovoice.org

Parámetros personalizados globales - Core Cookbook Kamailio

Existen parámetros que pueden ser definidos en el archivo de configuración de Kamailio y que luego se
pueden utilizar en el bloque de procesamiento de las solicitudes SIP. Una propriedad interesante de
estos parámetros es que sus valores se pueden modificar a través de la interfaz RPC de Kamailio; esto
evita de tener que reiniciar Kamailio.

El modulo que permite este tipo de operaciones es CFG_RPC que claramente hay que cargar en el
bloque módulos del archivo de configuración de Kamailio; de forma predefinida está cargado.

La definición de estos parámetros sigue la siguiente sintaxis:

group.variable = value desc "description"

Un ejemplo:

pstn.gw_ip = "1.2.3.4"desc "Dirección IP del Gateway PSTN"

El valor del parámetro luego se puede utilizar en el script de Kamailio a través de la siguiente variable:

$sel(cfg_get.group.variable)

Ejemplo:

$ru = "sip:" +$rU + "@" +$sel(cfg_get.pstn.gw_ip);

Tipos de Rutas – Core Cookbook Kamailio

18
La ruta de procesamiento principal es request_route, de hecho el tercer bloque del archivo de
configuración de Kamailio inicia con:

request_route{

en esta ruta se procesan todas las solicitudes SIP que legan al Proxy SIP.

Con la sentencia route se definen subrutas donde se enviará la solicitud SIP. Ejemplo:

route(NATDETECT);

Otros tipos de rutas que se pueden utilizar son:

• branch_route es una ruta que contiene una serie de acciones que Kamailio realizará por cada
branch de una petición SIP. Se crean distintos branch de una petición SIP cuando, por ejemplo,
la misma extensión está registrada desde distintos dispositivos y Kamailio crea un INVITE para
cada uno de ellos.
• failure_route es una ruta que contiene una serie de acciones que se ejecutarán para cada
transacción SIP cuyo resultado es una respuesta de error con código SIP >= 300. En el caso de
una llamada entre extensiones, si el dispositivo no está disponible o se encuentra ocupado, se
puede configurar esta ruta para enviar la llamada, por ejemplo, al buzón de voz.
• reply_route es una ruta que puede contener una serie de acciones a ejecutar para todas las
respuestas SIP recibidas.
• onreply_route es una ruta que puede contener una serie de acciones a ejecutar sobre las
respuestas SIP recibidas. La diferencia con la ruta anterior es que se llama SIEMPRE con una
función especifica del modulo TM: t_on_reply
• onsend_route es una ruta que puede contener una serie de acciones que se van a ejecutar para
una solicitud SIP cuyo destino es otro Proxy/Servidor SIP
• event_route es una ruta que se ejecuta cuando la interfaz de eventos de Kamailio detecta que se
ha presentado el evento declarado en la ruta. Para definir el evento para el cual la ruta es
responsable, se nombra después de la ruta. Ejemplo (en negrita):
event_route[E_PIKE_BLOCKED]

De la mayoría de estas rutas veremos algunos ejemplos a lo largo del curso.

Declaraciones – Core CookBook Kamailio

Pasamos ahora a las distintas declaraciones que podemos utilizar para el procesamiento de las
peticiones SIP.

La primera es la típica if-else. Si se verifica una determinada condición ejecutar una determinada
acción sino ejecutar otra. El else se puede omitir y no es obligatorio. Todos los ejemplos a seguir son
tomados de la documentación de Kamailio:

if (expr) {
acción;

19
} else {
acción;
}

El comando Switch. La mayoría de las funciones que se utilizan en el script de Kamailio, al ejecutarse
devuelven un valor numérico que se almacena en la pseudo-variable $retcode (código devuelto). Se
puede utilizar este comando para ejecutar una serie de acciones según el valor numérico de esa
variable:

route {
route(my_logic);
switch($retcode)
{
case -1:
log("Procesar los SIP INVITE aquí \n");
break;
case 1:
log("Procesar los SIP INVITE aquí \n");
break;
case 2:
case 3:
log("Procesar los SIP SUBSCRIBE y NOTIFY aquí \n");
break;
default:
log("Procesar cualquier otro tipo de solicitud aquí \n");
}

El comando While se utiliza para ejecutar un determinado ciclo hasta que no se cumpla una
determinada condición:

$var(i) = 0;
while($var(i) < 10)
{
xlog("conteo: $var(i)\n");
$var(i) = $var(i) + 1;
}

Otros comandos que pueden ser muy útiles a la hora de construir el script de Kamailio, son los
operadores lógicos:

• == es igual a
• != no es igual a
• =~ la expresión regular que sigue empareja con la declaración que precede el operador
• !~ la expresión regular que sigue no empareja con la declaración que precede el operador
• > mayor a
• >= mayor o igual a
• < menor a

20
• <= menor o igual a
• && operador lógico AND
• || operador lógico OR
• ! operador lógico NOT
• […] operador de test. Dentro de los corchetes puede haber cualquier tipo de expresión
aritmética

Para más informaciones acerca de como funcionan y como se construyen las expresiones regulares,
pueden consultar este breve manual en Español. A lo largo del curso veremos algunos ejemplos.

Operadores – Core CookBook Kamailio

Los operadores permiten realizar una serie de operaciones en el archivo de configuración. Pueden ser:

• Asociaciones: asignar un valor a una variable. Ejemplos:


• $var(a) = 123;
• $var(b) = “fulano”;
• Operaciones sobre cadenas. Ejemplos:
• $var(a) = “prueba”
• $var(b) = “sip:” + $var(a) + “@” + “voztovoice.org”; El resultado será
sip:prueba@voztovoice.org

Todos los operadores que se pueden utilizar para este tipo de operaciones:

• + más
• - menos
• / dividir
• * multiplicar
• % modulo

Las operaciones que siguen se ejecutan a nivel de bit y solo se pueden realizar sobre valores numéricos.
Trabajan directamente con el sistema binario donde un byte está compuesto por 8 bits que pueden estar
en cero (no activado) y uno (activado). En la primera linea los valores numéricos de cada bit cuando
esté en 1. Si hay más de un bit en uno el valor de cada bit se suma para obtener el valor final.

128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0

Algunos ejemplos:

00001000 tendrá el valor numérico 8


00001001 tendrá el valor numérico 9 (8 + 1)
10000000 tendrá el valor numérico 128

• | operación de bit a bit de tipo OR

21
• & operación de bit a bit de tipo AND

• ^ operación de bit a bit de tipo XOR

• ~ operación de bit a bit de tipo NOT

• << operación de bit a bit de tipo correr a la izquierda por el numero de posiciones indicadas en
la segunda casilla de la imagen

22
• >> operación de bit a bit de tipo correr a la derecha por el numero de posiciones indicadas en la
segunda casilla de la imagen:

Variables – Pseudo-Variables CookBook Kamailio

Las pseudo variables (PV): proveen acceso a las informaciones relacionadas con el procesamiento de
las solicitudes SIP (cabeceras, Request URI, protocolo de trasporte, etc.) o de los datos internos del
funcionamiento de Kamailio. La mayoría son de sola lectura y solamente algunas se pueden modificar.
Pueden contener uno o más valores (ejemplo las cabeceras Via contenidas en una petición SIP). El
inicio de cada pseudo variable es identificado por $.

Existen un grupo predefinido de pseudo variables cuyo nombre está compuesto por uno o más
caracteres; existen también pseudo variables especiales que hacen referencia a campos dinámicos de las
transacciones (AVP y/o Cabeceras). Las variables AVP (Attribute Value pair) son variables dinámicas
que están asociadas a una petición SIP o una transacción.

Algunos ejemplos de pseudo variables:

• $cl contiene el valor de la cabecera content-length


• $du contiene la URI de destino de la solicitud SIP
• $rc o $retcode contiene el valor devuelto por la ultima función utilizada en el script
• $rm contiene el valor del método SIP utilizado
• $ru contiene el valor de la Request URI de la petición SIP
• $rU contiene solamente el usuario presente en la Request URI (la parte antes de la @)
• $Ri contiene el valor de la IP de donde se ha recibido la petición SIP (en el caso que
Kamailio escuche en más de una IP)

Transformaciones – Transformations CookBook Kamailio

23
Una trasformación es una función que se aplica a una pseudo variable para extraer un determinado
valor de la variable misma. El valor de la variable a la que se aplica la trasformación no cambia.

Algunos ejemplos nos ayudarán a entender como funcionan:

• {s.len} devuelve la longitud de una variable


• {s.int} devuelve el valor numérico de una variable cuyo valor se ha asignado como
alfanumérico
• {s.substr,offset,length} devuelve el valor de una variable partiendo de la posición declarada en
la opción offset y por el numero de caracteres declarados en la opción length. Si length es igual
a 0 devolverá todo el contenido de la variable una vez quitado el numero de caracteres
declarados en la opción offset. Ejemplo: si $var(a) es igual a “abcd”
• $(var(a){s.substr,1,0}) devolverá bcd
• $(var(a){s.substr,1,2}) devolverá bc

Otras paginas de documentación muy importantes son:

• El esquema de la base de datos dividido por módulos


• La lista completa de los parámetros de todos los módulos (ordenados alfabéticamente)
• La lista completa de las funciones activadas por los módulos (ordenadas alfabéticamente)
• La lista completa de los comandos RPC
• La lista completa de las estadísticas que se pueden extraer de Kamailio (ordenadas
alfabéticamente)

Ahora que conocemos las gran partes de las opciones/variables/operaciones que se pueden utilizar en el
script de configuración de Kamailio, podemos pasar a la configuración de Kamailio para el registro de
los usuarios/dispositivos.

24

También podría gustarte