apache / mynewt-nimble

Apache mynewt
https://mynewt.apache.org/
Apache License 2.0
664 stars 384 forks source link

nimble/ll: Fix encryption pause/restart procedure #1796

Closed andrzej-kaczmarek closed 3 weeks ago

andrzej-kaczmarek commented 3 weeks ago

This fixes 2 issues in encrpytion pause/restart procedure (i.e. key refresh) initiated in central role:

  1. We transition to "paused" encryption state when LL_PAUSE_ENC_RSP is txd, but that is done after we try to enqueue LL_ENC_REQ. This means LL_ENC_REQ is put at the end of tx queue. By conicidence this makes order of PDUs correct when there's only LL_PAUSE_ENC_RSP on tx queue, but it fails if there was an ACL packet already queued. In such case LL_ENC_REQ is queued after that ACL packet which means neither will be sent - ACL packet cannot be sent because we have no encryption, LL_ENC_REQ cannot be sent because there's ACL packet in front.
  2. We do not check if LL_ENC_REQ was properly queued (i.e. if mbuf was allocated for PDU) so it may happen that LL_ENC_REQ will never be queued.

In both scenarios the connection will timeout eventually since encryption restart procedure cannot be completed.

This fix ensures that LL_ENC_REQ is queued properly by using a "pending" flag that is evaluated when checking for pending procedures.