rtpproxy 配置

1、下载rtpproxy并安装

cd /home/hi
下载rtpproxy最新版,比如rtpproxy-2.1.0.tar.gz
tar –xzvf rtpproxy-2.1.0.tar.gz
cd rtpproxy-2.1.0
./configure
make
make install

2、启动rtpproxy

可以根据需求启动一系列rtpproxy进程,格式如下:
./rtpproxy -l 192.168.1.122 -s udp:192.168.1.122: 20000 -F

3、OpenSIPS配置

#
# $Id$
#
# 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:
#      http://www.opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#


####### Global Parameters #########

debug=2
log_stderror=no
log_facility=LOG_LOCAL1

fork=yes
children=4

/* uncomment the following lines to enable debugging */
#debug=6
#fork=no
#log_stderror=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 revers DNS on IPs */
auto_aliases=no

listen=udp:192.168.1.216:5060   # CUSTOMIZE ME 
listen=tcp:192.168.1.122:5050   # CUSTOMIZE ME 
# Udp和tcp的地址填写该opensips服务器的地址

####### Modules Section ########
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600)  # 6 hours timeout
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME

####  NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger@127.0.0.1") #CUSTOMIZE ME
modparam("nathelper", "received_avp", "$avp(received_nh)")

loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:192.168.1.122:20000") # CUSTOMIZE ME
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

4、参考资料http://blog.sina.com.cn/s/blog_6e74c5df0102vdkv.html

rtpproxy 初始化代码分析

rtpproxy启动

./rtpproxy -A 110.172.192.68 -l 0.0.0.0 -s udp:localhost:7890 -n tcp:localhost:7890 -F -d DBUG -m 50002 -M 50020 -d
  • 1

log_level:log_facility
参数解释如下:
-A 本机外网地址
-l 本机内网侦听地址
-s 本机侦听opensips通知端口
-n 超时通知接收端口
-F 不检查是否为超级用户模式
-d 调试消息输出级别
-m rtp最小端口
-M rtp最大端口

-d
log_level为日志级别,值如下
DBUG INFO WARN ERR CRIT
log_facility为日志输出到哪,利用的系统日志

         {"LOG_AUTH",     LOG_AUTH},
    {"LOG_CRON",     LOG_CRON},
    {"LOG_DAEMON",   LOG_DAEMON},
    {"LOG_KERN",     LOG_KERN},
    {"LOG_LOCAL0",   LOG_LOCAL0},
    {"LOG_LOCAL1",   LOG_LOCAL1},
    {"LOG_LOCAL2",   LOG_LOCAL2},
    {"LOG_LOCAL3",   LOG_LOCAL3},
    {"LOG_LOCAL4",   LOG_LOCAL4},
    {"LOG_LOCAL5",   LOG_LOCAL5},
    {"LOG_LOCAL6",   LOG_LOCAL6},
    {"LOG_LOCAL7",   LOG_LOCAL7},
    {"LOG_LPR",      LOG_LPR},
    {"LOG_MAIL",     LOG_MAIL},
    {"LOG_NEWS",     LOG_NEWS},
    {"LOG_USER",     LOG_USER},
    {"LOG_UUCP",     LOG_UUCP},
#if !defined(__solaris__) && !defined(__sun) && !defined(__svr4__)
    {"LOG_AUTHPRIV", LOG_AUTHPRIV},
    {"LOG_FTP",      LOG_FTP},
    {"LOG_SYSLOG",   LOG_SYSLOG},
#endif
    {NULL,           0}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

入口:main.c

int main(int argc, char **argv)
{
int i, len, timeout, controlfd, alarm_tick;
double sptime, eptime, last_tick_time;
unsigned long delay;
struct cfg cf;
char buf[256];

//初始化配置,将启动时传入的参数保存到cf结构体中
init_config(&cf, argc, argv);                     

 //将1~255数随机存储在cf.stable.rand_table[256]数组中
init_hash_table(&cf.stable);       

//初始化媒体流端口,-m 50002 -M 50020端口范围用于媒体流中转,并且成对使用
 //此函数将指定的端口范围保存在cf.stable.port_table[65536]数组中,保存端口对中的一个. 并将对port_table[]下标查找的最大值保存在cf.port_table_idx                                      
    init_port_table(&cf);               

//创建与opensips命令交互的socket,并进行端口绑定,绑定的端口为 -s 传进来的参数
controlfd = init_controlfd(&cf);

//日志初始化,利用的是系统日志,在启动参数中配置
glog = cf.stable.glog = rtpp_log_open(&cf.stable, "rtpproxy", NULL, LF_REOPEN);

//创建一个超时通知线程rtpp_notify_queue_run,绑定的socket端口为 -n传进来的参数
if (cf.timeout_socket != NULL) {    
    cf.timeout_handler = rtpp_notify_init(glog, cf.timeout_socket);
}

//写pid到/var/run/rtpproxy.pid文件中
i = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
len = sprintf(buf, "%u\n", (unsigned int)getpid());
write(i, buf, len);
close(i);

//设置此进程的user ID和group ID,对应配置参数为-u uname:gname
if (cf.stable.run_uname != NULL || cf.stable.run_gname != NULL)
    drop_privileges(&cf);
cf.stable.controlfd = controlfd;
cf.sessinfo.sessions[0] = NULL;
cf.sessinfo.nsessions = 0;
cf.rtp_nsessions = 0;
//创建rtpp_cmd_queue_run线程监听和处理controlfd的数据
rtpp_command_async_init(&cf);         
sptime = 0;
eptime = getdtime();
last_tick_time = 0;
timeout = 1000 / POLL_RATE;
for (;;) {                               
delay = (eptime - sptime) * 1000000.0;
if (delay <= 0) {
sptime = eptime;
last_tick_time = 0;
} else if (delay < (1000000 / POLL_RATE)) {
sptime += 1.0 / (double)POLL_RATE;
usleep((1000000 / POLL_RATE) - delay);
} else {
sptime = eptime;
}
pthread_mutex_lock(&cf.sessinfo.lock);
if (cf.sessinfo.nsessions > 0) {
i = poll(cf.sessinfo.pfds, cf.sessinfo.nsessions, timeout);
pthread_mutex_unlock(&cf.sessinfo.lock);
if (i < 0 && errno == EINTR)
continue;
} else {
pthread_mutex_unlock(&cf.sessinfo.lock);
usleep(timeout * 1000);
}
eptime = getdtime();
if (eptime > last_tick_time + TIMETICK) {
alarm_tick = 1;
last_tick_time = eptime;
} else {
alarm_tick = 0;
}
pthread_mutex_lock(&cf.glock);
process_rtp(&cf, eptime, alarm_tick);
if (cf.rtp_nsessions > 0) {
process_rtp_servers(&cf, eptime);
}
pthread_mutex_unlock(&cf.glock);
}
exit(0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

初始化较为简洁,主要做了如下事项:
1. 启动参数的处理
2. log日志初始化
3. 创建两个线程,一个处理超时通知(socket端口为-s传进来的),一个监听控制命令(socket端口为-n传进来的)
4. 主程序处理循环

posted on 2018-09-13 11:42  caigan  阅读(3428)  评论(0编辑  收藏  举报