加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

1.rtpproxy 初始化代码分析

(2015-03-02 16:30:30)
标签:

杂谈

分类: 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 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}

        

入口:main.c

  1. int main(int argc, char **argv)
  2. {
  3. int i, len, timeout, controlfd, alarm_tick;
  4. double sptime, eptime, last_tick_time;
  5. unsigned long delay;
  6. struct cfg cf;
  7. char buf[256];


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

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

  12. //初始化媒体流端口,-m 50002 -M 50020端口范围用于媒体流中转,并且成对使用
  13.  //此函数将指定的端口范围保存在cf.stable.port_table[65536]数组中,保存端口对中的一个. 并将对port_table[]下标查找的最大值保存在cf.port_table_idx                                      
  14.     init_port_table(&cf);               
  15.  
  16. //创建与opensips命令交互的socket,并进行端口绑定,绑定的端口为 -s 传进来的参数
  17. controlfd = init_controlfd(&cf);
  18.  
  19. //日志初始化,利用的是系统日志,在启动参数中配置
  20. glog = cf.stable.glog = rtpp_log_open(&cf.stable, "rtpproxy", NULL, LF_REOPEN);
  21.  
  22. //创建一个超时通知线程rtpp_notify_queue_run,绑定的socket端口为 -n传进来的参数
  23. if (cf.timeout_socket != NULL) {    
  24.     cf.timeout_handler = rtpp_notify_init(glog, cf.timeout_socket);
  25. }

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

  31. //设置此进程的user ID和group ID,对应配置参数为-u uname:gname
  32. if (cf.stable.run_uname != NULL || cf.stable.run_gname != NULL)
  33.     drop_privileges(&cf);
  34. cf.stable.controlfd = controlfd;
  35. cf.sessinfo.sessions[0] = NULL;
  36. cf.sessinfo.nsessions = 0;
  37. cf.rtp_nsessions = 0;
  38. //创建rtpp_cmd_queue_run线程监听和处理controlfd的数据
  39. rtpp_command_async_init(&cf);         
  40. sptime = 0;
  41. eptime = getdtime();
  42. last_tick_time = 0;
  43. timeout = 1000 / POLL_RATE;
  44. for (;;) {                               
  45. delay = (eptime - sptime) * 1000000.0;
  46. if (delay <= 0) {
  47. sptime = eptime;
  48. last_tick_time = 0;
  49. } else if (delay < (1000000 / POLL_RATE)) {
  50. sptime += 1.0 / (double)POLL_RATE;
  51. usleep((1000000 / POLL_RATE) - delay);
  52. } else {
  53. sptime = eptime;
  54. }
  55. pthread_mutex_lock(&cf.sessinfo.lock);
  56. if (cf.sessinfo.nsessions > 0) {
  57. i = poll(cf.sessinfo.pfds, cf.sessinfo.nsessions, timeout);
  58. pthread_mutex_unlock(&cf.sessinfo.lock);
  59. if (i < 0 && errno == EINTR)
  60. continue;
  61. } else {
  62. pthread_mutex_unlock(&cf.sessinfo.lock);
  63. usleep(timeout * 1000);
  64. }
  65. eptime = getdtime();
  66. if (eptime > last_tick_time + TIMETICK) {
  67. alarm_tick = 1;
  68. last_tick_time = eptime;
  69. } else {
  70. alarm_tick = 0;
  71. }
  72. pthread_mutex_lock(&cf.glock);
  73. process_rtp(&cf, eptime, alarm_tick);
  74. if (cf.rtp_nsessions > 0) {
  75. process_rtp_servers(&cf, eptime);
  76. }
  77. pthread_mutex_unlock(&cf.glock);
  78. }
  79. exit(0);
  80. }
初始化较为简洁,主要做了如下事项;
1.  启动参数的处理
2.  log日志初始化
3.  创建两个线程,一个处理超时通知(socket端口为-s传进来的),一个监听控制命令(socket端口为-n传进来的)
4.  主程序处理循环




0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有