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. 主程序处理循环
rtpproxy 配置的更多相关文章
- kamailio 云部署 配置NAT
公有云配置NAT 第一步:将内网ip广播至公网ip,编辑/etc/kamailio/kamailio.cfg文件,搜索listen,添加如下配置 # listen=udp: listen= adver ...
- Mediaproxy 与 Rtpproxy
Mediaproxy: Mediaproxy是Opensips的一个模块,它用来实现现有大多数sip客户端的自动NAT穿透.这就意味着,当使用mediaproxy模块时,不需要对NAT盒子进行任何配置 ...
- 配置android sdk 环境
1:下载adnroid sdk安装包 官方下载地址无法打开,没有vpn,使用下面这个地址下载,地址:http://www.android-studio.org/
- Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记
以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...
- react-router 组件式配置与对象式配置小区别
1. react-router 对象式配置 和 组件式配置 组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...
- 总结:Mac前端开发环境的搭建(配置)
新年新气象,在2016年的第一天,我入手了人生中第一台自己的电脑(大一时好友赠送的电脑在一次无意中烧坏了主板,此后便不断借用别人的或者网站的).macbook air,身上已无分文...接下来半年的房 ...
- Android Studio 多个编译环境配置 多渠道打包 APK输出配置
看完这篇你学到什么: 熟悉gradle的构建配置 熟悉代码构建环境的目录结构,你知道的不仅仅是只有src/main 开发.生成环境等等环境可以任意切换打包 多渠道打包 APK输出文件配置 需求 一般我 ...
- Virtual Box配置CentOS7网络(图文教程)
之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...
- [linux]阿里云主机的免登陆安全SSH配置与思考
公司服务器使用的第三方云端服务,即阿里云,而本地需要经常去登录到服务器做相应的配置工作,鉴于此,每次登录都要使用密码是比较烦躁的,本着极速思想,我们需要配置我们的免登陆. 一 理论概述 SSH介绍 S ...
随机推荐
- Go Example--打点器
package main import ( "time" "fmt" ) func main() { // 定时器 是当你想要在未来某一刻执行一次时使用的 - ...
- Go Example--通道方向
package main import "fmt" func main() { pings := make(chan string, 1) pongs := make(chan s ...
- 【HAOI2012】外星人
又犯sb错了QAQ 原题: 艾莉欧在她的被子上发现了一个数字 ,她觉得只要找出最小的x使得,.根据这个 她就能找到曾经绑架她的外星人的线索了.当然,她是不会去算,请你帮助她算出最小的x. test&l ...
- mysql不存在插入否则更新
1.如果存在就更新,没有就插入,相当于三目运算 CREATE UNIQUE INDEX xxx ON t_msg_user_view(USER_ID); INSERT INTO xxx(user_id ...
- 修改VS2017模板文件,添加文件头部自定义注释
找到Class.cs文件 找到VS2017安装目录下面的Class.cs文件,一般在C盘或者D盘 模块文件位置: 接口模版:C:\Program Files (x86)\Microsoft Visua ...
- 使用dynamic和MEF实现轻量级的AOP组件 ---- 系列文章
.NET 4 实践 - 使用dynamic 和MEF实现轻量级的AOP组件(1) .NET 4 实践 - 使用dynamic和MEF实现轻量级的AOP组件 (2) .NET 4 实践 - 使用 ...
- mysql 不允许分组的问题
异常信息:this is incompatible with sql_mode=only_full_group_by 解决办法: 找到 my.cnf find / -name my.cnf 然后在 ...
- getModifiers 方法解释。
modifier: 字面意思修饰符. getModifiers 得到的就是 前面的 的修饰符 ,这个方法 字段和方法 都有.这个方法的值是 修饰符 相加的到的值. 例子: public class ...
- mac home目录创建文件夹,修改权限
mac 是基于unix, 自带就有home目录,但是为空.home目录的默认所属用户是root wheel,mac默认的root账号所属用户是root admin,所以root也无法在home目录下创 ...
- C#实现Google S2算法
S2其实是来自几何数学中的一个数学符号 S²,它表示的是单位球.S2 这个库其实是被设计用来解决球面上各种几何问题的.值得提的一点是,除去 golang 官方 repo 里面的 geo/s2 完成度目 ...