Está en la página 1de 14

Segunda Parte - DROUTING

Después del modulo DISPATCHER, vamos a ver como se realiza la misma tarea del balanceamiento
de carga de las llamadas con el modulo DROUTING. Este modulo se puede utilizar para conectar
Kamailio a GATEWAY que a su vez están directamente conectados a la red PSTN (tipo GrandStream,
Audiocodes, Patton) o, como en el caso de nuestra configuración, para conectar Kamailio a
proveedores SIP. Claramente en ambos casos es posible recibir de los mismos GATEWAY llamadas
entrantes y la configuración de este tipo de llamadas, es muy parecida a la del modulo DISPATCHER

El modulo DROUTING, además de la configuración de los parámetros y el utilizo de las funciones que
se activan al cargar el modulo, se basa en cuatro tablas presentes en la base de datos kamailio. Las
cuatros tablas son:

• dr_groups: donde se configuran los grupos que se utilizarán para dar acceso a los distintos tipo
de llamadas (fijos, celulares, internacionales, etc...)
• dr_gateways: donde se configuran los GATEWAY que se utilizarán para sacar las llamadas
• dr_gw_lists: donde se agrupan los GATEWAY en una estructura más grande que normalmente
utilizan los operadores telefónicos que venden trafico al por mayor. En este curso no se
utilizará.
• dr_rules: contiene todas las reglas de marcado basadas en el prefijo de la llamada, en el grupo
que la puede realizar y los GATEWAY que se utilizarán para terminarla.

Los campos presentes en la tabla dr_groups:

• id: es un numero progresivo que automáticamente se asignará a cada entrada presente en la


tabla
• username: el nombre/numero de usuario
• domain: el nombre de dominio al que pertenece el usuario (en un escenario multi dominio)
• groupid: numero del grupo al que pertenece el usuario
• description: una descripción de la entrada

Los campos presentes en la tabla dr_gateways:

1
• gwid: es un numero progresivo que automáticamente se asignará a cada entrada presente en la
tabla
• type: para diferenciar los GATEWAY utilizados para llamadas salientes de los GATEWAY
utilizados para las llamadas entrantes o de los GATEWAY que se utilizan para ambos escenarios
• address: la dirección IP del GATEWAY
• strip: cuantos dígitos hay que quitar al numero marcado antes de enviar la llamada al
GATEWAY
• pri_prefix: el prefijo que hay que añadir al numero marcado antes de enviar la llamada al
GATEWAY y después de haber quitado el valor, si presente, en el campo strip
• attrs: un valor que luego se puede utilizar en el script de Kamailio como variable
• description: una descripción del GATEWAY

Los campos presentes en la tabla dr_rules:

• ruleid: es un numero progresivo que automáticamente se asignará a cada entrada presente en la


tabla
• groupid: los grupos que tienen acceso a esta regla
• prefix: el prefijo del numero marcado para que esta regla aplique
• timerec: si la regla es valida solamente en determinadas horas, días, etc... se indica en este
parámetro utilizando como referencia la RFC2445 y utilizando los siguientes parámetros en el
orden indicado: <dtstart>|<duration>|<freq>|<until>|<interval>|<byday>|<bymonthday>|
<byyearday>|<byweekno>|<bymonth>. Una explicación de cada parámetro está presente en la
RFC mencionada

2
• priority: la prioridad que tiene la regla. Un numero más alto corresponde a una prioridad más
alta
• routeid: una subruta presente en el script de Kamailio será ejecutada siguiendo el orden
indicado más adelantes en el algoritmo de búsqueda del modulo
• gwlist: una lista de GATEWAY/CARRIERS que se utilizarán cuando aplique esta regla. Se
pueden indicar sin o con el peso de cada GATEWAY: un peso más alto dará prioridad a un
Gateway en lugar de otro con un peso más bajo.
• description: una descripción de la regla

Los campos presentes en la tabla dr_carriers (que no se utilizará):

• id: es un numero progresivo que automáticamente se asignará a cada entrada presente en la


tabla
• gwlist: la lista de GATEWAY que serán parte de cada entrada. Se pueden indicar con o sin el
peso de cada GATEWAY
• description: una descripción del CARRIER

Luego, en el script de Kamailio, de las funciones activadas por el modulo, se utilizarán estas dos:

• do_routing([groupID]
• use_next_gw()

La primera se utiliza para buscar las mejores rutas para una determinada llamada y la segunda para
intentar sacar la llamada utilizando otra ruta si la primera falla. Una ruta, en este caso, puede estar
compuesta por uno o más GATEWAY.

Si se quiere utilizar el modulo también para las llamadas entrantes, la función que hay que utilizar es:

• is_from_gw

Ahora una paréntesis acerca de las prestaciones del modulo. Los desarrolladores han realizado pruebas
creando alrededor de 400mil reglas y midiendo dos valores:

• el tiempo para cargar las reglas desde la base de datos hacia la memoria de trabajo de Kamailio
• cuanto espacio de memoria utilizaban las reglas una vez cargadas en la memoria de trabajo de
Kamailio

3
El tiempo de carga ha sido entre 4 y 8 segundos. Una vez cargadas, la memoria ocupada por las reglas
ha sido alrededor de 96 MegaByte. ¡Nada mal! Claro está que sería interesante conocer en que tipo de
servidor se han realizado las pruebas pero, en general, el modulo tiene muy buenas prestaciones.

¿Cómo funciona el algoritmo que se ocupa de buscar la/s mejor/mejores rutas para una llamada? Los
pasos que sigue el algoritmo son:

1. primero averigua el grupo al que pertenece el usuario que está llamando. Como en la función
do_rounting es posible indicar un grupo, si se indica directamente en la función, este pasaje se
salta
2. una vez localizado el grupo, el algoritmo busca, entre todas las reglas que incluyen el grupo
definido, aquellas que más se acerquen al prefijo que el usuario ha marcado. Ejemplo: si el
usuario marca 573 y para el mismo grupo hay dos reglas: 57 y 573, la segunda será aquella que
se escogerá
3. Entre las reglas seleccionadas, el sistema aplicará el criterio de horario, es decir que escogerá
las reglas que permitan llamar esa ruta en la hora en que se está realizando la llamada. Si
encuentra más de una, escogerá aquella que tenga una prioridad más alta.
4. Una vez localizada la regla “final”, si esta contiene un valor en el campo routeid (como
veremos más adelante), el procesamiento se pausará hasta que no se complete la ejecución de
esa sub ruta que tiene que estar presente en el archivo de configuración de Kamailio.
5. La linea en la tabla de la regla utilizada, puede contener uno o más GATEWAY cada uno con o
sin un peso. Kamailio procesa la lista en el mismo orden como se ha definido al momento de
crear la regla; si se ha definido un peso para cada GATEWAY , se ordenarán los GATEWAY en
base al peso de cada uno; luego de la lista creada se intentará sacar la llamada siguiendo el
orden creado. Si el primer destino falla, se intentará utilizar el segundo y así a seguir hasta
utilizar todos los GATEWAY presentes en la lista creada
6. Quita, si presente, el numero de dígitos indicados en el campo strip de la tabla dr_gateways y
luego añade, si presente, el prefijo definido en el campo pri_prefix de la tabla dr_gateways
para ese Gateway

Como se pueden dar cuenta la complejidad de escenarios que se pueden crear es bastante amplia. La
idea, en este curso, es que logren sacar llamadas y que sepan como configurar rutas de respaldo.

Ahora vamos a crear este tipo de escenario:

1. se crearán tres grupos distintos: uno que tiene acceso solamente a llamadas a fijos colombianos,
otro que tiene acceso solamente a llamadas a fijos y celulares colombianos y para terminar otro
que tiene acceso a llamadas a fijos, celulares e internacionales (TIENEN que personalizar la
configuración para su país)
2. se configurarán dos GATEWAY; uno principal y uno de respaldo
3. Se definirán las reglas para las llamadas a fijos, para llamadas a celulares y para llamadas
internacionales. Estas reglas son para las llamadas a Colombia. TIENEN que adaptarlas a su
país

Una vez realizada la configuración en la base de datos, se modificará el archivo de configuración de


Kamailio.

4
Se inicia entrando en el cliente MariaDB

mysql

MariaDB [(none)]> use kamailio

Se añade la primera entrada donde se indica que solamente el usuario 1000 del primer dominio tendrá
acceso a todas las llamadas (fijos, celulares, internacionales). La idea del numero presente en el campo
groupid es que de a entender de que permisos se tratan.

IMPORTANTE: Cambiar la XX con los dos números de su primer sub dominio asignado:

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1000','sipXX.kamailio.club','57300','fijos,celulares,intern');

El usuario 1001 del mismo dominio tendrá acceso a las llamadas a fijos y celulares:

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1001','sipXX.kamailio.club','573','fijos,celulares');

El usuario 1002 del primer dominio tendrá acceso a las llamadas a fijos:

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1002','sipXX.kamailio.club','57','fijos');

Luego se define que todos los usuarios del segundo dominio asignado tendrán acceso a llamadas a fijos
y no más.

IMPORTANTE: Cambiar XX con los dos dígitos de su segundo sub dominio asignado:

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1000','sipXX.kamailio.club','57','fijos');

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1001','sipXX.kamailio.club','57','fijos');

MariaDB [kamailio]> insert into dr_groups (username,domain,groupid,description) values


('1002','sipXX.kamailio.club','57','fijos');

IMPORTANTE: hay que crear una entrada para cada usuario configurado en el sistema. Esto
quiere decir que cada vez que se cree un nuevo usuario, habrá que crear una nueva entrada en la
tabla dr_groups

El resultado final será:

MariaDB [kamailio]> select * from dr_groups;

5
Terminada esta parte se configuran dos GATEWAY. La idea es que uno sea el principal y uno de
respaldo (la IP son reales y son dos servidores que les permitirá sacar las llamadas):

MariaDB [kamailio]> insert into dr_gateways (address,strip,description) values


('50.116.31.15','0','VozToVoice Principal');

MariaDB [kamailio]> insert into dr_gateways (address,strip,description) values


('173.255.199.156','0','VozToVoice Respaldo');

El resultado final será:

MariaDB [kamailio]> select * from dr_gateways;

Por ultimo se definen las reglas para las llamadas a fijos, celulares y internacionales (En Colombia 1 2
y de 4 a 9 son prefijos para llamadas a fijos, 3 es el prefijo para llamadas a celulares; 57 es el prefijo del
país). Claramente las entradas se pueden elaborar más, diferenciando, por ejemplo, las llamadas a
celulares según los prefijos de cada operador o diferenciando los países para las llamadas
internacionales. En esta guía se muestra una configuración básica que les permita luego poder trabajar
con el modulo conociendo su funcionamiento:

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','571','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','572','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','574','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','575','1,2','VozToVoice Fijos');

6
MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values
('57,573,57300','576','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','577','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','578','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57,573,57300','579','1,2','VozToVoice Fijos');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('573,57300','573','1,2','VozToVoice Celulares');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,gwlist,description) values


('57300','00','1,2','VozToVoice Internacionales');

El resultado:

MariaDB [kamailio]> select * from dr_rules;

Se sale del cliente MariaDB:

MariaDB [kamailio]> quit

Ahora se puede pasar a la configuración de Kamailio. Se crea una copia del archivo con la
configuración del segundo escenario del modulo DISPATCHER:

cd /etc/kamailio

cp /etc/kamailio/kamailio.cfg /etc/kamailio/kamailio.cfg.dispatcher2

IMPORTANTE: al final del documento encuentran las instrucciones para descargar el archivo
de configuración como va a quedar al terminar esta parte.

7
Se abre el archivo de configuración de Kamailio:

kacfg

se comenta esta linea (17):

#!define WITH_DISPATCHER

para desactivar el modulo DISPATCHER y todos los bloques relacionados:

# #!define WITH_DISPATCHER

después de esa linea se añade:

#!define WITH_DROUTING

luego después de este bloque (desde la linea 425):

# ----- dialog params -----


modparam("dialog", "dlg_flag", 0)
modparam("dialog", "default_timeout", 21600)
modparam("dialog", "db_url", DBURL)
modparam("dialog", "db_mode", 1)
modparam("dialog", "send_bye", 1)
modparam("dialog", "ka_timer", 3)
modparam("dialog", "ka_interval", 30)
modparam("dialog", "ka_failed_limit", 1)
modparam("dialog", "track_cseq_updates", 1)

se añade:

#!ifdef WITH_DROUTING
# -----drouting module and keepalive-----
loadmodule "keepalive.so"
loadmodule "drouting.so"
modparam("drouting", "ruri_avp", '$avp(dr_ruri)')
modparam("drouting", "attrs_avp", '$avp(dr_attrs)')
modparam("drouting", "use_domain", 1)
modparam("drouting", "enable_keepalive", 1)
modparam("drouting", "db_url", DBURL)
#!endif

• en la primera linea se averigua si la sentencia WITH_DROUTING está activada. Si así fuera se


continua con las lineas que siguen sino se salta el bloque
• en la segunda linea una descripción

8
• en la tercera linea se carga el modulo keepalive que se utilizará para el monitoreo de los
Gateway configurados en la tabla dr_gateways
• en la cuarta linea se carga el modulo drouting
• en la quinta linea se configura la variable que contendrá los destinos alternativos para terminar
la llamada en el caso en que el primer intento no tenga éxito
• en la sexta linea se configura la variable que contendrá los atributos asociados con el gateway
seleccionado. Si se quiere utilizar el sistema de prioridad y/o peso, este parámetro es
indispensable
• en la séptima linea se configura el modulo para que trabaje en un escenario multidominio
• en la octava linea se activa el monitoreo de los Gateway utilizando el modulo KEEPALIVE
• en la novena linea se indica la conexión a la base de datos
• en la ultima se cierra el ciclo iniciado con la sentencia #!ifdef

Se pasa al script de Kamailio. Después de este bloque (desde la linea 548):

# user location service


route(LOCATION);

se añade:

#!ifdef WITH_DROUTING
route(DROUTING);
#!endif

y antes del bloque que empieza con (desde la linea 560):

#!ifdef WITH_DISPATCHER
route[DISPATCHER] {

se añade:

#!ifdef WITH_DROUTING
route[DROUTING] {
if (do_routing()) {
t_on_failure("GWFAILURE");
route(RELAY);
} else {
send_reply("404","No Route found");
exit;
}
}
#!endif

Que se lee: si la función do_routing tiene éxito (encuentra una ruta para la llamada basándose en el
usuario que está llamando y el destino) se procesa la llamada en la subruta RELAY; si no se logra
enviar la llamada por cualquier motivo, se salta a la ruta de error GWFAILURE. Luego después de
este bloque (desde la linea 1157):

9
failure_route[MESSAGE_FAILURE] {
if (m_store()) {
xlog("L_NOTICE","Mensaje fuera de linea almacenato");
t_reply("202", "Accepted");
} else {
xlog("L_NOTICE","Mensaje fuera de linea no almacenato");
t_reply("503", "Service Unavailable");
}
}

se añade:

#!ifdef WITH_DROUTING
failure_route[GWFAILURE] {
if (t_is_canceled()) {
exit;
}
xlog("L_NOTICE","Gateway Failover");
# detect failure and redirect to next available GW
if (t_check_status("(408)|([56][0-9][0-9])")) {
xlog("Failed GW $rd detected \n");

if ( use_next_gw() ) {
t_on_failure("GWFAILURE");
t_relay();
exit;
}

send_reply("500","All GW are down");


}
}
#!endif

Donde si la respuesta SIP recibida al INVITE está incluida en los códigos de error indicados (408 o que
empiezan con 5 o 6 y siguen con un numero entre 0 y 9 y terminan con un numero entre 0 y 9) se
intenta sacar la llamada por otro GATEWAY (la ruta/rutas de respaldo) utilizando la función
use_next_gw. Si no se lograra sacar la llamada también con el/los GATEWAY de respaldo, se contesta
que todos los GATEWAY están caídos/no disponibles.

Al final del archivo se añade:

event_route[keepalive:dst-up] {
xlog("L_NOTICE", "Gateway Activo: $rm $ru\n");
}

event_route[keepalive:dst-down] {

10
xlog("L_NOTICE", "Gateway Inactivo $rm $ru\n");
}

Son dos rutas de tipo evento activadas por el modulo KEEPALIVE que señalan en el LOG del Proxy
SIP cada cambio que se presente en el estado de los Gateway monitoreados; en el caso del modulo
DROUTING los GATEWAY configurados en la tabla dr_gateways.

Se guardan los cambios y se controla que la sintaxis del archivo de configuración de Kamailio esté
correcto:

kamailio -c /etc/kamailio/kamailio.cfg

Listening on
udp: 108.61.78.60 [108.61.78.60]:5060
udp: 10.39.96.3 [10.39.96.3]:5060
Aliases:

config file ok, exiting...

Si no salen errores, se reinicia Kamailio:

systemctl restart kamailio

Al primer control realizado por el modulo KEEPALIVE sobre el estado de los dos Gateway
configurados, en el LOG de Kamailio veremos:

NOTICE: {2 10 OPTIONS 6d54cb310dadf4e2-19465@108.61.86.103} <script>: Gateway Activo: OPTIONS sip:173.255.199.156


NOTICE: {2 10 OPTIONS 6d54cb310dadf4e3-19465@108.61.86.103} <script>: Gateway Activo: OPTIONS sip:50.116.31.15

El mensaje SIP de tipo OPTIONS se envía de forma predefinida cada 30 segundos. Si se quiere
modificar este valor, hay que utilizar el parámetro ping_interval. Para realizar el control cada 10
segundos sería:

modparam("keepalive", "ping_interval", 10)

si un Gateway se cae o se vuelve inalcanzable, veremos el mensaje en el LOG de Kamailio:

NOTICE: <script>: Gateway Inactivo OPTIONS sip:173.255.199.156

Y a partir de ese momento el Gateway no será tomado en cuenta por el modulo DROUTING para las
llamadas salientes. Con el modulo se activa un comando para recargar la configuración del modulo sin
tener que reiniciar Kamailio:

kamcmd drouting.reload

Ahora se pueden realizar las primeras pruebas. Se registra la usuario 1000 del primer dominio y se
intentan sacar tres llamadas:

11
• una a un fijo
• una a un celular
• una internacional

deberían funcionar todas. Se registra la usuario 1001 del primer dominio y se intenta sacar tres
llamadas:

• una a un fijo
• una a un celular
• una internacional

La llamada internacional no debería funcionar y si se activa la captura de paquetes después de que el


usuario se ha autenticado correctamente, Kamailio contestará con 404 No Route found:

Si se registra la usuario 1002 y se intenta sacar una llamada a celular debería pasará lo mismo

Si quieren realizar una prueba del funcionamiento del campo priority de la tabla dr_rules, añadan dos
reglas más utilizando el mismo prefijo; en mi caso:

mysql

MariaDB [(none)]> use kamailio

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,priority,gwlist,description) values


('57,573,57300','57318','100','1','VozToVoice Claro1');

MariaDB [kamailio]> insert into dr_rules (groupid,prefix,priority,gwlist,description) values


('57,573,57300','57318','50','2','VozToVoice Claro1');

12
como la primera regla tiene un prioridad más alta, cada vez que se marque un numero cuyo prefijo
inicia con 57318, siempre se escogerá el primer Gateway para terminar la llamada.

MariaDB [kamailio]> quit

Como se ha explicado anteriormente, para recargar las reglas sin reiniciar Kamailio, se utiliza el
siguiente comando:

kamcmd drouting.reload

Luego para ver si efectivamente se utiliza el primer gateway para terminar la llamada, se activa el
debug de Kamailio:

kamctl srv debug 3

y se marca a un numero cuyo prefijo inicie con 57318 PERSONALIZAR SEGÚN SU


CONFIGURACIÓN. Una vez marcado el numero se para el debug:

kamctl srv debug 2

y se busca cualquier LOG relacionado con el modulo DROUTING:

cat /var/log/kamailio.log | grep drouting

Entre tantas lineas aparecerá:

drouting [drouting.c:973]: do_routing(): setting the gw [0] as ruri "sip:573182409064@50.116.31.15"

que significa que efectivamente la llamada se sacó con el Gateway configurado en la regla con más alta
prioridad.

Realicen más pruebas y comenten sus resultados en el foro de este modulo Semanal.

Para bajar el archivo de configuración como quedaría al terminar esta parte:

cd /etc/kamailio/

wget https://campus.voztovoice.org/kamailio/kamailio.cfg.drout

se abre:

nano kamailio.cfg.drout

se modifica la linea 91, 393, 453 y 1021 cambiando IPPublica con la IP publica de su servidor. Se
cambian las lineas 92, 142 y 1148 modificando IPPrivada con la IP privada de su servidor. Se modifica
la linea 469 cambiando sipXX.kamailio.club con el primer sub dominio asignado a su servidor. Se
guardan los cambios y se sobrescribe al archivo de configuración predefinido:

13
cp kamailio.cfg.drout kamailio.cfg

Se reinicia Kamailio:

systemctl restart kamailio

Pasamos al modulo LCR, el más complejo de los tres.

14

También podría gustarte