Bugs and annoyances
From VoIPER
Annoyances
To fix
- The transaction mapping is not tied to a particular transaction and as a result if a late update of a transaction occurs it can effect the processing of a later transaction resulting in that transaction being reported as invalid
- One way to prevent this would be to somehow notifiy the transaction manager when the previous transaction has finished and returned (probably in the INCOMPLETE stage) and delete the transaction so that it won't be put on the update queue if a new response arrives. The problem with this though is that we should acknowledge any requests that arrive that need such an ACK and deleting the transaction like this will mean we can't.
- A better solution would be some way of telling sip_agent.py what transaction it was we were interested in processing with the given dictionary
Fixed
- After a transaction is complete there may still be requests on the output queue because duplicate requests from the target will result in duplicates on the queue and only one will be consumed by sip_agent. The queue should be cleared after every transaction.
- FIX - The queue is now flushed after every transaction. The cause for this was verified as repeated pushing of the same transaction to the output queue when duplicate messages arrive. e.g two 100 Trying responses would result in an extra request being left on the queue unless the transaction description specifically asks for two 100 Trying responses.....which it won't
- Due to the same behaviour that caused the previous issue it is possible for a transaction to fail because it moves from a valid state (as defined by the transaction dictionary) to the next state before the sip_agent gets a chance to process the initial response. For example, if a 100 Trying is quickly followed by a 486 Busy Here the sip_agent may not get the transaction until the 486 Busy Here has been appended but it will still be expecting the transaction to only have progressed as far as 486 Busy Here unless the 486 Busy here is described in the transaction dictionary at the same level as the 100 Trying (which it shouldn't be as a 486 Busy Here should never be expected before a 100 Trying)
- FIX - If, by the time we get around to processing the transaction it has moved into an invalid and unexpected state we return T_INVALID_STATE which indicates the target device has done something it shouldn't have or that our transaction description was incorrect
- It is possible that if two requests arrive in quick succession from the target the second request will effectively cloak the first and sip_agent.py will not see it. This is because sip_agent.py only deals with the last request to arrive so if two arrive before it gets a chance to process the first then the first is effectively lost. This is fine if an informational message is hidden by a final response but not if a final response is hidden by an informational message.
- Section 17.2.1 of the SIP RFC describes how the processing of an INVITE transaction should occur with respect to what needs a response and what doesn't and has a handy state diagram.
- 1XX responses update the state of the transaction and are informational. The don't require any response though and can't move the transaction into a final state
- 2XX response terminates the transaction/initiates the talk-y part and requires an ACK response. This ACK is technically part of a its own transaction.
- 3XX to 6XX responses complete the transaction and require an ACK in confirmation
- FIX - A copy of the object is put on the update queue instead of the actual object itself. The initial object is mutable so the cloaking occured as a result. As a deep copy of objects are now used this is no longer an issue.