什么是uac trunk auth,看这里就知道了
1. A -> INVITE -> OpenSIPS B
2. A OpenSIPS -> INVITE -> B
3. A OpenSIPS <- 401(7) <- B
4. A OpenSIPS -> INVITE (auth) -> B
5. A OpenSIPS <- 200 <- B
6. A <- 200 <- OpenSIPS
OpenSIPS3.2的uac trunk auth要比Kamailio复杂了一点点,Kamailio支持CSeq自动增加,而OpenSIPS需要在路由脚本里面处理
我在网上找到了一篇文章,内容如下:
#------------ uac related parts
loadmodule "uac_auth.so"
modparam("uac_auth","auth_realm_avp","$avp(uac_realm)")
modparam("uac_auth","auth_username_avp","$avp(uac_username)")
modparam("uac_auth","auth_password_avp","$avp(uac_password)")
loadmodule "uac.so"
loadmodule "uac_registrant.so"
modparam("uac_registrant", "db_url", "mysql://astercc:astercc@localhost/opensips")
modparam("uac_registrant", "timer_interval", 120)
modparam("uac_registrant", "hash_size", 2)
# In DB we're storing info on external services where to register
modparam("uac_registrant", "db_url", DBURL)
...
route {
...
# Handle sequential requests part
if (has_totag()) {
if (loose_route()) {
...
} else {
...
if (is_method("ACK") && isflagset(AUTH_DONE)) {
# Process ACK's
if ($cs == $avp(original_cseq)) {
route(INCREASE_CSEQ);
}
}
...
}
}
...
# CANCEL processing
if (is_method("CANCEL")) {
# Addition of process CSeq in a case of auth call
if (isflagset(AUTH_DONE)) {
# Process CANCEL's to both sides
if ($cs == $avp(original_cseq)) {
route(INCREASE_CSEQ);
} else {
route(RESTORE_CSEQ);
}
}
...
}
...
# INVITE processing
if (is_method("INVITE")) {
...
# Here to find out call to external auth trunk
if (...) {
$avp(original_cseq) = $cs;
setflag(IS_OUTBOUND_CALL);
# Also point, here, if we already know that trunk with username and pass, provider may require specific Form and To fields
#if (...) {
# uac_replace_to("sip:$tU@$rd");
# uac_replace_from("sip:$avp(uac_username)@$rd");
#}
}
...
}
onreply_route[1] {
...
# On reply just restore original CSeq.
route(RESTORE_CSEQ);
...
}
failure_route[1] {
...
# Authentication reply on outbound call received?
if (t_check_status("40[17]") && isflagset(IS_OUTBOUND_CALL)) {
# Have we already tried to authenticate?
if (isflagset(AUTH_DONE)) {
t_reply("503","Authentication failed");
exit;
}
# Set flag of auth preformed
setflag(AUTH_DONE);
# Getting realm from responce
# Get Proxy-Auth header
if ($(<reply>hdr(Proxy-Authenticate))) {
$var(raw_auth) = $(<reply>hdr(Proxy-Authenticate));
}
# Prefer WWW-Authenticate to Proxy-Authenticate
if ($(<reply>hdr(WWW-Authenticate))) {
$var(raw_auth) = $(<reply>hdr(WWW-Authenticate));
}
$var(reg_start) = "/(.*?)realm=\"//g";
$var(reg_end) = "/\"(.*)//g";
$var(raw_auth) = $(var(raw_auth){re.subst,$var(reg_start)});
$avp(uac_realm) = $(var(raw_auth){re.subst,$var(reg_end)});
# --- Here we assume, that avp(uac_username) and avp(uac_password) are set elsewhere
if (uac_auth()) {
route(INCREASE_CSEQ);
} else {
exit;
}
route(RELAY);
}
...
}
route[RESTORE_CSEQ] {
if (isflagset(AUTH_DONE) && is_avp_set("$avp(original_cseq)")) {
remove_hf("CSeq:");
append_hf("CSeq: $avp(original_cseq) $rm\r\n", "Call-ID");
}
}
route[INCREASE_CSEQ] {
if (isflagset(AUTH_DONE) && is_avp_set("$avp(original_cseq)")) {
$var(inc_cseq) = $(avp(original_cseq){s.int}) + 1;
remove_hf("CSeq:");
append_hf("CSeq: $var(inc_cseq) $rm\r\n", "Call-ID");
}
}
顺便说下,文章自然是好文章,但不必完全照抄,主要是看思路。