SIP协议入门
1. 注册
RFC时序图
OpenSips中文网 数据库表的描述 配置两台FS负载均衡(方案介绍、重定向分发) 核心函数 主题列表 ds分发逻辑
接到任何消息都返回 200OK:


两个表:
subscriber 存放分机号、密码等信息(预先注册的账号、密码)
location 已注册的分机信息(在线用户的表)
select * from location; 查看在线/注册用户,服务器会定期去清理这些表。
在在线和离线状态间切换,就可以发现 location 表中的内容发生变化,同时能够抓到 REGISTER 的信令的包。
![]()

注册就是为了接电话,实际上是告诉服务器,我上线了,其它人打进来电话,服务器就会找到我。
实际上不注册也能拨电话,用户的账号密码,也是早先就建好了的,采用摘要认证的方式进行密码的密文传输。
服务器也可以把 REGISTER 的信息放到数据库中,也可以把这些信息放到内存中。
脚本:
scp root@192.168.2.95:/usr/local/etc/opensips/opensips.cfg .
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
# the "Residential" scenario.
# You can enable / disable more features / functionalities by
# re-generating the scenario with different options.#
#
# Please refer to the Core CookBook at:
# https://opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
log_level=3
log_stderror=no
log_facility=LOG_LOCAL0
children=4
/* uncomment the following lines to enable debugging */
#debug_mode=yes
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
/* comment the next line to enable the auto discovery of local aliases
based on reverse DNS on IPs */
auto_aliases=no
listen=udp:192.168.2.95:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local//lib64/opensips/modules/"
db_default_url="mysql://opensips:opensipsrw@192.168.2.95:3306/opensips"
#loadmodule "proto_udp.so"
loadmodule "db_mysql.so"
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "use_domain", 1)
modparam("auth_db", "password_column", "password")
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "db_mode", 1)
modparam("usrloc", "nat_bflag", "NAT_BFLAG")
modparam("usrloc", "use_domain", 1)
modparam("usrloc", "hash_size", 16)
#modparam("usrloc", "nat_bflag", "NAT")
#modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "max_contacts", 1)
modparam("registrar", "min_expires", 30)
modparam("registrar", "max_expires", 300)
modparam("registrar", "default_expires", 120)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header("10")) {
send_reply("483","Too Many Hops");
exit;
}
if (is_method("OPTIONS")){
t_reply("200", "OK");
exit;
}
$var(pTg) = has_totag();
xlog("method[$rm] has_totag = $var(pTg)");
if ( $var(pTg) > 0) {
if (loose_route()) {
xlog("loose_route ---> as receive message method[$rm]");
# route it out to whatever destination was set by loose_route() in $du (destination URI).
route(relay);
}
else
{
if ( is_method("ACK") )
{
if ( t_check_trans() )
{
# non loose-route, but stateful ACK; must be an ACK after a 487 or e.g. 404 from upstream server
xlog("receive message method[$rm] then do t_relay");
t_relay();
exit;
}
else
{
xlog("receive message method[$rm] no transaction , then exit");
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if (!is_method("REGISTER|MESSAGE")) {
record_route();
}
if (is_method("PUBLISH|SUBSCRIBE")) {
t_reply("405", "Method Not Allowed ");
exit;
}
if (is_method("REGISTER")) {
xlog("rhjiang---test--Do REGISTER AUTH : [$rm] ci[$ci] si[$si] sp[$sp] rd[$rd] rU[$rU] fU[$fU]");
route(AUTH);
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply("484","Address Incomplete");
exit;
}
if (!lookup("location","m")) {
t_reply("404", "Not Found");
exit;
}
route(relay);
## preloaded route checking
#if (loose_route()) {
# xlog("L_ERR",
# "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
# if (!is_method("ACK"))
# send_reply("403","Preload Route denied");
# exit;
#}
## record routing
#if (!is_method("REGISTER|MESSAGE"))
# record_route();
## account only INVITEs
#if (is_method("INVITE")) {
#
# do_accounting("log");
#}
#
#if (!is_myself("$rd")) {
# append_hf("P-hint: outbound\r\n");
#
# route(relay);
#}
## requests for my domain
#
#if (is_method("PUBLISH|SUBSCRIBE")) {
# send_reply("503", "Service Unavailable");
# exit;
#}
#if (is_method("REGISTER")) {
# # store the registration and generate a SIP reply
# if (!save("location"))
# xlog("failed to register AoR $tu\n");
# exit;
#}
#if ($rU==NULL) {
# # request with no Username in RURI
# send_reply("484","Address Incomplete");
# exit;
#}
## do lookup with method filtering
#if (!lookup("location","m")) {
# t_reply("404", "Not Found");
# exit;
#}
## when routing via usrloc, log the missed calls also
#do_accounting("log","missed");
#route(relay);
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_reply] {
xlog("incoming reply [$ci] [$si:$sp] [$rs]\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
}
onreply_route[handle_nat] {
xlog("incoming reply [$ci] [$si:$sp] [$rs]\n");
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_reply");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply("500","Internal Error");
}
exit;
}
route[AUTH]{
$var(authRslt) = www_authorize("$td", "subscriber"); # the same as --> www_authorize("", "subscriber");
xlog("register auth result [$var(authRslt)] rd [$rd] user[$fU] source ip[$si]");
switch ($var(authRslt)) {
case -1:
send_reply("404", "Not Found");
exit;
case -2:
case -5:
send_reply("403", "Forbidden");
exit;
case -3:
case -4:
###www_challenge("$td","1");
www_challenge("$td","0");
exit;
}
$var(pA) = is_ip_registered("location", "$tu", "$si");
if ( $var(pA) < 0 ) {
xlog("====SIP contact ct:[$ct] [$fu] ci:[$ci] did not registe on, then check registe status for fU:[$fU].");
if ( is_registered("location")) {
xlog("L_WARN", "====Forbid $ct to registe on, cuase by : exist another $fU has registed");
send_reply("403", "Occupied");
exit;
}
}
if (!save("location", "f")) {
sl_reply_error();
}
$var(expire) = "0";
if ( $hdrcnt(Expires) == 0 ) {
$var(expire) = $ct.fields(expires);
xlog("no expire header ,contact expire is [$var(expire)]");
} else {
$var(expire) = $hdr(Expires);
xlog("expires header , expire [$var(expire)]");
}
exit;
}
subscriber表的内容:
mysql> select * from subscriber; +----+----------+--------------+----------+---------------+----------------------------------+----------------------------------+------+ | id | username | domain | password | email_address | ha1 | ha1b | rpid | +----+----------+--------------+----------+---------------+----------------------------------+----------------------------------+------+ | 1 | 1001 | 192.168.2.95 | 1001 | | 3aaaa10ee16d03e725ffa19c61b3e87e | c4eb44a7a7e51f576fd5219758aa0c97 | NULL | | 2 | 1002 | 192.168.2.95 | 1002 | | 4cfbb0a15c8313d96dda4a4d18bb61ec | 0111f45781f805188980eb38c0ca6e95 | NULL | +----+----------+--------------+----------+---------------+----------------------------------+----------------------------------+------+
按F2保存到路径中:

2. 拨打一通电话
INVITE:

100Trying:

INVITE:

100Trying:

180Ringing:

180Ringing:

200OK:

200OK:

ACK:

ACK:

BYE:

BYE:

200OK:

200OK:


浙公网安备 33010602011771号