Buenas a todos, os planteo una duda ...
Ante un INVITE que llega a un OpenSer, para un usuario que tiene n contacs (se ha registrado desde varios sitios), el comportamiento de TM y REGISTRANT es hacer branching y paralel forking, hasta ahi todo ok.
Ahora resulta que uno o varios de los n contacs tiene Path y esto hace "saltar" las branches a otro proxy.
Todos los contact reciben su INVITE, al que contestan con sus respectivos 100 Trying, 180 Ringing, etc ...
Si un contact contesta (genera un 200 Ok), el OpenSer "autogenera" (desde el proxy que ha recibido el 200 OK) un 487 para el resto de los branches, incluidos los que van con PATH, hasta aqui todo ok Problema: algunos de los contacs estaban detrás de NAT, lo que hico que el INVITE generase peticiones de sesion a un MediaProxy, pero cuando los branches que no contestaron reciben su 487, cortan, pero es que el OpenSer tambien me llama a end_media_session, jodiendome el invento, porque el usuario se queda con una llamada con el canal de señalización abierto, pero sin RTP.
Pregunta: ¿Como se puede hacer que el end_media_session se ejecute SOLO ante el final reply del branch que contestó y no ante los 487 que van para los branches que no contestaron?, está claro que será con setbflag, pero la duda es como puedo saber, ante una llamada a lookup que este INVITE va a generar branching.
El Friday 15 February 2008 03:03:08 Raúl Alexis Betancor Santana escribió:
Buenas a todos, os planteo una duda ...
Ante un INVITE que llega a un OpenSer, para un usuario que tiene n contacs (se ha registrado desde varios sitios), el comportamiento de TM y REGISTRANT es hacer branching y paralel forking, hasta ahi todo ok.
Ahora resulta que uno o varios de los n contacs tiene Path y esto hace "saltar" las branches a otro proxy.
Lo que tienes que hacer es tratar todos esos temas dentro de un "branch_route[ ]". Es decir, tras hacer el lookup("location") no hagas "nada" más dentro de ese "route",
Algo así:
route { [...]
t_on_branch("ON_BRANCH_TO_USER"); if (! lookup("location") sl_send_error(; exit; } t_relay()
}
branch_route[ON_BRANCH_TO_USER] { Tratar aquí cada nuevo branch por separado. Por ejemplo:
ifbflagset(BFLAG_NATTED_USER) use_media_proxy(); }
Todos los contact reciben su INVITE, al que contestan con sus respectivos 100 Trying, 180 Ringing, etc ...
Si un contact contesta (genera un 200 Ok), el OpenSer "autogenera" (desde el proxy que ha recibido el 200 OK) un 487 para el resto de los branches, incluidos los que van con PATH, hasta aqui todo ok Problema: algunos de los contacs estaban detrás de NAT, lo que hico que el INVITE generase peticiones de sesion a un MediaProxy,
Eso es porque llamas a "use_media_proxy()" desde el route. Por ejemplo, supongamos que un AoR está registrado desde NAT y desde una IP pública. Si tras el "lookup(location)" haces en el mismo route un: ifbflagset(BFLAG_NATTED_USER) entonces es una lotería: - Si el primer contanto que aparece en location está tras NAT entonces se esa función "ifbflagset" devuelve TRUE. - Si el primer contanto que aparece en location está tras IP pública entonces se esa función "ifbflagset" devuelve FALSE. Es decir, no hay forma de hacer distinción. En cambio si haces esa comprobación dentro de un branch_route sí que se actuará por separado, pues dentro de un branch_route se actua sobre cada branch por separado, y cada branch tiene su RURI, sus flags...
pero cuando los branches que no contestaron reciben su 487, cortan, pero es que el OpenSer tambien me llama a end_media_session, jodiendome el invento, porque el usuario se queda con una llamada con el canal de señalización abierto, pero sin RTP.
No te debería pasar eso si haces lo que te comento, garantizado.
Saludos.
El Friday 15 February 2008 08:36:59 Iñaki Baz Castillo escribió:
Lo que tienes que hacer es tratar todos esos temas dentro de un "branch_route[ ]". Es decir, tras hacer el lookup("location") no hagas "nada" más dentro de ese "route",
Algo así:
route { [...]
t_on_branch("ON_BRANCH_TO_USER"); if (! lookup("location") sl_send_error(; exit; } t_relay()
}
branch_route[ON_BRANCH_TO_USER] { Tratar aquí cada nuevo branch por separado. Por ejemplo:
ifbflagset(BFLAG_NATTED_USER) use_media_proxy(); }
Buff, me va tocar rehacer todo el script, hasta ahora yo tenía chorrocientos route[n], para que cada uno hicera una cosa muy concreta (comprobar y setear un CLI de un cliente, activar accounting, etc.)
Si modifico solo el route que trata el invite, derivando los branches a un branch_route, ¿puedo desde ahi seguir llamando a mis route anteriores que ejecutaban mis "funciones"?, supongo que sí .. pero ahora el tema del branching me descoloca un poco .. toca repasar docu.
Eso es porque llamas a "use_media_proxy()" desde el route. Por ejemplo, supongamos que un AoR está registrado desde NAT y desde una IP pública.
Correcto, es lo que hacía. Ya veo que no lo entendí correctamente, de hecho me mosqueaba muy mucho, que todos los INVITE's "forkeados" que salian hacia los distintos UA's tubiesen exactamente el mísmo identificador de branch, cuando se supone que cada uno debería de tener uno distinto.
Si tras el "lookup(location)" haces en el mismo route un: ifbflagset(BFLAG_NATTED_USER) entonces es una lotería:
- Si el primer contanto que aparece en location está tras NAT entonces se
esa función "ifbflagset" devuelve TRUE.
- Si el primer contanto que aparece en location está tras IP pública
entonces se esa función "ifbflagset" devuelve FALSE. Es decir, no hay forma de hacer distinción. En cambio si haces esa comprobación dentro de un branch_route sí que se actuará por separado, pues dentro de un branch_route se actua sobre cada branch por separado, y cada branch tiene su RURI, sus flags...
Ajá, gracias por la aclaración.
pero cuando los branches que no contestaron reciben su 487, cortan, pero es que el OpenSer tambien me llama a end_media_session, jodiendome el invento, porque el usuario se queda con una llamada con el canal de señalización abierto, pero sin RTP.
No te debería pasar eso si haces lo que te comento, garantizado.
Ok, entonces modificaré el script para trabajar de la siguiente manera ...
route[0] { .... if(is_method("INVITE")) { route(13); # } ... } ... route[13] { sl_send_reply("100", "Trying"); ... t_on_branch(2); if(!lookup("location")) { xlog("L_INFO", "Local user offline - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n"); ... } t_relay() ... } ... branch_route[2] { route(12) } #######################
La duda la tengo, en si puedo llamar a route(12) desde el branch_route y que sigua el flujo que ya tenía antes definido en el script.
El Friday 15 February 2008 10:56:30 Raúl Alexis Betancor Santana escribió:
Buff, me va tocar rehacer todo el script, hasta ahora yo tenía chorrocientos route[n], para que cada uno hicera una cosa muy concreta (comprobar y setear un CLI de un cliente, activar accounting, etc.)
Si modifico solo el route que trata el invite, derivando los branches a un branch_route, ¿puedo desde ahi seguir llamando a mis route anteriores que ejecutaban mis "funciones"?, supongo que sí .. pero ahora el tema del branching me descoloca un poco .. toca repasar docu.
¡¡ Sí !! esa es la buena noticia ;)
Desde un branch_route puedes llamar a un route y en ese caso sólo se actuará sobre cada branch. Comprobadísimo :)
Ok, entonces modificaré el script para trabajar de la siguiente manera ...
route[0] { .... if(is_method("INVITE")) { route(13); # } ... } ... route[13] { sl_send_reply("100", "Trying"); ... t_on_branch(2); if(!lookup("location")) { xlog("L_INFO", "Local user offline - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n"); ... } t_relay() ... } ... branch_route[2] {
Yo aquí añadiría: xlog("branch_route[2]: RURI = $ru \n"); (así verás cada branch y su localización, para debugueo y tal).
route(12) } #######################
La duda la tengo, en si puedo llamar a route(12) desde el branch_route y que sigua el flujo que ya tenía antes definido en el script.
Sí :)
La duda más estúpida del mundo ...
t_on_branch(n) "salta" automáticamente después del lookup() o la secuencia es t_on_branch(n) ... lookup() ... t_relay() ¿?
Porque siendo el segundo caso ¿que pasa si solo hay un AoR y no varios? .. ¿salta igualmente al branch_route[n]?
El Friday 15 February 2008 11:37:20 Raúl Alexis Betancor Santana escribió:
La duda más estúpida del mundo ...
t_on_branch(n) "salta" automáticamente después del lookup() o la secuencia es t_on_branch(n) ... lookup() ... t_relay() ¿?
on_branch[ ] se ejecuta tras crear la transacción, o sea, justo al hacer t_relay().
Porque siendo el segundo caso ¿que pasa si solo hay un AoR y no varios? .. ¿salta igualmente al branch_route[n]?
Sí, salta aunque sólo haya uno, es lo mismo.
El Friday 15 February 2008 10:44:09 Iñaki Baz Castillo escribió:
El Friday 15 February 2008 11:37:20 Raúl Alexis Betancor Santana escribió:
La duda más estúpida del mundo ...
t_on_branch(n) "salta" automáticamente después del lookup() o la secuencia es t_on_branch(n) ... lookup() ... t_relay() ¿?
on_branch[ ] se ejecuta tras crear la transacción, o sea, justo al hacer t_relay().
Porque siendo el segundo caso ¿que pasa si solo hay un AoR y no varios? .. ¿salta igualmente al branch_route[n]?
Sí, salta aunque sólo haya uno, es lo mismo.
Bien, el cambio ha sido menos dramático de lo que me pensaba .. menos mal, ya tenía sudores frios si tenía que volver a plantear todo el script .. XDD
Un tema sobre las pseudovariables ... $ou siempre contiene la RURI original ¿verdad?, es que tengo un caso rana que tenía resuelto haciendo $ru=$ou y no quería que ahora eso se fuera al garete con el branch
El Friday 15 February 2008 11:58:33 Raúl Alexis Betancor Santana escribió:
Un tema sobre las pseudovariables ... $ou siempre contiene la RURI original ¿verdad?, es que tengo un caso rana que tenía resuelto haciendo $ru=$ou y no quería que ahora eso se fuera al garete con el branch
Sí, $ou tiene el RURI original que llegó a OpenSer. Incluso aunque hagas cambios sucesivos del $ru, $ou sigue conteniendo el original.
sr-users-es@lists.kamailio.org