====== Random SIP test bits ====== I do a fair bit of SIP interoperability testing and testing other UA devices for compliance before offering them to customers. As such, i'm slowly building up a list of edge cases that are often overlooked when developers write SIP stacks and TU's. ===== PRACK ===== * A device MUST reject a request if it contains Require: 100rel but is not willing to send provisional responses reliably. This includes when performing a delayed offer INVITE. ===== Parser Stuff ===== * URI Parsing: transport-param, user-param, method-param, ttl-param and maddr-param MUST have a value, and it can be a token. other-param is not a token, and as so for example transport=ac% is correct according to the ABNF, however x-unknown-header=ac% isn't as '%' indicates an escaped value instead - urgh! ===== Authentication Stuff ===== * UAC retries when getting a stale=true * Doesn't kabopom on unknown algo oir missing parameters ===== Transaction Stuff ===== * ACK to an IST that has not yet sent a response must ignore, not b0rk. * re-transmit should result in response being sent to value in sent-by/received/rport, not originator of the retransmit. * transaction timers don't start until a transaction is created, they do NOT include the time it takes to do DNS processing. ===== TU Stuff ===== * Ensure device checks response to a dialog creating request checks the CSeq in the response and doesn't just blindly ignore it. * a reINVITE that gets challenged must re-send the reINVITE correctly WITHIN the dialog. * Fork, then one leg sends a 401/407 after a provisional - ensure the response actual gets processed and new request sent out. * Ensure receiving an unknown target dialog identifier returns 481 rather than create new session when receiving an INVITE. If it is not, then a UAC that just blindly follows 302 requests within a dialog could send an INVITE to a UAS that trusts it, and process the INVITE as a new request. Only an issue where the UAS behaves differently with requests from trusted UACs (arguably this is the fault of the UAC for just blindly following the 302, however, RFC 3261 does state that requests with target dialog id should only be resumed if the device is **sure** it is a local ID, wether crashed or not). * Ensure 30x responses without contact header doesn't barf. * Any URI scheme is allowed almost anywhere a sip/sips/tel URI is - especially mailto and http URI's in 3xx responses. * Check a request that loops back to the same UAS processes the first request, but any further ones with the same tag/callid/cseq are rejected (8.2.2.2) * Ensure an ICT does not require a 487 after a provisioanl resposne when cancelled - should time out after T1 * 64. (9.1) * (NOTE: concenus is still out on this one - you can optionally just ignore a 3xx response - see draft-dialogusage) Ensure 3xx to in-dialog request is followed - although there is a bug open about it, current spec allows. (But what happens to dialog targets?) * Multiple requests in a dialog can not be outstanding due to CSeq ordering unless the UAC can handle 500 responses to re-send. e.g, (in-dialog) - reINVITE followed immediatly by a MESSAGE. Unless the re-INVITE receives a provisional before the MESSAGE is sent, there is the possibility of the MESSAGE arriving first at the UAS, and thus the re-INVITE arriving with a lower CSeq - which would cause a 500 response. * Allow, Supported, and Accept in a provisional INVITE resposne are only valid for as long as the dialog is in an early state. * 200 to INVITE with unsupported offer must respond with ACK with valid SDP answer, followed by a BYE, not b0rk. * 200 to INVITE with unsupported answer (i.e, broken answer - no supported codecs) should respond with ACK, followed by a BYE, not b0rk, or possibly just ignore it and hope a fork will cause a more sensible answer. * INVITE without SDP, 200 OK with SDP, ACK with no SDP (no content at all, or 0 byte SDP), or unsupport, broken, or invalid content-type must result in a BYE, not a b0rk. Same with MESSAGE followed by re-INVITE (or any other method). Note: This could happen when UAC sends BYE that crosses a 2xx response - the invite session must be immediatly terminated, so app might not store the SDP to use for an answer in it. There are probably buggy implementations trying to handle this correctly in the INVITE -> 18x/sdp -> PRACK/sdp -> 200[prack] -> BYE -> 2xx[inv] edge case where the PRACK contains the SDP answer. * ACK must come from the same transport the non-200OK was received on. * re-INVITE's can take a long time - the user may be asked if they want to accept the session modifications. * re-INVITE resposne with 491 followed by immediate BYE must not b0rk the client * INVITE -> 401 [www-auth + to tag] -> INVITE [must not contain to tag] * Ensure to tags in responses to INVITE is truly random on a per device basis (but must be consistant if the UAS is stateless). Forking to different devices from the same vendor might cause problems otherwise when we get a tag collision. * If a UAC was ever to fork an INVITE itself, it must handle different branches returning 200 OK without a tog tag correctly (RFC 2543 edge case where INVITE arrives at UAS with only a single via branch), or handle it when the UAC gets 200 OK's with collisions * An INVITE generated by a UA after receiving an out of dialog REFER should NOT contain a to tag - and certianly not the one from the REFER's from tag * Overlapped in-dialog requests must handle CSeq correctly when dealing with 401/407 or retry responses * CANCEL must be sent to the same place as the INVITE was if doing RFC 3263 procedures * Do not send CANCEL before we receive at least one provisional resposne on a branch * Ensure a UAS that does not do request merging handles cancelling just one branch without cancelling the other. * UAC View: INVITE, 200[d1], 200[d2], ACK[d1], ACK[d2], BYE[d2], RT:200[d1], RT:200[d2]. RT:200[d1] and RT:200[d2] MUST be ACK'ed, and contain the correct to/from headers per the 200 which is being retransmitted. * UAC View: >INVITE[t1], <200[t1], >ACK[for t1 200], >INVITE[t2], <491[[t2], <200[t2] -- i.e, when re-INVITE is received by UAS before the ACK. * UAS Handle receiving BYE after sending 2xx but before ACK correctly. Totally legal due to UAC being allowed to send BYE on early dialogs. * UAC handled receiving a provisional on the same branch (and to tag) a 2xx has already generated should NOT cause ringing!! * UAS must handle receiveing a re-transmitted INVITE for 64 * T1 seconds after the 2xx has been sent * UAS correctly handle edge case where an INVITE is retransmitted but delayed, and arrives at the UAS after an ACK has already been received (for example, due to a routing change somewhere). * A 2xx ACK should include & process Max-Forwards as normal