summaryrefslogtreecommitdiff
path: root/pysnmp/proto
diff options
context:
space:
mode:
authorelie <elie>2013-11-09 22:01:33 +0000
committerelie <elie>2013-11-09 22:01:33 +0000
commit704974e090122b73ef2ad59f23aa0b9e0e50023e (patch)
treef3331d4dcdd2f9aa3eb4e868410dc056e6dd660e /pysnmp/proto
parenteb44ada0eb7aaeb6be4026abe89af8420a942a9a (diff)
downloadpysnmp-704974e090122b73ef2ad59f23aa0b9e0e50023e.tar.gz
Execution Observer facility implemented to give app an inside view
of SNMP engine inner workings. This is thought to be a generic framework for viewing (and modifying) various internal states of pysnmp engine. Previously introduced non-RFC APIs (like getting peer's transport endpoint) will be gradually migrated to this new framework.
Diffstat (limited to 'pysnmp/proto')
-rw-r--r--pysnmp/proto/mpmod/rfc2576.py125
-rw-r--r--pysnmp/proto/mpmod/rfc3412.py108
-rw-r--r--pysnmp/proto/rfc3412.py120
3 files changed, 314 insertions, 39 deletions
diff --git a/pysnmp/proto/mpmod/rfc2576.py b/pysnmp/proto/mpmod/rfc2576.py
index d988496..03ad11f 100644
--- a/pysnmp/proto/mpmod/rfc2576.py
+++ b/pysnmp/proto/mpmod/rfc2576.py
@@ -33,8 +33,8 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
expectResponse,
sendPduHandle
):
- snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
- snmpEngineID = snmpEngineID.syntax
+ snmpEngineId, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
+ snmpEngineId = snmpEngineId.syntax
# rfc3412: 7.1.1b
if pdu.tagSet in rfc3411.confirmedClassPDUs:
@@ -45,7 +45,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
# Since there's no SNMP engine identification in v1/2c,
# set destination contextEngineId to ours
if not contextEngineId:
- contextEngineId = snmpEngineID
+ contextEngineId = snmpEngineId
# rfc3412: 7.1.5
if not contextName:
@@ -86,7 +86,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
globalData,
snmpEngineMaxMessageSize.syntax,
securityModel,
- snmpEngineID,
+ snmpEngineId,
securityName,
securityLevel,
scopedPDU
@@ -99,7 +99,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
int(msgID),
sendPduHandle=sendPduHandle,
msgID=msgID,
- snmpEngineID=snmpEngineID,
+ snmpEngineId=snmpEngineId,
securityModel=securityModel,
securityName=securityName,
securityLevel=securityLevel,
@@ -109,6 +109,26 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
transportAddress=transportAddress
)
+ communityName = msg.getComponentByPosition(1) # for observer
+
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc2576.prepareOutgoingMessage',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ wholeMsg=wholeMsg,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ communityName=communityName,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc2576.prepareOutgoingMessage'
+ )
+
return ( transportDomain, transportAddress, wholeMsg )
# rfc3412: 7.1
@@ -127,8 +147,8 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
stateReference,
statusInformation
):
- snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
- snmpEngineID = snmpEngineID.syntax
+ snmpEngineId, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
+ snmpEngineId = snmpEngineId.syntax
# rfc3412: 7.1.2.b
if stateReference is None:
@@ -162,7 +182,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
# Since there's no SNMP engine identification in v1/2c,
# set destination contextEngineId to ours
if not contextEngineId:
- contextEngineId = snmpEngineID
+ contextEngineId = snmpEngineId
# rfc3412: 7.1.5
if not contextName:
@@ -193,8 +213,6 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
errorIndication = errind.unsupportedSecurityModel
)
- securityEngineId = snmpEngineID
-
# rfc3412: 7.1.8.a
( securityParameters,
wholeMsg ) = smHandler.generateResponseMsg(
@@ -203,13 +221,31 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
globalData,
maxMessageSize,
securityModel,
- snmpEngineID,
+ snmpEngineId,
securityName,
securityLevel,
scopedPDU,
securityStateReference
)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc2576.prepareResponseMessage',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=snmpEngineId,
+ communityName=msg.getComponentByPosition(1),
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc2576.prepareResponseMessage'
+ )
+
return ( transportDomain, transportAddress, wholeMsg )
# rfc3412: 7.2.1
@@ -241,8 +277,9 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
# rfc2576: 5.2.1
snmpEngineMaxMessageSize, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize')
+ communityName = msg.getComponentByPosition(1)
securityParameters = (
- msg.getComponentByPosition(1),
+ communityName,
# transportDomain identifies local enpoint
(transportDomain, transportAddress)
)
@@ -261,7 +298,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
)
# rfc3412: 7.2.6
- ( securityEngineID,
+ ( securityEngineId,
securityName,
scopedPDU,
maxSizeResponseScopedPDU,
@@ -276,7 +313,7 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
msg
)
- debug.logger & debug.flagMP and debug.logger('prepareDataElements: SM returned securityEngineID %r securityName %r' % (securityEngineID, securityName))
+ debug.logger & debug.flagMP and debug.logger('prepareDataElements: SM returned securityEngineId %r securityName %r' % (securityEngineId, securityName))
# rfc3412: 7.2.6a --> noop
@@ -329,6 +366,24 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
stateReference = None
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc2576.prepareDataElements:response',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ communityName=communityName,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc2576.prepareDataElements:response'
+ )
+
# rfc3412: 7.2.12c
smHandler.releaseStateInformation(securityStateReference)
@@ -353,12 +408,12 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
msgID = pdu.getComponentByPosition(0)
# rfc3412: 7.2.13a
- snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
- if securityEngineID != snmpEngineID.syntax:
+ snmpEngineId, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
+ if securityEngineId != snmpEngineId.syntax:
smHandler.releaseStateInformation(securityStateReference)
raise error.StatusInformation(
errorIndication = errind.engineIDMismatch
- )
+ )
# rfc3412: 7.2.13b
stateReference = self._cache.newStateReference()
@@ -378,6 +433,24 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
transportAddress=transportAddress
)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc2576.prepareDataElements:confirmed',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ communityName=communityName,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc2576.prepareDataElements:confirmed'
+ )
+
debug.logger & debug.flagMP and debug.logger('prepareDataElements: cached by new stateReference %s' % stateReference)
# rfc3412: 7.2.13c
@@ -400,6 +473,24 @@ class SnmpV1MessageProcessingModel(AbstractMessageProcessingModel):
# Pass new stateReference to let app browse request details
stateReference = self._cache.newStateReference()
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc2576.prepareDataElements:unconfirmed',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ communityName=communityName,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc2576.prepareDataElements:unconfirmed'
+ )
+
# This is not specified explicitly in RFC
smHandler.releaseStateInformation(securityStateReference)
diff --git a/pysnmp/proto/mpmod/rfc3412.py b/pysnmp/proto/mpmod/rfc3412.py
index f51033a..09779a4 100644
--- a/pysnmp/proto/mpmod/rfc3412.py
+++ b/pysnmp/proto/mpmod/rfc3412.py
@@ -259,6 +259,23 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
transportAddress=transportAddress
)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareOutgoingMessage',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ wholeMsg=wholeMsg,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareOutgoingMessage'
+ )
+
return ( transportDomain,
transportAddress,
wholeMsg )
@@ -296,7 +313,7 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
transportAddress = cachedParams['transportAddress']
debug.logger & debug.flagMP and debug.logger('prepareResponseMessage: stateReference %s' % (stateReference))
-
+
# 7.1.3
if statusInformation is not None and 'oid' in statusInformation:
# 7.1.3a
@@ -389,7 +406,7 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
# XXX need to coerce MIB value as it has incompatible constraints set
headerData.setComponentByPosition(
1, snmpEngineMaxMessageSize.syntax, verifyConstraints=False
- )
+ )
# 7.1.7d
msgFlags = 0
@@ -452,6 +469,23 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
if len(wholeMsg) > min(snmpEngineMaxMessageSize.syntax, maxMessageSize):
raise error.StatusInformation(errorIndication=errind.tooBig)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareResponseMessage',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=snmpEngineID,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareResponseMessage'
+ )
+
return ( transportDomain, transportAddress, wholeMsg )
# 7.2.1
@@ -674,6 +708,23 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
# 7.2.11b (incomplete implementation)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareDataElements:internal',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareDataElements:internal'
+ )
+
# 7.2.11c
smHandler.releaseStateInformation(securityStateReference)
@@ -700,6 +751,23 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
errorIndication = errind.dataMismatch
)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareDataElements:response',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareDataElements:response'
+ )
+
# 7.2.12c
smHandler.releaseStateInformation(securityStateReference)
stateReference = None
@@ -749,6 +817,23 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
debug.logger & debug.flagMP and debug.logger('prepareDataElements: new stateReference %s' % stateReference)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareDataElements:confirmed',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareDataElements:confirmed'
+ )
+
# 7.2.13c
return ( messageProcessingModel,
securityModel,
@@ -768,7 +853,24 @@ class SnmpV3MessageProcessingModel(AbstractMessageProcessingModel):
if pduType in rfc3411.unconfirmedClassPDUs:
# Pass new stateReference to let app browse request details
stateReference = self._cache.newStateReference()
-
+
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.prepareDataElements:unconfirmed',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ securityEngineId=securityEngineId,
+ pdu=pdu)
+ )
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.prepareDataElements:unconfirmed'
+ )
+
# This is not specified explicitly in RFC
smHandler.releaseStateInformation(securityStateReference)
diff --git a/pysnmp/proto/rfc3412.py b/pysnmp/proto/rfc3412.py
index d18c74f..2aee1a6 100644
--- a/pysnmp/proto/rfc3412.py
+++ b/pysnmp/proto/rfc3412.py
@@ -33,9 +33,10 @@ class MsgAndPduDispatcher:
# Source of sendPduHandle and cache of requesting apps
self.__sendPduHandle = nextid.Integer(0xffffff)
- # To pass transport info to app
+ # To pass transport info to app (legacy)
self.__transportInfo = {}
+ # legacy
def getTransportInfo(self, stateReference):
if stateReference in self.__transportInfo:
return self.__transportInfo[stateReference]
@@ -135,14 +136,17 @@ class MsgAndPduDispatcher:
debug.logger & debug.flagDsp and debug.logger('sendPdu: new sendPduHandle %s, timeout %s ticks, cbFun %s' % (sendPduHandle, timeout, cbFun))
+ origTransportDomain = transportDomain
+ origTransportAddress = transportAddress
+
# 4.1.1.4 & 4.1.1.5
try:
- ( destTransportDomain,
- destTransportAddress,
+ ( transportDomain,
+ transportAddress,
outgoingMessage ) = mpHandler.prepareOutgoingMessage(
snmpEngine,
- transportDomain,
- transportAddress,
+ origTransportDomain,
+ origTransportAddress,
messageProcessingModel,
securityModel,
securityName,
@@ -168,21 +172,38 @@ class MsgAndPduDispatcher:
self.__cache.pop(sendPduHandle)
raise error.PySnmpError('Transport dispatcher not set')
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.sendPdu',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ outgoingMessage=outgoingMessage,
+ messageProcessingModel=messageProcessingModel,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ pdu=PDU)
+ )
+
try:
snmpEngine.transportDispatcher.sendMessage(
- outgoingMessage, destTransportDomain, destTransportAddress
+ outgoingMessage, transportDomain, transportAddress
)
except PySnmpError:
if expectResponse:
self.__cache.pop(sendPduHandle)
raise
+ snmpEngine.observer.clearExecutionContext(snmpEngine, 'rfc3412.sendPdu')
+
# Update cache with orignal req params (used for retrying)
if expectResponse:
self.__cache.update(
sendPduHandle,
- transportDomain=transportDomain,
- transportAddress=transportAddress,
+ transportDomain=origTransportDomain,
+ transportAddress=origTransportAddress,
securityModel=securityModel,
securityName=securityName,
securityLevel=securityLevel,
@@ -210,7 +231,6 @@ class MsgAndPduDispatcher:
stateReference,
statusInformation
):
- """PDU dispatcher -- prepare and serialize a response"""
# Extract input values and initialize defaults
k = int(messageProcessingModel)
if k in snmpEngine.messageProcessingSubsystems:
@@ -224,8 +244,8 @@ class MsgAndPduDispatcher:
# 4.1.2.2
try:
- ( destTransportDomain,
- destTransportAddress,
+ ( transportDomain,
+ transportAddress,
outgoingMessage ) = mpHandler.prepareResponseMessage(
snmpEngine,
messageProcessingModel,
@@ -239,7 +259,7 @@ class MsgAndPduDispatcher:
maxSizeResponseScopedPDU,
stateReference,
statusInformation
- )
+ )
debug.logger & debug.flagDsp and debug.logger('returnResponsePdu: MP suceeded')
except error.StatusInformation:
# 4.1.2.3
@@ -253,12 +273,31 @@ class MsgAndPduDispatcher:
snmpSilentDrops.syntax = snmpSilentDrops.syntax + 1
raise error.StatusInformation(errorIndication=errind.tooBig)
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.returnResponsePdu',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ outgoingMessage=outgoingMessage,
+ messageProcessingModel=messageProcessingModel,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ pdu=PDU)
+ )
+
# 4.1.2.4
snmpEngine.transportDispatcher.sendMessage(
outgoingMessage,
- destTransportDomain,
- destTransportAddress
- )
+ transportDomain,
+ transportAddress
+ )
+
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.returnResponsePdu'
+ )
# 4.2.1
def receiveMessage(
@@ -396,11 +435,27 @@ class MsgAndPduDispatcher:
# 4.2.2.1.2.d
return restOfWholeMsg
else:
- # Pass transport info to app
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.receiveMessage:request',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ wholeMsg=wholeMsg,
+ messageProcessingModel=messageProcessingModel,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ pdu=PDU)
+ )
+
+ # pass transport info to app (legacy)
if stateReference is not None:
self.__transportInfo[stateReference] = (
transportDomain, transportAddress
- )
+ )
+
# 4.2.2.1.3
processPdu(
snmpEngine,
@@ -414,9 +469,16 @@ class MsgAndPduDispatcher:
PDU,
maxSizeResponseScopedPDU,
stateReference
- )
+ )
+
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.receiveMessage:request'
+ )
+
+ # legacy
if stateReference is not None:
del self.__transportInfo[stateReference]
+
debug.logger & debug.flagDsp and debug.logger('receiveMessage: processPdu succeeded')
return restOfWholeMsg
else:
@@ -436,6 +498,21 @@ class MsgAndPduDispatcher:
# 4.2.2.2.3
# no-op ? XXX
+ snmpEngine.observer.storeExecutionContext(
+ snmpEngine,
+ 'rfc3412.receiveMessage:response',
+ dict(transportDomain=transportDomain,
+ transportAddress=transportAddress,
+ wholeMsg=wholeMsg,
+ messageProcessingModel=messageProcessingModel,
+ securityModel=securityModel,
+ securityName=securityName,
+ securityLevel=securityLevel,
+ contextEngineId=contextEngineId,
+ contextName=contextName,
+ pdu=PDU)
+ )
+
# 4.2.2.2.4
processResponsePdu = cachedParams['cbFun']
processResponsePdu(
@@ -451,7 +528,12 @@ class MsgAndPduDispatcher:
statusInformation,
cachedParams['sendPduHandle'],
cachedParams['cbCtx']
- )
+ )
+
+ snmpEngine.observer.clearExecutionContext(
+ snmpEngine, 'rfc3412.receiveMessage:response'
+ )
+
debug.logger & debug.flagDsp and debug.logger('receiveMessage: processResponsePdu succeeded')
return restOfWholeMsg