From c4880b636bf1069e5d216fd96db671e9004eec73 Mon Sep 17 00:00:00 2001 From: Zaid Abdulla Date: Sat, 10 Dec 2016 16:01:25 -0800 Subject: [PATCH] Fault when provisions repeat indefinitely --- lib/cwmp.coffee | 3 +++ lib/session.coffee | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/cwmp.coffee b/lib/cwmp.coffee index 296233d..bea5450 100644 --- a/lib/cwmp.coffee +++ b/lib/cwmp.coffee @@ -483,6 +483,9 @@ listener = (httpRequest, httpResponse) -> throw err if err sessionData.tasks = dueTasks sessionData.faults = faults + sessionData.retries = {} + for k, v of faults + sessionData.retries[k] = v.retries sessionData.operations = operations # Delete expired faults diff --git a/lib/session.coffee b/lib/session.coffee index b24dfec..cdcda3b 100644 --- a/lib/session.coffee +++ b/lib/session.coffee @@ -103,9 +103,6 @@ loadParameters = (sessionData, callback) -> generateRpcId = (sessionData) -> - if sessionData.rpcCount > 255 or sessionData.revisions.length > 15 - throw new Error('Too many RPCs') - return sessionData.timestamp.toString(16) + "0#{sessionData.rpcCount.toString(16)}".slice(-2) @@ -611,8 +608,8 @@ rpcRequest = (sessionData, _declarations, callback) -> detail: fault.detail } - if sessionData.faults[channel]? - f.retries = (sessionData.faults[channel].retries or 0) + 1 + if sessionData.retries[channel]? + f.retries = sessionData.retries[channel] + 1 faults[channel] = f @@ -686,6 +683,32 @@ rpcRequest = (sessionData, _declarations, callback) -> if not sessionData.syncState? return callback() + if sessionData.rpcCount >= 255 or + sessionData.revisions.length >= 8 or + sessionData.iteration >= 64 + + faults = {} + for p, i in sessionData.provisions[0] + channel = sessionData.channels[i] + fault = faults[channel] + if not fault? + fault = { + provisions: [] + timestamp: sessionData.timestamp + code: 'endless_cycle' + message: 'The provision seems to be repeating indefinitely' + } + + if sessionData.retries[channel]? + fault.retries = sessionData.retries[channel] + 1 + + faults[channel] = fault + + fault.provisions.push(p) + + clearProvisions(sessionData) + return callback(null, faults) + inception = sessionData.declarations.length - 1 provisions = generateGetVirtualParameterProvisions(sessionData, sessionData.syncState.virtualParameterDeclarations[inception]) @@ -1551,8 +1574,8 @@ rpcFault = (sessionData, id, faultResponse, callback) -> detail: faultResponse.detail } - if sessionData.faults[channel]? - fault.retries = (sessionData.faults[channel].retries or 0) + 1 + if sessionData.retries[channel]? + fault.retries = sessionData.retries[channel] + 1 faults[channel] = fault