You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/iptrtpproxy/oob/sip-router-oob-RTPPROXY.cfg...

432 lines
19 KiB

#
# $Id: ser-oob-RTPPROXY.cfg.inc,v 1.46 2008/09/15 15:51:44 tirpi Exp $
#
# BEGIN: RTP proxy include section
#
# INSTALLATION:
# 1) apply patch ser-oob-RTPPROXY.cfg.patch to ser-oob.cfg
# 2) add content of this file in ser-oob.cfg
# 3) modify parameters
#
# Problem when forking and early media are received. In this case we should create for each branch extra dialog_id,
# record-route it and call route[RTPPROXY_PROCESS_REQUEST] for each branch. But it's limited by
# ser lump system.
# Important: t_newtran() must be executed before RTPPROXY_PROCESS_REQUEST is executed to eat retransmissions
#
# global script flags/AVPs used:
# FLAG_INIT_DLG ... if dialog initialize request
# FLAG_NAT ... test when RTP proxy will be applied
# $dialog_id ... unique dialog id
#
# local to RTP proxy AVPs (rtp_dlg_* are dialog AVPs)
# $rtp_dlg_sess_ids ... list of confirmed (INVITE/200OK/ACK, INVITE/180/PRACK, UPDATE/200OK ) RTP sessions
# $rtp_dlg_sess_ids2 ... list of non-confirmed sessions
# $rtp_method_flag ... request method passed to onreply/failure
#
# rtpproxy.* configuration params
#
# Note: INVITE w/o offer, 200OK w/offer, PRACK/ACK w/answer (RFC3262) not supported.
# RTP Proxy options
# if RTP stream uses a different interface as SIP we can define sip-ip to find switchboard according received and next hop address
loadmodule "iptrtpproxy"
#loadmodule "modules/iptrtpproxy-v2/iptrtpproxy.so"
modparam("iptrtpproxy", "config", "/etc/iptrtpproxy.cfg");
#DEBCONF-RTTPPROXY-START
modparam("iptrtpproxy", "switchboard", "name=*;sip-addr=213.192.59.75"); ## TODO change back to .75
#modparam("iptrtpproxy", "switchboard", "name=gate_a;sip-addr=1.2.3.4;aggregation=AA")
#modparam("iptrtpproxy", "switchboard", "name=gate_b;aggregation=A")
modparam("iptrtpproxy", "codec_set", "name=any;media_type=*;rights=0;codecs=*;max_streams=9999");
modparam("iptrtpproxy", "codec_set", "name=audio_only;media_type=*;rights=0;codecs=*;max_streams=0;media_type=audio;max_streams=9999");
modparam("iptrtpproxy", "codec_set", "name=PCMU_PCMA_only;media_type=*;rights=1;codecs=*;rights=0;codecs=PCMU,PCMA");
modparam("iptrtpproxy", "codec_set", "name=parityfec_only;media_type=*;rights=1;codecs=*;rights=0;codecs=parityfec");
#DEBCONF-RTTPPROXY-END
avpflags
rtpproxy_dlg; # extra attributes
modparam("avp_db", "attr_group", "id=rtp_dlg,flag=rtpproxy_dlg,table=rtpproxy_attrs");
#
# Whether to enable or disable the rtp proxy. Possible values are:
# "0" -- always disable
# "1" -- always enable regardless of whether UAC or UAS is behind NAT
# "detect" -- detect whether the UAC or the UAS is behind NAT,
# and enable the rtp proxy when necessary
# "compare" -- Check whether the inbound and outbound interfaces
# differ. If not, do not enable rtp proxy.
#
#DEBCONF-RTP_ENABLE-START
rtp_proxy.enabled = "detect" desc "indicates whether the RTP Proxy is enabled or not (0/1/detect)"
rtp_proxy.learning_timeout = "20" desc "RTP proxy learning timeout (sec)"
rtp_proxy.ringing_timeout = "90" desc "RTP proxy ringing timeout (sec)"
rtp_proxy.expiration_timeout = "30" desc "RTP proxy expiration timeout (sec)"
rtp_proxy.always_learn = "0" desc "RTP proxy always learn (0/1)"
rtp_proxy.hide_o_addr = "" desc "Fake address to hide original address provided at SDP o= line"
rtp_proxy.codec_set = "any" desc "Codec authorization set"
# throttled packets are MARKed and need be removed by a netfilter rule in FORWARD chain
rtp_proxy.throttle_mark = "1" desc "Netfilter MARK of packets being throttled"
rtp_proxy.throttle_rtp_max_bytes = "0" desc "Max. RTP bytes per sec rate"
rtp_proxy.throttle_rtcp_max_bytes = "0" desc "Max. RTCP bytes per sec rate"
rtp_proxy.throttle_rtp_max_packets = "0" desc "Max. RTP packets per sec rate"
rtp_proxy.throttle_rtcp_max_packets = "0" desc "Max. RTCP packets per sec rate"
#DEBCONF-RTP_ENABLE-END
route[RTPPROXY_PROCESS_REQUEST] {
if (method != "INVITE" && method != "UPDATE" && method != "BYE" && method != "ACK" && method != "PRACK") {
# we are interested in INVITE/BYE dialog related requests only
break;
}
if (!defined $dialog_id) { # AVP loaded from route cookie
if (@method != "ACK")
t_reply("400", "Missing cookie"); # 500 (=our bug) in case of init request because it'd been generated by ourselves
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: missing cookie: %@hf_value.route[0]\n");
drop;
}
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST:\n%mb");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: SDP\n%@msg.content.sdp\n");
if (isflagset(FLAG_INIT_DLG)) {
# if init request then test RTP proxy is to by applied
if (@cfg_get.rtp_proxy.enabled == "0") {
# RTP Proxy is disabled
break;
} else if (@cfg_get.rtp_proxy.enabled == "detect") {
if (!isflagset(FLAG_NAT)) {
# If no NAT is involved we don't have to do here anything.
break;
}
} else if (@cfg_get.rtp_proxy.enabled != "1") {
# This is not a valid setting
xlog("L_ERR", "RTPPROXY_PROCESS_REQUEST: Unknown option for rtp_proxy.enabled: %@cfg_get.rtp_proxy.enabled\n");
return;
} # else rtp proxy is permanently enabled
if (isflagset(FLAG_RTP_PROXY)) {
break;
}
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: routing '%@received.ip'->'%@next_hop.src_ip', src_ip:%@src.ip\n");
if (@src.ip == @received.ip) {
# it's case when ser forwards message to itself, if the second pass would
# have added rtpproxy it'd rtpproxy twice through local chain, there is a problem
# in netfilter
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: do not add RTPPROXY because srcip=receivedip\n");
break;
}
if (method != "INVITE" || strempty(@msg.body)) { # limitation, initial INVITE must provide SDP to allocate session
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: initial INVITE without body\n");
break;
}
if ((@cfg_get.rtp_proxy.enabled == "compare") && (@received.ip == @next_hop.src_ip)) {
# Inbound and outbound interfaces are the same,
# do not proxy.
break;
}
}
if ((method == "INVITE" || method == "UPDATE") && @msg.body!="") {
if (@iptrtpproxy.active_media_num == "0") break;
iptrtpproxy_set_param("codec_set", "@cfg_get.rtp_proxy.codec_set");
iptrtpproxy_set_param("remove_codec_mask", "1");
if (!iptrtpproxy_authorize_media()) {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: cannot authorize media\n");
t_reply("415", "Cannot authorize media");
drop;
}
if (@iptrtpproxy.active_media_num == "0") {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: no acceptable codec\n");
t_reply("488", "Not acceptable here");
drop;
}
# if RTP stream uses the same interface as SIP we can find switchboard according received and next hop address
# It's always needed for dialog init requests but sometimes may be needed also for
# re-INVITEs in case that switchboards could not be obtained from $rtp_dlg_sess_ids2, i.e. reused existing sesssions
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: find switchboard-a for '%@received.ip'\n");
if (!iptrtpproxy_set_param("switchboard_by_sip_ip_a", "@received.ip")) {
xlog("L_ERR", "RTPPROXY_PROCESS_REQUEST: Cannot find switchboard-a for routing '%@received.ip'\n");
t_reply("500", "RTP proxy error");
drop;
}
eval_push("x:%@next_hop.src_ip");
if (@eval.get[-1] == @received.ip) {
iptrtpproxy_set_param("switchboard_b", "@iptrtpproxy.switchboard_a");
}
else {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: find switchboard-b for '%@eval.get[-1]'\n");
if (!iptrtpproxy_set_param("switchboard_by_sip_ip_b", "@eval.get[-1]")) {
xlog("L_ERR", "RTPPROXY_PROCESS_REQUEST: Cannot find switchboard for routing '%@eval.get[-1]'\n");
t_reply("500", "RTP proxy error");
drop;
}
}
eval_remove(-1, 1);
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: INVITE: %@iptrtpproxy.switchboard_a->%@iptrtpproxy.switchboard_b, learning-timeout: %@iptrtpproxy.learning_timeout, expiration-timeout: %@iptrtpproxy.expiration_timeout, always-learn: %@iptrtpproxy.always_learn\n");
# you can call a custom procedure to find switchboards and override default behaviour here
if (strempty(@iptrtpproxy.switchboard_a) || strempty(@iptrtpproxy.switchboard_b)) { # do not use proxy
break;
}
# no "uncontrolled" break bellow this line !!!
if (isflagset(FLAG_INIT_DLG)) { # INVITE && !to.tag
route("RTPPROXY_REMOVE_ATTRS");
iptrtpproxy_set_param("learning_timeout", "@cfg_get.rtp_proxy.ringing_timeout");
} else {
# remove any non-confirmed
route("RTPPROXY_LOAD_ATTRS");
if ($rtp_dlg_sess_ids2!="") {
# there is a non confirmed request in progress, wait till is confirmed
t_reply("491", "Pending request");
drop;
}
if (strempty($rtp_dlg_sess_ids)) {
# limitation, initial INVITE must provide SDP to allocate session
break; # possible because $rtp_dlg_* are null
}
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids");
iptrtpproxy_delete("$rtp_dlg_sess_ids2");
del_attr("$rtp_dlg_sess_ids2");
iptrtpproxy_set_param("learning_timeout", "@cfg_get.rtp_proxy.learning_timeout");
}
if (@cfg_get.rtp_proxy.hide_o_addr != "") {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: INVITE: rewrite o_addr='%@cfg_get.rtp_proxy.hide_o_addr'\n");
iptrtpproxy_set_param("o_addr", "@cfg_get.rtp_proxy.hide_o_addr");
}
# we are optimistic and do not expect callee will change stream ip:port when caller has not done it.
# If we want to be fully RFC3264 compliant we'd alloc completely new RTP session set for all
# streams provided in caller's SDP regardless a change detected since last confirmed INVITE.
# This solution has two drawbacks, the 1st it may lead to RTP session exhastion, the 2nd there are
# non re-INVITE compliant phones which does not like IP:port change in SDP
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids");
# throttling stuff
iptrtpproxy_set_param("throttle_mark", "@cfg_get.rtp_proxy.throttle_mark");
iptrtpproxy_set_param("throttle_rtp_max_bytes", "@cfg_get.rtp_proxy.throttle_rtp_max_bytes");
iptrtpproxy_set_param("throttle_rtcp_max_bytes", "@cfg_get.rtp_proxy.throttle_rtcp_max_bytes");
iptrtpproxy_set_param("throttle_rtp_max_packets", "@cfg_get.rtp_proxy.throttle_rtp_max_packets");
iptrtpproxy_set_param("throttle_rtcp_max_packets", "@cfg_get.rtp_proxy.throttle_rtcp_max_packets");
if (isflagset(FLAG_REVERSE_DIR)) {
eval_push("0"); # callee -> caller
} else {
eval_push("1"); # caller -> callee
}
if (!iptrtpproxy_alloc("@eval.pop[-1]")) {
t_reply("500", "RTP proxy error");
drop;
}
# we need save in dialog as non-confirmed sess_ids (not only in transaction) because
# UPDATE in non-confirmed INVITE and ACK to 200OK are considered as separate transactions.
if (@iptrtpproxy.session_ids != "")
$rtp_dlg_sess_ids2 = @iptrtpproxy.session_ids;
else
del_attr("$rtp_dlg_sess_ids2");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: allocated ids2=%$rtp_dlg_sess_ids2\n");
# session_ids are stored in AVP to let commit (on_reply) or rollback (on_failure) allocated sessions
$rtp_method_flag = @method;
append_hf("X-RTP-Proxy: YES\r\n");
setflag("FLAG_RTP_PROXY");
route("RTPPROXY_SAVE_ATTRS");
}
else if (method == "ACK" || method == "PRACK") {
# ACK after 200OK is considered as separate transaction
# we'll accept RTP sessions, in case of re-INVITE
# we cannot do it in 200OK because old and new streams must
# be traversed till ACK
# save non-confirmed as confirmed
route("RTPPROXY_LOAD_ATTRS");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: %@method, delete(ids=%$rtp_dlg_sess_ids), protect(ids2=%$rtp_dlg_sess_ids2)\n");
if (strempty($rtp_dlg_sess_ids2)) {
break; /* do not save, non SDP related re-INVITE or retrasmission which is not eaten by tm module, SDP in ACK is not supported */
}
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids2");
iptrtpproxy_delete("$rtp_dlg_sess_ids");
$rtp_dlg_sess_ids = $rtp_dlg_sess_ids2;
del_attr("$rtp_dlg_sess_ids2");
route("RTPPROXY_SAVE_ATTRS");
}
else if (method == "BYE") { # CANCEL ???
# we must delete rtp session in BYE request, otherwise we risk problem of lost 200OK to BYE
route("RTPPROXY_LOAD_ATTRS");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REQUEST: %@method delete(ids=%$rtp_dlg_sess_ids, ids2=%$rtp_dlg_sess_ids2)\n");
iptrtpproxy_set_param("protected_session_ids", "");
iptrtpproxy_delete("$rtp_dlg_sess_ids");
iptrtpproxy_delete("$rtp_dlg_sess_ids2");
route("RTPPROXY_REMOVE_ATTRS");
# $rtp_method_flag = @method; # nothing to do in onreply to BYE
}
# rtp_dlg_* have been removed to save memory
}
route[RTPPROXY_PROCESS_REPLY] {
if (!defined $dialog_id || strempty($rtp_method_flag) || strempty(@msg.body)) break;
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY:\n%mb\n");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: SDP\n%@msg.content.sdp\n");
if ($rtp_method_flag == "INVITE" && (status=~"18[0-9]" || status=~"2[0-9][0-9]")) {
# If RTP proxy was activated and this is a 18x or 2xx reply with a
# body, inform RTP proxy.
# onreply route is called for EACH retransmission, tm does NOT eat anything
if (strempty($rtp_last_code) || $rtp_last_code != @msg.res.code) {
if (@iptrtpproxy.active_media_num == "0") break;
iptrtpproxy_set_param("codec_set", "@cfg_get.rtp_proxy.codec_set");
iptrtpproxy_set_param("remove_codec_mask", "1");
if (!iptrtpproxy_authorize_media()) {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: cannot authorize media\n");
drop;
}
if (@iptrtpproxy.active_media_num == "0") {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: no acceptable codec\n");
drop;
}
# (probably) no retransmission
route("RTPPROXY_LOAD_ATTRS");
$rtp_last_code = @msg.res.code;
if (isflagset(FLAG_INIT_DLG) && status=~"18[0-9]") {
iptrtpproxy_set_param("learning_timeout", "@cfg_get.rtp_proxy.ringing_timeout");
}
else {
iptrtpproxy_set_param("learning_timeout", "@cfg_get.rtp_proxy.learning_timeout");
}
iptrtpproxy_set_param("expiration_timeout", "@cfg_get.rtp_proxy.expiration_timeout");
iptrtpproxy_set_param("always_learn", "@cfg_get.rtp_proxy.always_learn");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: update(ids2=%$rtp_dlg_sess_ids2, learning-timeout: %@iptrtpproxy.learning_timeout) protect(ids=%$rtp_dlg_sess_ids)\n");
if (@cfg_get.rtp_proxy.hide_o_addr != "") {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: INVITE: rewrite o_addr='%@cfg_get.rtp_proxy.hide_o_addr'\n");
iptrtpproxy_set_param("o_addr", "@cfg_get.rtp_proxy.hide_o_addr");
}
if (!isflagset(FLAG_REVERSE_DIR)) { # revert direction
eval_push("0"); # callee -> caller
} else {
eval_push("1"); # caller -> callee
}
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids");
# throttling stuff
iptrtpproxy_set_param("throttle_mark", "@cfg_get.rtp_proxy.throttle_mark");
iptrtpproxy_set_param("throttle_rtp_max_bytes", "@cfg_get.rtp_proxy.throttle_rtp_max_bytes");
iptrtpproxy_set_param("throttle_rtcp_max_bytes", "@cfg_get.rtp_proxy.throttle_rtcp_max_bytes");
iptrtpproxy_set_param("throttle_rtp_max_packets", "@cfg_get.rtp_proxy.throttle_rtp_max_packets");
iptrtpproxy_set_param("throttle_rtcp_max_packets", "@cfg_get.rtp_proxy.throttle_rtcp_max_packets");
if (iptrtpproxy_update("@eval.pop[-1]", "$rtp_dlg_sess_ids2")) {
if (status=~"2[0-9][0-9]") {
if (isflagset(FLAG_INIT_DLG)) {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: adjust timeout(ids2=%$rtp_dlg_sess_ids2)\n");
if (isflagset(FLAG_REVERSE_DIR)) {
eval_push("0"); # callee -> caller
} else {
eval_push("1"); # caller -> callee
}
iptrtpproxy_adjust_timeout("@eval.pop[-1]", "$rtp_dlg_sess_ids2"); # decrease ringing-timeout, a to b direction
}
# the confirmed session will be adjusted in ACK, because old media (re-INVITE) should be traversed
}
if (@iptrtpproxy.session_ids != "") {
$rtp_dlg_sess_ids2 = @iptrtpproxy.session_ids;
$rtp_last_sess_ids2 = @iptrtpproxy.session_ids; # keep it in transaction
}
else {
del_attr("$rtp_dlg_sess_ids2");
del_attr("$rtp_last_sess_ids2");
}
}
else {
;
# drop; ???
}
route("RTPPROXY_SAVE_ATTRS");
}
else {
# we MUST do the same message modifications as in first reply
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: update-retransmission(ids2=%$rtp_last_sess_ids2)\n");
if (@cfg_get.rtp_proxy.hide_o_addr != "") {
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: INVITE: retrasmission rewrite o_addr='%@cfg_get.rtp_proxy.hide_o_addr'\n");
iptrtpproxy_set_param("o_addr", "@cfg_get.rtp_proxy.hide_o_addr");
}
if (!isflagset(FLAG_REVERSE_DIR)) { # set update SDP only flag & revert direction
eval_push("2"); # callee -> caller (bin=10)
} else {
eval_push("3"); # caller -> callee (bin=11)
}
iptrtpproxy_update("@eval.pop[-1]", "$rtp_last_sess_ids2"); # TODO flag to update SDP only
}
}
else if ($rtp_method_flag == "UPDATE" && status=~"2[0-9][0-9]" && $rtp_dlg_sess_ids2!="") {
# confirm pending offer (UPDATE is not followed by ACK/PRACK)
route("RTPPROXY_LOAD_ATTRS");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_REPLY: %@method, delete(ids=%$rtp_dlg_sess_ids), protect(ids2=%$rtp_dlg_sess_ids2)\n");
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids2");
iptrtpproxy_delete("$rtp_dlg_sess_ids");
$rtp_dlg_sess_ids = $rtp_dlg_sess_ids2;
del_attr("$rtp_dlg_sess_ids2");
route("RTPPROXY_SAVE_ATTRS");
}
}
route[RTPPROXY_PROCESS_FAILURE] {
if (!defined $dialog_id || strempty($rtp_method_flag)) break;
xlog("L_EDEBUG", "RTPPROXY_PROCESS_FAILURE:\n%mb\n");
xlog("L_EDEBUG", "RTPPROXY_PROCESS_FAILURE: SDP\n%@msg.content.sdp\n");
if (isflagset(FLAG_INIT_DLG) && $rtp_method_flag == "INVITE") {
route("RTPPROXY_LOAD_ATTRS");
#remove all sessions
xlog("L_EDEBUG", "RTPPROXY_PROCESS_FAILURE: %@method delete(ids=%$rtp_dlg_sess_ids, ids2=%$rtp_dlg_sess_ids2)\n");
iptrtpproxy_set_param("protected_session_ids", "");
iptrtpproxy_delete("$rtp_dlg_sess_ids"); # early media are considered as confirmed
iptrtpproxy_delete("$rtp_dlg_sess_ids2");
route("RTPPROXY_REMOVE_ATTRS");
} else if ($rtp_method_flag == "INVITE" || $rtp_method_flag == "UPDATE") {
route("RTPPROXY_LOAD_ATTRS");
#remove only unconfirmed sessiosn
xlog("L_EDEBUG", "RTPPROXY_PROCESS_FAILURE: %@method, delete(ids2=%$rtp_dlg_sess_ids2), protect(ids=%$rtp_dlg_sess_ids)\n");
iptrtpproxy_set_param("protected_session_ids", "$rtp_dlg_sess_ids");
iptrtpproxy_delete("$rtp_dlg_sess_ids2");
del_attr("$rtp_dlg_sess_ids2");
route("RTPPROXY_SAVE_ATTRS");
}
if ($rtp_dlg_sess_ids2!="") { # ????? never TODO: retest
# do it if request really failed
# if flexroute forwards call in CAPM-PP callback then request is dropped
iptrtpproxy_set_param("protected_session_ids", "");
iptrtpproxy_delete("$rtp_dlg_sess_ids2");
del_attr("$rtp_dlg_sess_ids2");
}
}
route[RTPPROXY_LOAD_ATTRS] {
del_attr("$rtp_dlg_sess_ids");
del_attr("$rtp_dlg_sess_ids2");
load_extra_attrs("rtp_dlg", "$dialog_id");
xlog("L_EDEBUG", "RTPPROXY_LOAD_ATTRS: dialog_id=%$dialog_id, method/flag='%@method'/'%$rtp_method_flag', ids=%$rtp_dlg_sess_ids, ids2=%$rtp_dlg_sess_ids2\n");
}
route[RTPPROXY_SAVE_ATTRS] {
xlog("L_EDEBUG", "RTPPROXY_SAVE_ATTRS: dialog_id=%$dialog_id, method='%@method', ids=%$rtp_dlg_sess_ids, ids2=%$rtp_dlg_sess_ids2\n");
setavpflag("$f.rtp_dlg_sess_ids", "rtpproxy_dlg");
setavpflag("$f.rtp_dlg_sess_ids2", "rtpproxy_dlg");
save_extra_attrs("rtp_dlg", "$dialog_id");
del_attr("$rtp_dlg_sess_ids");
del_attr("$rtp_dlg_sess_ids2");
}
route[RTPPROXY_REMOVE_ATTRS] {
xlog("L_EDEBUG", "RTPPROXY_REMOVE_ATTRS: dialog_id=%$dialog_id, method='%@method'\n");
del_attr("$rtp_dlg_sess_ids");
del_attr("$rtp_dlg_sess_ids2");
remove_extra_attrs("rtp_dlg", "$dialog_id");
}
# END: RTP proxy include section