一:官网主页
http://savannah.nongnu.org/projects/exosip/
二:源代码下载
http://www.antisip.com/download/
osip和exosip2源代码目录:
http://www.antisip.com/download/exosip2/
目录:
Parent Directory -
libeXosip2-3.5.0.tar.gz13-Sep-201116:12476K
libeXosip2-4.0.0.tar.gz11-Apr-201210:16499K
libeXosip2-4.1.0.tar.gz06-Jan-201417:36519K
libosip2-3.5.0.tar.gz13-Sep-2011 16:12584K
libosip2-4.0.0.tar.gz11-Apr-2012 10:16606K
libosip2-4.1.0.tar.gz06-Jan-2014 16:57621K
三:使用版本
osip和exosip的对应版本代码的下载:
libeXosip2-4.1.0.tar.gz
libosip2-4.1.0.tar.gz
第一步:我想知道osip_message_build_answer到底是如何负责创建默认的sip数据包
第二步:eXosip_call_t 和 eXosip_dialog_t的区别
callid dialogid之间的区别是什么
第三步:osip内部是什么时候调用event_free函数清楚内存分配(尽管已经手动调用),但是调用的时间完全不听使唤
第四步:osip_list_get到底隐藏什么样的秘密
osip_list_add到底又是什么样的添加
第五步:eXosip_event_add到底代表的是什么
其中关键的代码是eXosip_event_add调用的函数osip_fifo_add这个函数具体不明
第六步:到底使用osip_message_get_contact到底操作的时候影响的是原来接收到的数据包,还是另外一个内存块的东西
第七步:osip_new_outgoing_your_instance
第八步:EXOSIP_REGISTRATION_NEW表示的是收到新的注册receivednew registration到底是怎么一回事,为什么这个事件是用在客户端,而不是服务器接受到一个注册请求,匪夷所思
第九步:EXOSIP_REGISTRATION_TERMINATED更是在什么情况下,服务器发起,给我的工作添加一个神秘的炸弹
客户端使用REGISTER方式来将TO头域中所列的地址登记在一个SIP服务器上
详细分析:这是否意味着应该将To头域中的信息填充到SIP服务器中的地址映射链表中,方便进行以后的地址管理,也就是将地址映射添加到定位服务器上
TRANSACTION事务:SIP的事务发生在客户端到服务器之间的一系列请求响应,包括从客户端的第一个请求到服务器的最后一个响应所有消息。在同样事务将有Cseq号码来鉴别。
URL 根据RFC1738这是一个考虑的问题
用户的SIP地址可以从out-of-band中获取,可以从存在的媒体代理获得,可以包含在邮件的消息头,可以记录在以前的交换INVITE中,
任何人都希望获取Request-URI的真实身份,但是没有免费的午餐,
SIP的寻址
被SIP称为对象的事主机上的用户,通过SIP的URL鉴别,SIP URL
例如:user@host user部分是一个用户名或者电话号码
host部分是一个域名或者IP地址
REGISTER请求中的contact头域表明用户的位置,为什么需要表明用户的位置,难道是想保存到位置服务器中去
1.osip_malloc分配一个内存块,osip_ict_t 指向这块内存地址
2获取invite报文的有效传输协议
osip_message_get_via (invite, 0, &via)
via_get_protocol (via)
if (osip_strcasecmp (proto, "TCP") != 0
&& osip_strcasecmp (proto, "TLS") != 0
&& osip_strcasecmp (proto, "SCTP") != 0)
3如果有更安全的传输方式,需要修改这个函数
4.查询是否是一个代理的服务器。对报文进行转发
osip_message_get_route (invite, 0,&route);
1.分析:函数首先获取认证字段的长度,然后动态内存分配,将osip_www_authenticate_t类型的数据复制成为一个字符串,目标地址是dest,但是导致的内存泄露也是一大隐患。
2.分析:函数首先将认证信息添加到数据报文中,然后将认证信息添加到osip_list链表,这将会大大方便函数的释放。
源代码1:
int
osip_www_authenticate_to_str (constosip_www_authenticate_t * wwwa, char **dest)
{
size_t len;
char *tmp;
*dest = NULL;
if((wwwa == NULL) || (wwwa->auth_type == NULL))
return OSIP_BADPARAMETER;
len= strlen (wwwa->auth_type) + 1;
if(wwwa->realm != NULL)
len = len + strlen (wwwa->realm) + 7;
if(wwwa->nonce != NULL)
len = len + strlen (wwwa->nonce) + 8;
len= len + 2;
if(wwwa->domain != NULL)
len = len + strlen (wwwa->domain) + 9;
if(wwwa->opaque != NULL)
len = len + strlen (wwwa->opaque) + 9;
if(wwwa->stale != NULL)
len = len + strlen (wwwa->stale) + 8;
if(wwwa->algorithm != NULL)
len = len + strlen (wwwa->algorithm) + 12;
if(wwwa->qop_options != NULL)
len = len + strlen (wwwa->qop_options) + 6;
tmp= (char *) osip_malloc (len);
if(tmp == NULL)
return OSIP_NOMEM;
*dest = tmp;
tmp= osip_str_append (tmp, wwwa->auth_type);
if(wwwa->realm != NULL)
{
tmp = osip_strn_append (tmp, " realm=", 7);
tmp = osip_str_append (tmp, wwwa->realm);
}
if(wwwa->domain != NULL)
{
tmp = osip_strn_append (tmp, ", domain=", 9);
tmp = osip_str_append (tmp, wwwa->domain);
}
if(wwwa->nonce != NULL)
{
tmp = osip_strn_append (tmp, ", nonce=", 8);
tmp = osip_str_append (tmp, wwwa->nonce);
}
if(wwwa->opaque != NULL)
{
tmp = osip_strn_append (tmp, ", opaque=", 9);
tmp = osip_str_append (tmp, wwwa->opaque);
}
if(wwwa->stale != NULL)
{
tmp = osip_strn_append (tmp, ", stale=", 8);
tmp = osip_str_append (tmp, wwwa->stale);
}
if(wwwa->algorithm != NULL)
{
tmp = osip_strn_append (tmp, ", algorithm=", 12);
tmp = osip_str_append (tmp, wwwa->algorithm);
}
if(wwwa->qop_options != NULL)
{
tmp = osip_strn_append (tmp, ", qop=", 6);
tmp = osip_str_append (tmp, wwwa->qop_options);
}
if(wwwa->realm == NULL)
{
/* remove comma */
len = strlen (wwwa->auth_type);
if ((*dest)[len] == ',')
(*dest)[len] = ' ';
}
return OSIP_SUCCESS;
}
源代码2:
int
osip_message_set_www_authenticate(osip_message_t * sip, const char *hvalue)
{
osip_www_authenticate_t *www_authenticate;
inti;
if(hvalue == NULL || hvalue[0] == '\0')
return OSIP_SUCCESS;
if(sip == NULL)
return OSIP_BADPARAMETER;
i =osip_www_authenticate_init (&www_authenticate);
if(i != 0)
return i;
i =osip_www_authenticate_parse (www_authenticate, hvalue);
if(i != 0)
{
osip_www_authenticate_free (www_authenticate);
return i;
}
sip->message_property = 2;
osip_list_add (&sip->www_authenticates, www_authenticate, -1);
returnOSIP_SUCCESS;
}
init函数会创建一个动态内存块,然后填充其中的字段(其实,不是填充,而是指向,因为里面的成员都是char*指针的居多,只是调整指向),例如
osip_www_authorization_t 结构体
存在如下的属性:
auth_type username nonce realm ,创建一个内存块,存储指向这些属性的内存指针
然后在添加到数据包中,这个时候会调用osip_list_add链表中的添加函数,等待被事务状态机释放内存。
osip_authorization_t *auth_header;
osip_authorization_init(&auth_header); //此句作用不明(现在已经很明白了)
提出一个问题:事务状态机的启动的时机又是什么时候?内存在哪里得到释放
第一步:调用osip_message_get_XXX,获取指向消息内容的指针
第二步:调用osip_XXX_clone,复制头域的结构体
第三步:对复制的内存对象进行操作
第四步:释放动态内存
以下是认证的:
//获取authorization头域信息
osip_authorization_t* authorization=NULL;
osip_message_get_authorization(je->request,0,&authorization);
//拷贝复制使用,记住动态内存释放
osip_authorization_t*authorizationofclone=NULL;
osip_authorization_clone(authorization,&authorizationofclone);
osip_dequote(authorizationofclone->username);
osip_dequote(authorizationofclone->uri);
osip_dequote(authorizationofclone->nonce);
osip_dequote(authorizationofclone->realm);
/
//计算MD5(username,uri,realm,nonce
/
//最终释放动态内存
osip_authorization_free(authorizationofclone);
在惊鸿一瞥中,发现osip_event.c文件测试解析osip报文的速度
非常值得我们参考,尤其是大数据解析的时候:
osip_event_t *
osip {
int kk;
int pstime1, pstime;
struct timespec tv1;
clock_get_time (CLOCK_REALTIME, &tv1);
pstime = ((tv1.tv_sec * 1000) + (tv1.tv_nsec / 1000000));
for (kk = 0; kk < 10000; kk++)
{
i = osip_message_init (&(se->sip));
if (osip_message_parse (se->sip, buf, length) == -1)
{
fprintf (stdout, "osip_message_parse retrun -1\n");
osip_message_free (se->sip);
} else
{ /* msg isparsed */
osip_message_free (se->sip);
}
}
clock_get_time (CLOCK_REALTIME, &tv1);
pstime1 = ((tv1.tv_sec * 1000) + (tv1.tv_nsec / 1000000));
fprintf (stdout, "CPU clock ticks for 10000 messages - T1: %i - T2:%i\n",
pstime1, pstime);
fprintf (stdout, "CPU time for 10000 messages - %d\n",(pstime1 - pstime));
}
osip_free (se);
return NULL;