From 0df4bcb1d6d5b19f157979a79986059a90b614ea Mon Sep 17 00:00:00 2001 From: Max Khon Date: Thu, 8 Aug 2019 14:07:26 +0700 Subject: [PATCH] recv_pdu() receives up to 1024 bytes at once from the agentx socket into a parsing buffer. Then the buffer is interpreted as a single PDU even if the buffer contained more than one PDU. Fix this by using payload_length field of AgentX PDU header and saving remaining unparsed buffer for the next recv_pdu() call. --- pyagentx/network.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pyagentx/network.py b/pyagentx/network.py index 9711398..c1d2370 100644 --- a/pyagentx/network.py +++ b/pyagentx/network.py @@ -14,6 +14,7 @@ def emit(self, record): import time import threading import Queue +import struct import pyagentx from pyagentx.pdu import PDU @@ -27,6 +28,7 @@ def __init__(self, queue, oid_list, sethandlers): self._queue = queue self._oid_list = oid_list self._sethandlers = sethandlers + self._recv_buf = '' self.session_id = 0 self.transaction_id = 0 @@ -65,11 +67,18 @@ def send_pdu(self, pdu): self.socket.send(pdu.encode()) def recv_pdu(self): - buf = self.socket.recv(1024) - if not buf: return None + if len(self._recv_buf) < 20: + self._recv_buf += self.socket.recv(1024) + if len(self._recv_buf) < 20: + return None + payload_len = struct.unpack('!L', self._recv_buf[16:20])[0] + logger.debug('buffer length {}, pdu length {}'.format(len(self._recv_buf), 20+payload_len)) pdu = PDU() - pdu.decode(buf) + pdu.decode(self._recv_buf[:20+payload_len]) + self._recv_buf = self._recv_buf[20+payload_len:] if self.debug: pdu.dump() + if len(self._recv_buf) > 0: + logger.debug('remaining buffer length {}'.format(len(self._recv_buf))) return pdu