最近遇到一个问题,SIP会话BYE的时候发送到了错误的IP和端口,抓包发现from域的uri和contact域的uri是不一样的,一个是内网地址,一个是外网地址。exosip在调用 eXosip_call_terminate 的时候使用了默认的from域字段,导致发送到了内网的错误地址。现在来看看EXOSIP的具体实现,并考虑怎么修改。
首先看看发送过程,bye消息属于NICT消息,由上一节可以知道调用的是osip_nict_execute ,第一个状态NICT_PRE_TRYING调用接口nict_snd_request,发送地址为nict->nict_context->destination。
void
nict_snd_request (osip_transaction_t * nict, osip_event_t * evt)
{
int i;
osip_t *osip = (osip_t *) nict->config;
/* Here we have ict->orig_request == NULL */
nict->orig_request = evt->sip;
i = osip->cb_send_message (nict, evt->sip, nict->nict_context->destination, nict->nict_context->port, nict->out_socket);
...
}
int
osip_nict_set_destination (osip_nict_t * nict, char *destination, int port)
{
if (nict == NULL)
return OSIP_BADPARAMETER;
if (nict->destination != NULL)
osip_free (nict->destination);
nict->destination = destination;
nict->port = port;
return OSIP_SUCCESS;
}
而设置地址的接口为osip_nict_set_destination,通过__osip_nict_init进行调用。可以看出如果有route字段,sip会优先使用route字段的uri,然后是"x-obr" "x-obp" "maddr",最后才是request->req_uri。
int
__osip_nict_init (osip_nict_t ** nict, osip_t * osip, osip_message_t * request)
{
osip_route_t *route;
int i;
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating NICT context\n"));
*nict = (osip_nict_t *) osip_malloc (sizeof (osip_nict_t));
if (*nict == NULL)
return OSIP_NOMEM;
memset (*nict, 0, sizeof (osip_nict_t));
/* for REQUEST retransmissions */
/* for PROXY, the destination MUST be set by the application layer,
this one may not be correct. */
osip_message_get_route (request, 0, &route);
if (route != NULL && route->url != NULL) {
osip_uri_param_t *lr_param;
osip_uri_uparam_get_byname (route->url, "lr", &lr_param);
if