下面是篇好文章,需要精读,精读可掌握rr的原理(如果还不懂可以来问我):
https://kb.smartvox.co.uk/opensips/contact-and-record-route-headers-explained/
下面比较kamailio rr模块自带的几个函数
作用都一样,在sip包里面增加record-route头,但前者是kamailio自动加头,后者则不然,比如,下面是我的路由脚本:
route[RECORD_ROUTE] {
if (isflagset(FLT_SRC_MS_TEAMS)) {
record_route_preset("KAM_IP4_ADDR:KAM_SIP_PORT;transport=tcp", "KAM_DOMAIN:KAM_SIPS_PORT;transport=tls");
add_rr_param(";r2=on");
} else if isflagset(FLT_DST_MS_TEAMS) {
record_route_preset("KAM_DOMAIN:KAM_SIPS_PORT;transport=tls", "KAM_IP4_ADDR:KAM_SIP_PORT;transport=tcp");
add_rr_param(";r2=on");
} else {
record_route();
}
return;
}
loose_route() 等于 loose_route_mode(0)
vmode0的意思是先检查严格路由,如果失败,再做松散路由检查
但是除了vmode0之外,还有vmode1,也就是只做松散路由检查
下面是我的笔记
## 双网卡
```cfg
mhomed=1
listen=udp:KAM_IP4_PUBLIC_ADDR:KAM_SIP_PORT # eth_wan
listen=udp:KAM_IP4_PRIVATE_ADDR:KAM_SIP_PORT # eth_lan
```
主机配置好路由(去到外网需从`eth_wan`发出,去到内网需从`eth_lan`发出),`Kamailio`路由不需设置`force send socket`。
`rr`头规则应该是:
- 从外网来,到外网去,`rr` = KAM_IP4_PUBLIC_ADDR
- 从内网来,到内网去,`rr` = KAM_IP4_PRIVATE_ADDR
- 其他, `rr` = KAM_IP4_PUBLIC_ADDR + KAM_IP4_PRIVATE_ADDR (哪个先哪个后是有讲究的)
## 单网卡,一个`sip`端口
```cfg
listen=udp:KAM_IP4_PRIVATE_ADDR:KAM_SIP_PORT advertise MY_IP4_PUBLIC_ADDR:KAM_SIP_PORT
```
在`listen`里面设置`advertise`地址。
我们习惯的做法是在`Kamailio`路由调用`record_route`函数。
rr头规则应该是:
- 从内网来,到内网去,`rr` = KAM_IP4_PRIVATE_ADDR
- 其他, `rr` = KAM_IP4_PUBLIC_ADDR
我们习惯把`FreeSWITCH`和`Kamailio`都放到内网,如果从外网来,去到`FreeSWITCH`,这样就需要`FreeSWITCH`把`SIP`包发到`Kamailio`的`advertise`地址。
或者尝试在`FreeSWITCH`所在的主机上执行下面的`shell`命令:
```shell
# 需要根据实际情况修改ip地址和端口
iptables -t nat -A OUTPUT -d 124.71.66.56 -p udp --dport 5060 -j DNAT --to-destination 10.167.82.4:5060
```
## 单网卡,两个`sip`端口
```cfg
listen=udp:KAM_IP4_PRIVATE_ADDR:KAM_SIP_LAN_PORT
listen=udp:KAM_IP4_PRIVATE_ADDR:KAM_SIP_WAN_PORT advertise MY_IP4_PUBLIC_ADDR:KAM_SIP_WAN_PORT
```
也就是把`KAM_SIP_LAN_PORT`和`KAM_SIP_WAN_PORT`分开。
需要在`dispatcher.list`的`attributes`里面指定`socket`参数(当然是内网)。
`Kamailio`路由不需设置`force send socket`。设置起来很麻烦,如果在`request route`设置了,可能也需要在`reply route`设置,处理的逻辑比较复杂。
`NAT`检测变成这样:
```route
route[NATDETECT] {
if (($proto =~ "ws") || ($Rp == KAM_SIP_WAN_PORT)) {
if (is_method("REGISTER")) {
fix_nated_register();
} else {
if (is_first_hop()) {
set_contact_alias();
}
}
setflag(FLT_NATS);
}
}
```
`KEMI`检测可以参考上面这段代码。
不再需要`nat_uac_test`函数了。这种方式等于自带网络拓扑。
`rr`头规则是:
- 从外网来,到外网去,`rr` = KAM_IP4_PUBLIC_ADDR
- 从内网来,到内网去,`rr` = KAM_IP4_PRIVATE_ADDR
- 其他, `rr` = KAM_IP4_PUBLIC_ADDR + KAM_IP4_PRIVATE_ADDR
我知道的都写在这里了。
我也知道rr很不容易理解,怎么办呢? 先死记,碰到问题之后套用本文提到的方法试试,说不定有用(一般情况下是有用的,不灵的话可发pcap和kamailio路由脚本给我),解决问题之后再多看多想