1、调度程序
调度程序是SNMP引擎中的关键部分,每个SNMP引擎只有一个调度程序。其任务是调度任务给各个版本相应的消息处理模型,将PDU调度给相关的应用程序。
对于外流的消息,某个应用程序将提供被发送的PDU,添加一些准备和发送信息需要的数据之后,应用程序确定将要使用的消息处理模型的版本以及期望的安全处理。
对于引入的消息,调度程序确定版本信息,并将该消息传送给相应版本的消息处理模型提取消息数据,协同安全处理服务对该消息进行处理。版本确定之后,PDU调度程序决定该PDU应当发送给哪个应用程序。
2、消息处理子系统
消息处理子系统是SNMP引擎的一部分,它同调度程序交互处理对应版本的消息,消息处理子系统包含一个或多个消息处理模型。
3、消息处理和调度的元素
在RFC3411中定义了如下元素:
contextEngineID
contextName
scopedPDU
maxSizeResponseScopedPDU
securityModel
securityName
securityLevel
messageProcessingModel
上述元素的值,对于引入的消息来说,相应版本的消息处理模块将它们的值提供给调度程序。对于流出的消息来说,由应用程序提供它们的值给调度程序。
对于某些版本的消息处理模块,这些值是从收到的消息中萃取而来;而对于其他的版本,这些值是通过某种算法计算或某种定义好的机制而来。而这种机制定义的值与调度程序不相关。
(1) 消息处理模型(messageProcessingModel)
messageProcessingModel的值标识消息处理模型。消息处理模型描述从消息中萃取数据的特定版本过程、产生消息、调用安全模型对消息提供安全服务;消息处理模型还负责将数据从特定版本的消息格式转换为一般格式数据,或者将一般格式数据转换成特定版本格式的数据。
(2) Pdu版本(PduVersion)
PduVersion的值描述协议操作的详细版本信息和与其关联的PDU格式。例如:SNMPv1、SNMPv2等。这个值还明确了消息中包含的PDU版本,同时指明了处理该PDU的应用程序。调度程序并不直接使用该值。
当应用程序请求调度程序向其他SNMP引擎发送PDU时,它将指定PduVeesion给调度程序,调度程序将该PduVersion传递给消息处理模型,消息处理模型将知道该如何处理该PDU。
对于引入的消息,pduVersion由相应版本的消息处理模块提供给调度程序,PDU调度程序将pduVersion传递给相应的应用程序,应用程序知道如何恰当的处理该PDU。
(3) Pdu类型(PduType)
PduType的值描述了协议操作的特定类型,是消息包含的PDU版本。应用程序为特定的contextEngineID注册特定的pduType。对于引入的消息,pduType由相应版本的消息处理模块提供给调度程序,随后用来调度该PDU给注册了该pduType的contextEngineID对应的应用程序。
(4) 发送PDU句柄(sendPduHandle)
sendPduHandle用于协调SNMP引擎和应用程序之间请求与应答操作,该句柄必须在所有版本的消息处理模块中是唯一的,并且只具有本地意义。
4、过程的调度程序元素(Dispatcher Elements of Procedure)
(1) 发送SNMP消息到网络
1)发送请求或通知
l 应用利用如下抽象原语请求发送一个这样的消息到网络。
l 如果messageProcessingModel的值标识的不是调度器所能识别的消息处理模型,返回一个errorIndication给应用,停止下面的工作。
l 调度器产生一个sendPduHandle,用于协调子系统的处理。
l 消息调度器根据messageProcessingModle利用如下原语将请求发送给相应版本的消息处理模块。
l 如果statusInformation显示一个错误,则返回一个errorIndication给相应请求。
l 如果statusInformation显示成功,sendPduHandle返回给应用,并且发送outgoingMessage。同时,通过destTransportDomain返回Transport,经由destTransportAddress返回地址。
2)发送应答到网络上
l 能够发送应答的应用通过如下抽象服务原语发送应答。
l 调度器通过如下原语将该请求发送到messageProcessingModel标识的消息处理模型。
l 如果result显示为errorIndication,errorIndication将被返回到应用,停止下面的工作。
l 如果result显示为成功,outgoingMessage将被发送,同时通过destTransportDomain返回Transport,经由destTransportAddress返回地址。
(2)从网络上接收消息
1)对收到的消息进行消息调度
l snmpInPkts计数器自加。
l 消息的版本被确定,如果消息不能清晰的被解析出其版本,则产生snmpInASNParseErrs计数器自加,丢弃消息;如果消息版本不支持,snmpInBadVersions计数器自加,丢弃消息。
l 确定源transportDomain和源transportAddress。
l 消息被传递给相应版本的消息处理模块,并返回抽象数据元素给调度器。这个操作是利用如下原语完成的。
l 如果result显示为errorIndication,消息将被丢弃。
l 至此,抽象数据元素准备好了,接下来的处理如下一部分描述。
2)对传入的消息进行PDU调度
接下来的处理由sendPduHandle来决定PDU调度器进行什么工作。如果sendPduHandle的值是<NONE>,表明该消息是一个请求或者通知,则进行下面第一部分的操作,表明该消息是一个应答,否则进行第二部分的操作。
Section 1:传入的是请求或通知
l 通过contextEngineID和PduType的组合,确定哪个应用注册了这个请求或通知;
l 如果没有应用注册,则:
a) snmpUnkownPDUHandle自加;
b) 利用如下原语产生一个请求;
c) 如果result显示为成功,这个准备好的消息被发送到destTransportDomain和destTransportAddress指示的请求产生者。同时通过destTransportDomain返回Transport,经由destTransportAddress返回地址。
d) 传入的消息被丢弃,这条消息的处理结束。
l 利用如下抽象服务原语,该PDU被调度到相应的应用中。
这条消息的处理结束。
Section 2:传入的是响应
l 利用sendPduHandle找到哪个应用正在等待这个应答;
l 如果没有找到这样的应用,消息被丢弃,同时stateReference被释放,snmpUnkownPDUHandle计数器自加,这条消息的处理结束。
l 丢弃所有缓存的关于该消息的信息(包括stateReference);
l 利用如下抽象服务原语将该应答被调度到相应的应用
该消息的处理结束。
(3)为正在处理的PDU类型注册应用
应用如果要处理某些PDU,必须在PDU调度器中进行注册,应用指出对哪些contextEngineID和PduType组合的消息负责。
l 应用利用如下抽象服务原语注册职责
注:实现应该针对同时注册多个contextEngineID提供一种请求注册手段,当然也要提供一种针对同时发生注册多个PduType值得情况。
l 检查参数的合法性,如果不合法,返回一个errorIndication(invalidParameter)给该应用。
l 一个contextEngineID和PduType组合只能注册一次,如果其他应用也要注册该组合,将会返回一个errorIndication(alreadyRegistered)给该应用。
l 否则,该次注册被存储,PDU可依此调度到相应的应用。
(4)应用注销处理的PDU
如果应用不再处理某个PDU,必须到调度器中注销。
l 应用可以利用如下抽象服务原语注销
注:实现必须提供同时注销多个contextEngineID的手段,当然也要提供一种同时注销多个pduType的手段。
l 如果该contextEngineID和pduType被注册了,直接删除该注册。如果不存在,则忽略该注销。
本文可任意转载和复制,但不得用于商业目的。在转载时,请注明出处!
-----------------> 支持开源 <-------------------