No ack on retransmitted confirmed uplinks

Hi there!
We have an issue whereas a confirmed uplink reaches the network server and the end device doesn’t “hear” the downlink ack frame (it can happen :stuck_out_tongue: ) the LoRaWAN stack will try several retransmission (in this case, 7).

The issue is that the fCnt won’t increment (normal behaviour) and the network server will say that it’s an “frame counter did not increment” error… which is fine because the uplink have reached application server… but it won’t respond to the subsequents confirmed uplinks and the end device will keep trying to retransmit the frame. Shouldn’t the NS respond anyway? I don’t want to disable frame counter validation as it will give me duplicated uplinks.

Thanks in advance!

I believe this is expected behavior (for LoRaWAN 1.0), and the device needs logic to behave appropriately for its power constraints, transmit counts, etc.

There is no way to distinguish a replay-attack from a re-transmission in LoRaWAN 1.0. If ChirpStack would respond to re-transmissions, then that would mean that an adversary would be able to reduce your network throughput by continuously re-transmit all uplinks that it sees.

Note that a LoRa gateway can receive multiple uplinks simultaneously, but that most gateways are half-duplex, thus when sending a downlink it is unable to receive. So you really want to avoid the possibility of an adversary that has the power of wasting gateway capacity.

In LoRaWAN 1.1 this is solved by adding the uplink channel into the MIC calculation. This means that as long the device re-transmits using a different channel, the NS can distinguish the re-transmission from a replay-attack.

Thanks, I though that as the 1.0.2 spec says that retransmissions should be in different channels that meant that the NS could identify retransmissions… but you are right, anyone could make replay attacks and that would be very bad :stuck_out_tongue:

I guess we can try do an app layer implementation to avoid this issue. Maybe we can send a duplicate message after 1 retransmission, store the fcnt error in our app backend and wait for a duplicate message and discard it.