http://kingwoo.blog.hexun.com/11006243_d.html Josua流程分析
http://bbs.chinaunix.net/archiver/tid-897276.html Partysip优化计划
http://blog.csdn.net/ugg/article/details/1522503
Partysip框架优化计划
http://free-bird816.iteye.com/blog/586228 OSIP协议栈使用入门
http://blog.csdn.net/rx_wen/article/details/5702687 getting start with osip
http://code.google.com/p/rxwen-blog-stuff/source/browse/trunk/protocol/basic_osip_sample/basic_osip_sample.cpp
basic_osip_sample.cpp
http://www.ietf.org/rfc/rfc3261.txt
http://www.gnu.org/software/osip/doc/html/modules.html
200300249partysip_description.rar
获取源码:
或者
wget http://download.savannah.gnu.org/releases/partysip/partysip-2.2.2.tar.gz
源码分析:
vim partysip-2.2.2/src/main.c
找到main 函数,在main (int argc, const char *const argv[]){}
行457~行465:定义了一些变量
行486~行587:ppl_initialize,猜测ppl应该是parse param line的意思,也就是解析参数行,就是运行 partysip的时候附加的参数,比如:partysip -d 6 -i 表示debug level 是6,并且交互运行。
行545~行687:配置和日志的设置。
行706:i = psp_core_init ();partysip// 核心初始化
行714: i = psp_utils_load_users ();//加载用户配置
行722:i = main_load_plugins ();//加载插件
行734: i = psp_core_start (interactive_mode);//partysip核心开始
行742:main_run ();//主线程的循环
暂时退出partysip-2.2.2/src/main.c
为了弄清partysip的运行时架构,需要找出共有多少个线程在处理事务。
partysip是基于libosip(这里选择libosip2-2.2.2),libosip中有一个osip_thread_create函数用来创建线程,于是在partysip目录下,grep osip_thread_create ./* -rn
结果显示:
./src/psp_module.c:121: module->thread = osip_thread_create (20000, func_start, arg);
./src/psp_osip.c:217: osip_thread_create (20000, (void *(*)(void *)) osip_timers_thread,
于是vim ./src/psp_module.c ./src/psp_osip.c
在./src/psp_osip.c 行217找到osip_thread_create,并且由psp_core_init函数调用,即
(*psp_osip)->timers =
217 osip_thread_create (20000, (void *(*)(void *)) osip_timers_thread,
218 (void *) (*psp_osip));
用来创建一个定时器线程处理函数。
在./src/psp_module.c 行121找到osip_thread_create,并且由module_start函数调用,由此可见,partysip在每个模块中都是用了线程来处理各自的事务。
退出vim,grep module_start ./* -rn,显示:
./src/sfp.c:347: i = module_start (pspm->module, func_start, arg);
./src/psp_resolv.c:75: i = module_start (resolv->module, func_start, arg);
./src/tlp.c:83: i = module_start (pspm->module, func_start, arg);
查看这三个文件
vim ./src/sfp.c ./src/psp_resolv.c ./src/tlp.c
在./src/sfp.c(sfp是state full processing,即全状态机处理)中行347:
342 int
343 pspm_sfp_start (pspm_sfp_t * pspm, void *(*func_start) (void *), void *arg)
344 {
345 int i;
346
347 i = module_start (pspm->module, func_start, arg);
348 if (i != 0)
349 return -1;
350 return 0;
351 }
在./src/psp_resolv.c(域名解析服务)中行75:
67 int
68 pspm_resolv_start (pspm_resolv_t * resolv, void *(*func_start) (void *),
69 void *arg)
70 {
71 int i;
72
73 if (resolv == NULL)
74 return -1;
75 i = module_start (resolv->module, func_start, arg);
76 if (i != 0)
77 return -1;
78 return 0;
79 }
在./src/tlp.c(tlp是transport layer processing,即传输层)行83:
78 int
79 pspm_tlp_start (pspm_tlp_t * pspm, void *(*func_start) (void *), void *arg)
80 {
81 int i;
82
83 i = module_start (pspm->module, func_start, arg);
84 if (i != 0)
85 return -1;
86 return 0;
87 }
如下图所示,切入点是tlp线程,即mythread_tlp
[root@localhost partysip-2.2.2]# grep mythread_tlp ./* -rn |grep '^\.'
./src/psp_core.c:665:mythread_tlp (pspm_tlp_t * tlp)
./src/psp_core.c:696: i = pspm_tlp_start (core->tlp, (void *(*)(void *)) mythread_tlp, core->tlp);
在./src/psp_core.c:665:找到mythread_tlp函数定义:
665 mythread_tlp (pspm_tlp_t * tlp)
666 {
667 int i;
668
669 i = pspm_tlp_execute (tlp, 5, 0, -1); /* infinite loop */
670 if (i != 0)
671 return NULL;
672 return NULL;
673 }
再查找pspm_tlp_execute函数的定义:
[root@localhost partysip-2.2.2]# grep pspm_tlp_execute ./* -rn |grep '^\.'
./partysip/partysip.h:140:int pspm_tlp_execute (pspm_tlp_t * pspm, int sec_max,
./src/psp_core.c:669: i = pspm_tlp_execute (tlp, 5, 0, -1); /* infinite loop */
./src/psp_core.c:730: i = pspm_tlp_execute (core->tlp, 0, 0, 1);
./src/tlp.c:90:pspm_tlp_execute (pspm_tlp_t * pspm, int sec_max, int usec_max,
在./src/tlp.c:90:找到pspm_tlp_execute函数定义:
89 int
90 pspm_tlp_execute (pspm_tlp_t * pspm, int sec_max, int usec_max,
91 int max_analysed)
92 {
定位到行170:
170 for (plug = pspm->tlp_plugins; plug != NULL; plug = plug->next)
171 {
172 if (plug->in_socket > 0)
173 {
174 if (FD_ISSET (plug->in_socket, &tlp_fdset))
175 {
176 plug->rcv_func->cb_rcv_func (1);
177 }
178 else if (plug->out_socket>0
179 && FD_ISSET (plug->out_socket, &tlp_fdset))
180 {
181 plug->rcv_func->cb_rcv_func (1);
182 }
183 else if (plug->mcast_socket>0
184 && FD_ISSET (plug->mcast_socket, &tlp_fdset))
185 {
186 plug->rcv_func->cb_rcv_func (1);
187 }
188 }
189 else
190 {
191 plug->rcv_func->cb_rcv_func (5);
192 }
193 }
194
195 if (max_analysed == 0)
196 return 0;
197 }
这个for循环将遍历所有模块,并根据tlp_fdset交由对应的模块处理函数处理。