基于bfin-uclinux的asterik siptls
来源:互联网 发布:卖家开通淘宝直播条件 编辑:程序博客网 时间:2024/06/07 09:35
博客N久没上了,平时太懒了。明天就放假了,事都忙完了,时间不能浪费,博客空空如也,现在有空就写写之前asterisk的siptls问题,说不定对看到这篇博文的你有用,对于这方面的资料实现太少,百度没,google没,当然碰到这些问题那个郁闷啊,不过还好,问题都解决了。下面说说这一路的过程
刚开始接到上头说让我看看配置asterisk的siptls,稍微了解了下TLS后上voip-info.org上查看如何配置,按上面步骤一步一步下来,没成功,证书生成问题,在网上搜索了下配置asterisk的TLS证书,重新生成证书,在PC上可以用。SIP话机TLS连接上,通话正常,trunk用TLS也正常。以为就这样简简单单结束了,谁知放在板卡上,TLS无法用了。板卡系统是uclinux,交叉编译工具用的是bfin-linux-uclibc。想想没问题啊。PC上都好好的。CLI上输出警告FILE * open failed!,有警告说明有问题,这就好办啦,看了下源码,handle_tcptls_connection函数中tcptls_session->f创建失败为空。什么原因导致?加几个打印信息,条件编译DO_SSL中的都没走,宏DO_SSL没定义,有个头文件有定义DO_SSL,但有条件,当时根本不懂这那些条件有什么用,自己直接宏定义,仍提示警告。仔细看源码发现是创建tcptls_session->f有两种方法,funopen和fopencookie,分别是BSD接口和linux的接口,豪无疑问是用linux接口。fopencookie在宏定义HAVE_FOPENCOOKIE下,看相关头文件中定义的#undef HAVE_FOPENCOOKIE,先不管3721先定义宏HAVE_FOPENCOOKIE,编译问题出来了,未定义fopencookie函数。libc.a中根本没有fopencookie函数。google后才晓得fopencookie是glibc中的函数。blackfin的工具链中的uclibc库默认是不支持fopencookie函数的(之前的DO_SSL没定义就是因为#undef HAVE_FOPENCOOKIE造成),因此得自己编译uclibc替换工具链中的相应库了。编译uclibc库中间遇到了一些波折不过最终也编译过了。函数支持了,以为这下总可以用了吧,不过还是不行,TLS分机能注册但通话有问题,中间又捣鼓了好久,确认不是新的uclibc问题,openssl和证书问题,最后就从代码着手,每次在建立通话时,ssl_read打印的信息显示ssl read size 1 returns 0 <>,建立的线程就被cleanup了。拿实际数据来说。
chan_sip.c
static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
{
//...以上省略
if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
while (cl > 0) {
size_t bytes_read;
ast_mutex_lock(&tcptls_session->lock);
if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
ast_mutex_unlock(&tcptls_session->lock);
goto cleanup;
}
buf[bytes_read] = '/0';
ast_mutex_unlock(&tcptls_session->lock);
if (me->stop)
goto cleanup;
cl -= strlen(buf);
ast_str_append(&req.data, 0, "%s", buf);
req.len = req.data->used;
}
}
//...以下省略
}
tcptls.c
static HOOK_T ssl_read(void *cookie, char *buf, LEN_T len)
{
int i = SSL_read(cookie, buf, len-1);
#if 0
if (i >= 0)
buf[i] = '/0';
ast_verb(0, "ssl read size %d returns %d <%s>/n", (int)len, i, buf);
#endif
return i;
}
假如content-length为395,循环每一次fread(buf, 1, 395, tcptls_session->f),由于ssl_read中只读取len-1的长度,因此只返回394的数据,因此进入循环第二次
fread(buf, 1, 395-394, tcptls_session->f),ssl_read,由于len-1,问题就出现了,我们想要读取这最后的1字节,但并未读取。
因此需要修改ssl_read,将其改为i = SSL_read(cookie, buf, len<2?len,len-1),避免最后一字节未得到。改完后,TLS功能完全可用了。下面总结下blackfin平台下asterisk实现TLS功能的方法。
一、编译uclibc
我的交叉编译工具用的是bfin-linux-uclibc。
将uClibc包中extra/Configs/Config.defaultfdpic.default移到uClibc目录下的.config
make menuconfig
String and Stdio Support --->
[*] Support fmemopen(), open_memstream(), and fopencookie() (glibc-compat)
编译完后,make install到bfin-linux-uclibc中的相应目录下。
二、修改asterisk的tcptls.c
static HOOK_T ssl_read(void *cookie, char *buf, LEN_T len)
{
int i = SSL_read(cookie, buf, len<2?len:len-1);
#if 0
if (i >= 0)
buf[i] = '/0';
ast_verb(0, "ssl read size %d returns %d <%s>/n", (int)len, i, buf);
#endif
return i;
}
三、重编整个工程,包括uclinux,asterisk。
四、用openssl生成证书,具体方法voip-info.org上有。
五、分机配置asterisk
tlsenable=yes
tlsbindaddr=0.0.0.0:5061
tlscertfile=/etc/asterisk/certs/asterisk.pem
tlsdontverifyserver=yes
tlscipher=DES-CBC3-SHA
[100]
transport=tls
注册台分机试了下可用,而tls trunk配置后也可呼入正常,一切OK。
注册TLS trunk
register = tls://user:pass@domain
PS:其实ssl_read函数根本没必要采取len-1的方式,因为读取大小完全可以在外部调用时控制。ssl_read的问题在电脑上没有影响,电脑系统是ubtun10.04。我猜测可能是uclibc与glibc在对fread处理有些不同,后面好好看下uclibc和glibc源码中fread的实现方式。
以上几个步骤看上去简简单单,但其中的曲折只有自己能体会,从中也学到了许多东西,年关将至,今年的问题没遗留到明年,心里的疙瘩也没了,准备好好回家过年喽。
- 基于bfin-uclinux的asterik siptls
- 初试bfin-uclinux-08r1.5-rc3的SMP支持
- 在gcc下模拟bfin-uclinux的内存管理(1):基本思想
- OpenFire的Asterik-IM集成
- OpenFire的Asterik-IM集成
- 在cygwin下进行bfin-uclinux开发
- 在cygwin下使用bfin-uclinux-gdb
- 在gcc下模拟bfin-uclinux的内存管理(2):所需要的文件及其更改
- 基于NIOS平台的嵌入式uclinux安装uclinux
- 基于uClinux的Web Server的实现
- 基于uclinux的sopc应用程序设计
- 基于uClinux的NPTL线程库移植
- 基于uClinux的NPTL线程库移植
- 基于BF531 DSP的uClinux 移植指南
- 基于uClinux的NPTL线程库移植
- 基于arm+uClinux的嵌入式系统的开发
- 基于arm+uClinux的嵌入式系统的开发
- 基于arm+uClinux的嵌入式系统的开发
- JavaMail常见问题解答
- 为什么中国的XBRL数据都不能免费下载?
- 百度如何优化
- servlet 2.5的新特性
- 我们是怎么老去的
- 基于bfin-uclinux的asterik siptls
- mail output
- Socket开发流程
- new和newInstance的区别方法
- 总结------------创建多域名(website)多网店(store)magento网站
- MAVEN 手册
- jQuery手册
- 开发思路!
- ANT 手册