Skip to content

Commit

Permalink
Fix behavior in presence of spurious non-CON requests
Browse files Browse the repository at this point in the history
Previously, RSTs were sent, which was in violation of the protocol.
  • Loading branch information
chrysn committed Nov 21, 2022
2 parents 90bcf41 + 96eeb67 commit 11285c3
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
8 changes: 5 additions & 3 deletions aiocoap/messagemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,15 @@ def dispatch_message(self, message):
if message.mtype is CON:
self._send_empty_ack(message.remote, message.mid, reason="acknowledging incoming response")
else:
if message.remote.is_multicast_locally:
self.log.info("Ignoring response incoming with multicast destination.")
else:
# A peer mustn't send a CON to multicast, but if a malicious
# peer does, we better not answer
if message.mtype == CON and not message.remote.is_multicast_locally:
self.log.info("Response not recognized - sending RST.")
rst = Message(mtype=RST, mid=message.mid, code=EMPTY, payload='')
rst.remote = message.remote.as_response_address()
self._send_initially(rst)
else:
self.log.info("Ignoring unknown response (which is not a unicast CON)")
else:
self.log.warning("Received a message with code %s and type %s (those don't fit) from %s, ignoring it.", message.code, message.mtype, message.remote)

Expand Down
12 changes: 11 additions & 1 deletion tests/test_noncoap_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,20 @@ async def test_noresponse(self):
@no_warnings
@asynctest
async def test_unknownresponse_reset(self):
self.mocksock.send(bytes.fromhex("4040ffff"))
self.mocksock.send(bytes.fromhex("4040ffff")) # CoAP CON 2.00 that the server has not sent a request for
response = await wait_for(self.mocksock.recv(), timeout=1)
self.assertEqual(response, bytes.fromhex("7000ffff"), "Unknown CON Response did not trigger RST")

@no_warnings
@asynctest
async def test_unknownresponse_noreset(self):
self.mocksock.send(bytes.fromhex("6040ffff")) # CoAP ACK 2.00 that the server has not sent a request for
try:
response = await wait_for(self.mocksock.recv(), timeout=1)
self.assertTrue(False, "Unknown ACK Response triggered something")
except TimeoutError:
pass

# Skipping the whole class when no multicast address was given (as otherwise
# it'd try binding :: which is bound to fail with a simplesocketserver setting)
@_skip_unless_defaultmcif
Expand Down

0 comments on commit 11285c3

Please sign in to comment.