以注册报文分析outbound域名地址解析流程
一、设置域名到注册客户端所属的事务客户端对象中
//注册客户端对象设置outbound域名
RvSipRegClientSetOutboundHostName
//事件客户端对象设置outbound域名
SipTranscClientSetOutboundHostName(&pRegClient->transcClient,strOutboundHost, outboundPort);
//设置事件客户端对象的outboundAddr信息
SipTransportSetObjectOutboundHost(pTranscClient->pMgr->hTransportMgr,
&pTranscClient->outboundAddr, strOutboundHost, outboundPort,
pTranscClient->pMgr->hGeneralMemPool, pTranscClient->hPage);
//将用户输入的域名存储到pTranscClient->outboundAddr的内存池中
RPOOL_AppendFromExternal(hObjPool, hObjPage, strOutboundHost,
(RvInt)strlen(strOutboundHost)+1, RV_FALSE, &offset, NULL);
pOutboundAddr->rpoolHostName.offset = offset;
pOutboundAddr->rpoolHostName.hPage = hObjPage;
pOutboundAddr->rpoolHostName.hPool = hObjPool;
//构造空的地址对象
RvAddressConstruct(RV_ADDRESS_TYPE_IPV4,&pOutboundAddr->ipAddress.addr)
RvAddressSetIpPort(&pOutboundAddr->ipAddress.addr,outboundPort);
//标记使用域名
pOutboundAddr->bUseHostName = RV_TRUE;
二、发送注册报文(省去无关的流程,只标记与outband关系紧密的流程)
1、发送注册请求
RvSipRegClientRegister
//激活注册
SipTranscClientActivate(&pRegClient->transcClient, SIP_TRANSACTION_METHOD_REGISTER,
NULL);
//构造事务对象
TranscClientCreateNewTransaction(pTranscClient)
//构造事务对象
SipTransactionCreate(pTranscClient->pMgr->hTranscMgr , &transcKey,
(void*)pTranscClient, SIP_TRANSACTION_OWNER_TRANSC_CLIENT,
pTranscClient->tripleLock, &(pTranscClient->hActiveTransc));
//事务创建
TransactionCreate(hTranscMgr,pKey,pOwner,eOwnerType,tripleLock,
RV_TRUE,phTransaction);
//事务创建
TransactionMgrCreateTransaction
//初始化新分配的事务对象
TransactionInitialize
//创建传送对象
SipTransmitterMgrCreateTransmitter
TransmitterMgrCreateTransmitter
//初始化新分配的传送对象
TransmitterInitialize
//创建一个空的DNSlist对象
//pTrx->hDnsList
SipTransportDNSListConstruct
//创建一个解析器对象
//其中pRslv->bIsAppRslv = false
//pRslv->hOwner = pTrx
SipResolverMgrCreateResolver(
pTrx->pTrxMgr->hRslvMgr,pTrx,
pTrx->pTripleLock, &pTrx->hRslv);
//将之前设置到事务客户端对象的outbound信息存储到
//pTrx->outboundAddr传送对象中
SipTransactionSetOutboundAddress(pTranscClient->hActiveTransc,
&pTranscClient->outboundAddr);
//注册客户端对象发送请求
TranscClientSendRequest
SipTransactionRequest(pTranscClient->hActiveTransc, eMethod,
pTranscClient->hRequestUri);
TransactionControlSendRequest(pTransc, hRequestUri,RV_TRUE);
//生成请求,并发送,这里bResolveAddr为true
GenerateAndSendRequest(pTransc,hRequestUri,
pTransc->hOutboundMsg,bResolveAddr);
TransactionTransportSendMsg(pTransc, bResolveAddress);
//传送对象发送消息
SipTransmitterSendMessage(pTransc->hTrx,
pTransc->hOutboundMsg, pTransc->msgType);
TransmitterControlStartMessageSending(pTrx);
//进行目标地址查找,下面单独分析
TransmitterDestDiscovery(pTrx,RV_TRUE)
------------------------------------------------------------------------------------------------------------------------------
TransmitterDestDiscovery
if (TRANSMITTER_RESOLUTION_STATE_UNDEFINED == pTrx->eResolutionState)
//传送对象状态切换
TransmitterChangeState(pTrx,RVSIP_TRANSMITTER_STATE_RESOLVING_ADDR,
RVSIP_TRANSMITTER_REASON_UNDEFINED,pTrx->hMsgToSend,NULL);
//当状态为RVSIP_TRANSMITTER_STATE_RESOLVING_ADDR不进行实际状态变更
//在此函数中仅仅通知上层
//通知传送对象的拥有者状态切换,这里会调用事务对象的回调函数
//TransactionTransportTrxStateChangeEv,该回调中没有
//RVSIP_TRANSMITTER_STATE_RESOLVING_ADDR状态的处理。
TransmitterCallbackStateChangeEv(pTrx,eNewState, eReason,hMsg,pExtraInfo);
//进行解析成功后的地址尝试,第一次不会成功,因为还没有开始解析
rv = DestTryPreDnsList(pTrx)
//尝试从解析成功地址列表中获取地址,执行失败
rv = RvSipTransportDNSListPopIPElement(pTrxMgr->hTransportMgr,
pTrx->hDnsList,&ipElement);
//返回没有找到
return RV_ERROR_NOT_FOUND;
//标记1
while (RV_OK == rv)
switch (pTrx->eResolutionState)
case TRANSMITTER_RESOLUTION_STATE_UNDEFINED:
//进行解析处理
rv = DestHandleResolutionStateUndefined(pTrx);
//传送对象的目标地址复位
TransmitterDestReset(pTrx);
//变迁传送对象状态为
//pTrx->eResolutionState =
//TRANSMITTER_RESOLUTION_STATE_RESOLUTION_STARTED
DestResolutionStateChange(pTrx,
TRANSMITTER_RESOLUTION_STATE_RESOLUTION_STARTED);
//查找下一跳的地址信息
DestIdentifyNextHopParams(pTrx);
DestGetRequestAddressFromMsg(pTrx, pTrx->hMsgToSend,
pTrx->bSendToFirstRoute, &pTrx->msgParams.strHostName,
&pTrx->msgParams.hostNameOffset, &pTrx->msgParams.port,
&pTrx->msgParams.transportType, &pTrx->msgParams.bIsSecure);
//假设当前没有route头域,则hRouteHop为空
hRouteHop = RvSipMsgGetHeaderByType(hMsgObject,
RVSIP_HEADERTYPE_ROUTE_HOP,RVSIP_FIRST_HEADER,&listElem);
// hRouteHop为空,不执行
while(hRouteHop != NULL)
……
//标记消息的目标地址使用请求URL
pTrx->hNextMessageHop = RvSipMsgGetRequestUri(hMsgObject);
bIsReqUri = RV_TRUE;
pTrx->eMsgAddrUsedForSending = TRANSMITTER_MSG_REQ_URI;
//尝试从传送对象中获取outbound信息,在创建事务对象时,
//已经正确初始化了传送对象的outbound信息,这里可以正
//确提取。
TryToUseOutboundAddress(pTrx, pHostName, pHostNameOffset,
pPort, pTransportType, &eCompType, pbIsSecure,
&bOutboundAddressFound);
//提取outbound地址信息
CheckForOutboundAddress(pTrx,pHostName,
pHostNameOffset,pPort,peTransportType,peCompType,
&rpoolSigcompId,pbAddrFound);
// pTrx->eResolutionState =
// TRANSMITTER_RESOLUTION_STATE_URI_FOUND
DestResolutionStateChange(pTrx,
TRANSMITTER_RESOLUTION_STATE_URI_FOUND);
//标记消息的目标地址使用outbound地址
pTrx->eMsgAddrUsedForSending =
TRANSMITTER_MSG_OUTBOUND_ADDR;
//返回OK,触发“标记1”处的循环
2、需要解析的outbound地址信息已经获取,并存储到pTrx->msgParams.strHostName、pTrx->msgParams.hostNameOffset、pTrx->msgParams.port、pTrx->msgParams.transportType、pTrx->msgParams.bIsSecure中,并且pTrx->eMsgAddrUsedForSending标记为
TRANSMITTER_MSG_OUTBOUND_ADDR。进入“标记1”循环处代码继续执行。
while (RV_OK == rv)
switch (pTrx->eResolutionState)
case TRANSMITTER_RESOLUTION_STATE_URI_FOUND:
//处理域名URI
rv = HandleUriFoundState(pTrx);
//查找域名地址类型
return DestProtocolInitialFind(pTrx)
DestProtocolGetExplicitlySpecified(pTrx)
if (pTrx->msgParams.transportType != RVSIP_TRANSPORT_UNDEFINED)
//将传送对象的传送类型设置为outbound信息类型
pTrx->destAddr.eTransport = pTrx->msgParams.transportType;
// pTrx->eResolutionState =
// TRANSMITTER_RESOLUTION_STATE_TRANSPORT_FOUND
DestResolutionStateChange(pTrx,
TRANSMITTER_RESOLUTION_STATE_TRANSPORT_FOUND);
//返回OK,触发“标记1”处的循环
return RV_OK
3、需要解析的outbound传输类型已经获取,进入“标记1”循环处代码继续执行
while (RV_OK == rv)
switch (pTrx->eResolutionState)
case TRANSMITTER_RESOLUTION_STATE_TRANSPORT_FOUND:
//进行域名解析
rv = DestHostPortDiscovery(pTrx);
//将outbound端口设置到pTrx->destAddr.addr中
RvAddressSetIpPort(&pTrx->destAddr.addr,DestChoosePort(pTrx));
//调用解析器进行解析,进行设置解析器应答的回调函数
// DestDataReportedEvHandler,当解析器异常解析完成后,触发该回调函数
//返回解析结果。
SipResolverResolve(pTrx->hRslv,RVSIP_RESOLVER_MODE_FIND_IP_BY_HOST,
pTrx->msgParams.strHostName,RVSIP_RESOLVER_SCHEME_UNDEFINED,
pTrx->msgParams.bIsSecure,RvAddressGetIpPort(&pTrx->destAddr.addr),
pTrx->destAddr.eTransport, pTrx->hDnsList, DestDataReportedEvHandler);
pRslv->pfnReport = DestDataReportedEvHandler;
pRslv->strQueryString = pTrx->msgParams.strHostName; //outbound的域名
pRslv->eScheme = RVSIP_RESOLVER_SCHEME_UNDEFINED;
pRslv->eState = RESOLVER_STATE_UNDEFINED;
pRslv->knownPort = RvAddressGetIpPort(&pTrx->destAddr.addr);
pRslv->knownTransport = pTrx->destAddr.eTransport;
pRslv->hDns = pTrx->hDnsList;
pRslv->eMode = RVSIP_RESOLVER_MODE_FIND_IP_BY_HOST;
pRslv->bIsSecure = pTrx->msgParams.bIsSecure;
switch(eMode)
case RVSIP_RESOLVER_MODE_FIND_IP_BY_HOST:
//进行域名解析
rv = ResolverDnsResolveIpByHost(pRslv);
switch (pRslv->eState)
case RESOLVER_STATE_UNDEFINED:
eNextQuery = RV_DNS_HOST_IPV4_TYPE;
eNextState = RESOLVER_STATE_TRY_A;
//发送解析请求,不详细分析了
AllocateAndSendQuery(pRslv,eNextQuery,pRslv->strQueryString,
RV_FALSE);
// pRslv->eState = RESOLVER_STATE_TRY_A;
ResolverChangeState(pRslv,eNextState);
return RV_ERROR_TRY_AGAIN;
//直接返回,等待DNS解析成功后,调用DestDataReportedEvHandler
switch (rv)
case RV_ERROR_TRY_AGAIN:
return RV_OK;
4、DNS解析成功后,调用DestDataReportedEvHandler
DestDataReportedEvHandler
TransmitterDestDiscovery(pTrx,RV_FALSE)
//进行解析成功后的地址尝试
rv = DestTryPreDnsList(pTrx);
if (TRANSMITTER_RESOLUTION_STATE_RESOLVED != pTrx->eResolutionState)
//从解析成功后的地址列表中获取IP地址
RvSipTransportDNSListPopIPElement(pTrxMgr->hTransportMgr,
pTrx->hDnsList,&ipElement);
//将解析成功后的地址设置到pTrx->destAddr中
pTrx->destAddr.eTransport = ipElement.protocol;
SipTransportIPElementToSipTransportAddress(&pTrx->destAddr,&ipElement);
// pTrx->eResolutionState =
// TRANSMITTER_RESOLUTION_STATE_RESOLVED
DestResolutionStateChange(pTrx,
TRANSMITTER_RESOLUTION_STATE_RESOLVED);
while (RV_OK == rv)
switch (pTrx->eResolutionState)
case TRANSMITTER_RESOLUTION_STATE_RESOLVED:
//目标地址已经成功解析
DestStateResolved(pTrx)
//事务对象状态变迁
TransmitterMoveToStateFinalDestResolved (pTrx,
RVSIP_TRANSMITTER_REASON_UNDEFINED, pTrx->hMsgToSend, NULL);
//根据目标地址类型,更新本地地址
TransmitterSetInUseLocalAddrByDestAddr(pTrx)
//修正VIA头域
TransmitterUpdateViaByFinalLocalAddress(pTrx,(pTrx->bFixVia||
pTrx->bTrxCreatedVia))
//传送对象状态变迁
TransmitterChangeState(pTrx,RVSIP_TRANSMITTER_STATE_FINAL_DEST_RESOLVED, RVSIP_TRANSMITTER_REASON_UNDEFINED,
hMsg,NULL);
pTrx->eState=
RVSIP_TRANSMITTER_STATE_FINAL_DEST_RESOLVED
//一层层对象向上通知,最终触发用户层设置的
// pfnFinalDestResolvedEvHandler回调,告知解析完成。
TransmitterCallbackStateChangeEv(pTrx,eNewState,
eReason,hMsg,pExtraInfo);
//传送层控制请求发出
TransmitterControlSend(pTrx,bReachedFromApp);
ProcessAndTransmit(pTrx);
//再次根据目标地址更新本地地址
TransmitterSetInUseLocalAddrByDestAddr(pTrx);
//更新VIA头域
TransmitterUpdateViaByFinalLocalAddress(pTrx,pTrx->bFixVia);
//传送对象状态更新,并通过事务对象进行其它处理,暂不详细 //分析。
TransmitterChangeState(pTrx,
RVSIP_TRANSMITTER_STATE_READY_FOR_SENDING,
RVSIP_TRANSMITTER_REASON_UNDEFINED, pTrx->hMsgToSend,
NULL);
//编码SIP消息
PrepareSentOutboundMsg(pTrx,pTrx->hMsgToSend,NULL,0);
//将消息插入到传送对象的消息发送列表中
TransmitterMsgToSendListAddElement(pTrx,
pTrx->hSentOutboundMsg);
//消息发送
TransmitterControlTransmitMessage(pTrx)
switch(pTrx->destAddr.eTransport)
case RVSIP_TRANSPORT_UDP:
//将请求消息发出
SipTransportUdpSendMessage(
pTrx->pTrxMgr->hTransportMgr,
pTrx->pTrxMgr->hMessagePool,pTrx->hSentOutboundMs,
*(pTrx->localAddr.hAddrInUse), &pTrx->destAddr.addr)
//激活消息发送
PostMessageSendingActiviteis(pTrx,&msg);
//从传送对象的发送列表中移除已经发送的消息
TransmitterMsgToSendListRemoveElement(pTrx,
hMsgPage);
//传送对象状态切换
TransmitterChangeState(pTrx,
RVSIP_TRANSMITTER_STATE_MSG_SENT, RVSIP_TRANSMITTER_REASON_UNDEFINED,
NULL,(void*)pSendInfo);
pTrx->eState =
RVSIP_TRANSMITTER_STATE_MSG_SENT
//通知事务对象,传送状态已经变迁,这里触
//发TransactionTransportTrxStateChangeEv回
//调,下面单独分析
TransmitterCallbackStateChangeEv(pTrx,
eNewState, eReason,hMsg,pExtraInfo);
--------------------------------------------------------------------------------------------------------------------------------
TransactionTransportTrxStateChangeEv
switch (eState)
case RVSIP_TRANSMITTER_STATE_MSG_SENT:
//根据发送消息类型,触发事务定时器,事务定时器及后续超时处理不详细分析
TransactionTimerSetTimers(pTransc,((SipTransportSendInfo*)pExtraInfo)->msgType);