MPS sends CHANNEL_CLOSE more than once for a given channel
orinem opened this issue · comments
Describe the bug 🪲
MPS sends CHANNEL_CLOSE when closing a channel. It also sends it in response to a CHANNEL_CLOSE message. AMT sends a CHANNEL_CLOSE message in response to receiving a CHANNEL_CLOSE message, at which time, it could re-use the channel ID. MPS's second CHANNEL_CLOSE could then close the wrong channel.
- MPS sends CHANNEL_CLOSE for channel ID N
- AMT responds with CHANNEL_CLOSE for channel ID N; it considers the channel closed
- MPS sends CHANNEL_OPEN
- AMT processes the CHANNEL_OPEN and reuses channel ID N
- MPS processes the CHANNEL_CLOSE response and sends another CHANNEL_CLOSE for channel ID N, closing the wrong channel
- MPS tries to use channel ID N and gets errors
The order of 2 and 3 isn't critical.
To Reproduce 🪜
Steps to reproduce the behavior:
Using MPS with silly level logging.
From the Sample UI, reload the device page multiple times before it finishes filling all the fields. The sample UI should show no errors. If it does, check the MPS logs for errors and the order of SendChannelClose, CHANNEL_CLOSE and CHANNEL_OPEN_CONFIRMATION along with the channel numbers. This example was OK, channel 7 was closed and the channel opened was 0. The 'bad' SendChannelClose is in bold:
2022-11-23T01:27:11.304Z debug: end of request, closing channel
2022-11-23T01:27:11.304Z silly: MPS: SendChannelClose, 7
2022-11-23T01:27:11.305Z debug: end of request, closing channel
2022-11-23T01:27:11.307Z silly: MPS: SendChannelOpen
2022-11-23T01:27:11.309Z silly: MPS: CHANNEL_CLOSE 9, 7
2022-11-23T01:27:11.309Z silly: MPS: SendChannelClose, 7
2022-11-23T01:27:11.314Z silly: MPS: CHANNEL_OPEN_CONFIRMATION, 10, 0, 499
Expected behavior
There should be no errors and SendChannelClose should only be called once.
AMT Device (please complete the following information): 🖥️
- OS: N/A
- AMT Version: 14..16
- AMT Configuration Mode: N/A
- Network Configuration: N/A
Service Deployment (please complete the following information): ⛈️
- Deployment Type: Docker
- Node Version: MPS
- Component & Version: 2.6.0
Additional context
To quote the port forwarding reference manual:
3.3.2.4 APF_ChannelClose
When a party wishes to terminate a channel, it sends the APF_ChannelClose message. The receiving party must send back an APF_ChannelClose message unless it has already sent this message for the same channel. The channel is considered closed for a party when it has both sent and received APF_ChannelClose. The party may then reuse the channel number.
This wouldn't have been a problem if the protocol had used the sender/recipient pair to close a channel since in our case at least, it's unique.
Fix is to add a 'closeSent' flag to CIRAChannel, set it when sending CHANNEL_CLOSE and don't send CHANNEL_CLOSE on receipt of a CHANNEL_CLOSE if the flag is set.