RvSIP 网络接口监控功能分析

备注:
在Ver 6.5.0.14版本上含有此功能,在Ver 5.0.0.29版本上没有此功能,其它版本未知。


初始化

//初始配全局配置结构
RvSipStackInitCfg(sizeof(RvSipStackCfg), p_stack_cfg);
	//标记使用网络接口变更功能
	internalStackCfg.bHandleNetworkInterfaceChange = RV_TRUE;

//协议栈构造
RvSipStackConstruct(……)
memcpy(&internalCfgStruct, pStackCfg, minCfgSize);

//协议栈各模块构造
StackConstructModules(&internalCfgStruct, pStackMgr);
	//传送层模块构造
	StackConstructTransportModule(…)
		//将网络接口变更功能配置存储到传送层配置块中
		transportCfg.bHandleNetworkInterfaceChange    = 
			pStackCfg->bHandleNetworkInterfaceChange;
		
		//传送层构造
		SipTransportConstruct(…)
			//传送层管理对象初始化
			TransportMgrInitialize(…)
				//将网络接口变更功能配置存储到传送层管理对象中
				pTransportMgr->bHandleNetworkInterfaceChange = 
					pTransportCfg->bHandleNetworkInterfaceChange;
				
				//将网络接口监控套接口注册到select引擎中,同时设置
				//对应的处理回调函数为NetworkAddressChangedEventHandler
				RvInterfaceMonitorRegister(pTransportMgr->pSelect,
				NetworkAddressChangedEventHandler, pTransportMgr,
				&pTransportMgr->listenerIdNetworkAddressChanged);
					pSelEng->currentAddrsNum = 
						RV_ADDR_MONITOR_MAX_CURRADDRS;	//10
					
					//当前RV_OS_TYPE宏为RV_OS_TYPE_LINUX,所以这里的
					// RvHostGetIpv4List为rvHostUnixGetIpV4List
					RvHostGetIpv4List(pSelEng->logMgr,
(RvUint32*)&pSelEng->currentAddrsNum,
pSelEng->currentAddrs);
	//调用系统接口,获取所有本地IPv4接口地址,存储到select
	//引擎中pSelEng->currentAddrs,其中环回地址放在最后面。
	rvHostUnixGetIpV4List(…);

//创建netlink套接口
pSelEng->routingSocket = socket(AF_NETLINK,SOCK_RAW, NETLINK_ROUTE);

//设置监听接口链路变动及接口配置变动的通知链组
nladdr.nl_family = AF_NETLINK;
nladdr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
nladdr.nl_pid = getpid();
bind(pSelEng->routingSocket, (struct sockaddr *) &nladdr, sizeof(nladdr));

//构造文件描述符对象,关联上面创建的netlink,并将文件描述
//符对象加入到select引擎对象中。同时设置该socket的处理回
//调函数为routingSocketCb
RvFdConstruct(&pSelEng->routingSocketFD,&pSelEng->routingSocket,logMgr);
RvSelectAdd2(pSelEng,&pSelEng->routingSocketFD,RvSelectRead,routingSocketCb,RV_FALSE);

//标记select引擎的接口监控已经开启
pSelEng->interfaceMonitorStarted = RV_TRUE;

//设置监控者回调,这里接口变动处理回调为
//NetworkAddressChangedEventHandler
pSelEng->onAddressChangeListenerers[cnt] = pListener;
pSelEng->onAddressChangeListenerersCtx[cnt] = pAppCtx;
pSelEng->onAddressChangeListenerersCnt ++;


系统接口变化通知

//netlink套接口处理回调
routingSocketCb
	//接收通知消息
	recvmsg(selectEngine->routingSocket, &msg, 0);
	
	//启动一个3秒定时器,待定时器超时后才处理所有的netlink通知消息,在定时器未
	//超时之前,仅收集所有系统发来的通知消息,最后统一处理。定时器超时后的回调函
	//数为routingSocketTimerCb
	RvTimerStartEx(&selectEngine->routingSocketTimer,&selectEngine->tqueue,
RvInterfaceMonitorStop(RV_TIMER_TYPE_ONESHOT,delay,routingSocketTimerCb,selectEngine);
---------------------------------------------------------------------------------------------------------------------------------
routingSocketTimerCb
	selectEngine->routingSocketTimerStarted = RV_FALSE;
	
	//处理接口改变的通知
	RvInterfaceMonitorChangeDetected(selectEngine);
		//获取当前系统网络接口的IPv4地址列表
		RvHostGetIpv4List(pSelEng->logMgr,&addrSz,addrs);
		
		//将当前获取的系统接口与之前在select引擎对象中记载的系统接口进行对比,得
		//出当前已经删除的接口数、已经删除的接口列表、新增的接口数、新增的接口列
		//表。分别存储到临时变量removed 、addrsRemoved 、added 、addrsAdded。
		
		//将当前系统接口的IPv4地址列表设置到select引擎对象中
		memcpy(pSelEng->currentAddrs,addrs,addrSz*sizeof(RvAddress));
		pSelEng->currentAddrsNum = addrSz;
		
		//调用监控者回调,当前回调为NetworkAddressChangedEventHandler
		memcpy(currListeners,pSelEng->onAddressChangeListenerers,
RV_ADDR_MONITOR_MAX_LISTENERES*sizeof(void*));
currListeners[cnt1])(currCtx[cnt1],addrsAdded,added,addrsRemoved,removed);
---------------------------------------------------------------------------------------------------------------------------------
NetworkAddressChangedEventHandler
	//遍历所有已经移除的系统接口
	for (i=0; i<removedAddrsCnt; i++)
		//进行删除处理
		if (pTransportMgr->hLocalUdpAddrList != NULL)
			NetworkAddressRemove(pTransportMgr, pTransportMgr->hLocalUdpAddrList, 
			&removedAddrs[i]);
				//获取传送对象本地地址列表的首地址
				RLIST_GetHead(pTransportMgr->hLocalAddrPool, hLocalAddrList,
(RLIST_ITEM_HANDLE*)&pLocalAddr);

while (pLocalAddr != NULL)
					
	bEqual = RvAddressCompare(&pLocalAddr->addr.addr, pAddress,
RV_ADDRESS_BASEADDRESS);
	
	//将当前传送对象的本地地址与已经删除的地址进行比较,如果相同
	//则对当前传送对象的本地地址进行去标记处理。
	if (bEqual == RV_TRUE)
		TransportMgrLocalAddressMarkUnusable(pLocalAddr);
			//标记地址已经不可使用
			pLocalAddr->bUsable = RV_FALSE;
			//地址引用计数递减处理
			TransportMgrLocalAddressRefCounterDecrement(pLocalAddr, 
			NULL);
				//引用计数递减
				pLocalAddr->refCounter--;
				
				//如果引用计数已经为0,则进行移除处理
				if (pLocalAddr->refCounter == 0)
					TransportMgrLocalAddressRemove(…)
						//如果接口监控功能开启,则在协议栈初始化
						//进行配置检测时在CalculateConfigParams
						//函数强制开启删除本地地址的开关。
						if (RV_FALSE == pTransportMgr->bDLAEnabled)
							return RV_ERROR_ILLEGAL_ACTION;
						
						//关闭该SOCKET,并且从传送对象的本地地
						//址列表中删除该地址。
						LocalAddressClose(pTransportMgr,pLocalAddr);
						LocalAddressRemoveFromList(…);
	
	//遍历所有传送对象本地地址列表
RLIST_GetNext(pTransportMgr->hLocalAddrPool, hLocalAddrList,
(RLIST_ITEM_HANDLE)pLocalAddr,&pLocalAddr);
	
	//遍历所有已经新增的系统接口
	for (i=0; i<addedAddrsCnt; i++)
		//将地址转换成协议栈处理的对象格式
		TransportMgrConvertRvAddress2TransportAddr((RvAddress*)&addedAddrs[i], 
		&addressDetails);
		
		//进行添加处理
		if (pTransportMgr->hLocalUdpAddrList != NULL)
			addressDetails.eTransportType = RVSIP_TRANSPORT_UDP;
			addressDetails.port = pTransportMgr->defaultUdpPort;
			
			NetworkAddressAdd(pTransportMgr, pTransportMgr->hLocalUdpAddrList,
&addedAddrs[i],&addressDetails);
	//获取传送对象本地地址列表的首地址
	RLIST_GetHead(pTransportMgr->hLocalAddrPool, hLocalAddrList,
(RLIST_ITEM_HANDLE*)&pLocalAddr);

//遍历所有传送对象本地地址列表
while (pLocalAddr != NULL)
	//在当前本地地址列表中查找是否有与新增的地址对象相同,如果
	//不同,则继续查找下一个,直到找到相同的。
	bEqual = RvAddressCompare(&pLocalAddr->addr.addr, pAddress,
	RV_ADDRESS_BASEADDRESS);
	if (bEqual == RV_FALSE)
		RLIST_GetNext(pTransportMgr->hLocalAddrPool, hLocalAddrList,
		pLocalAddr, (RLIST_ITEM_HANDLE*)&pLocalAddr);
		continue;
	
	//如果当前地址列表中的地址已经为可使用状态,则直接返回。
	SipTransportMgrLocalAddressIsUsable(pLocalAddr, &bUsable);
	if (pLocalAddr->bUsable == RV_TRUE)
		return;
	
	//将之前已经标记为不可使用的地址标记为可以使用。
	TransportMgrLocalAddressMakeUsable(pLocalAddr);
	
	Return;

//如果新增的接口地址没有出现在传送模块的本地地址列表中,则添加到
//地址列表中。
TransportMgrLocalAddressAdd(pTransportMgr, pAddressDetails, 
sizeof(RvSipTransportAddr), RVSIP_LAST_ELEMENT, NULL, RV_TRUE,
RV_FALSE, RV_TRUE, &hLocalAddr);





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值