您的位置:首页 > 理论基础 > 计算机网络

RvSIP 网络接口监控功能分析

2014-07-18 16:50 375 查看
备注:
在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);




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: