RvSIP Outband域名地址解析分析

以注册报文分析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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值