Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions mqtt_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class MQTTControlPacket:
UNSUBACK,
]

unparsed = ''
def __init__(self, packet):
self._packet = packet
# Fixed header
Expand All @@ -62,6 +63,13 @@ def __init__(self, packet):
self.packet_type_human = self.Names[self.packet_type]
self.dup, self.qos, self.retain = self._parse_flags()
self.remaining_length, self.total_length = self._parse_remaining_length()
# The remaining_length only gives the data,
# it is possible that one tcp packet contains multiple mqtt packets
# capture the unparsed stuff
if self.total_length < len(packet):
self.unparsed = packet[self.total_length:]
self._packet = packet[:self.total_length]

if self.total_length > len(packet):
# Partial packet, raise BlockingIOError (the Python error than best corresponds to errno EAGAIN)
raise BlockingIOError(f'Incomplete MQTT control packet: only {len(packet)} bytes remaining, but header expected {self.total_length}', len(packet))
Expand Down Expand Up @@ -263,8 +271,12 @@ def _parse_packet_identifier(self):
def tcp_message(flow: tcp.TCPFlow | http.HTTPFlow):
message = flow.messages[-1]

mqtt_packet = MQTTControlPacket(message.content)
dump(mqtt_packet)
data = message.content
while data:
mqtt_packet = MQTTControlPacket(data)
dump(mqtt_packet)
data = mqtt_packet.unparsed



def dump(mqtt_packet: MQTTControlPacket):
Expand Down Expand Up @@ -306,12 +318,16 @@ def websocket_message(flow: http.HTTPFlow):
ws_buffer[fid] += flow.websocket.messages[-1].content
while ws_buffer[fid]:
try:
mqtt_packet = MQTTControlPacket(ws_buffer[fid])
data = ws_buffer[fid]
while data:
mqtt_packet = MQTTControlPacket(data)
dump(mqtt_packet)
data = mqtt_packet.unparsed

except BlockingIOError as exc:
ctx.log.debug("Awaiting more bytes for complete MQTT control packet")
break
else:
dump(mqtt_packet)
b = ws_buffer[fid] = mqtt_packet._extra
b = ws_buffer[fid] = mqtt_packet._extra # Not 100% about the logic here -- check
if b:
ctx.log.debug(f'Saving remaining {len(b)} bytes after MQTT control packet')