C. Recommendations to NAT+SIP-friendly vendors ------------------------------------------ Recommendation for NATs: -- implement a non-symmetric NAT policy, e.g., full-cone (see RFC3489) -- that's a requirement for succesful STUN operation (providers don't need to use RTP relay) -- keep NAT bindings sufficiently long -- 2 minutes is a reasonable value; shorter values are likely to result in unreachability of natted devices from outside -- allow natted data between two devices on the private part to be exchanged over the translated public IP address -- STUN will otherwise fail for communication between devices behind the same NAT -- preserve source port numbers unless multiple natted devices compete for the same IP address -- that allows some SIP phones to get even over symmetric NATs without help of RTP relay -- use a stateless binding allocation algorithm -- that keeps phones working even if NAT bindings disapper due to reboot or other reason -- allow manual provisioning of NAT translations This is NAT-friendly behaviour we recommend to implement in SIP telephones: 1) detect type of NAT using STUN 2) if NAT non-symmetric, use STUN 3) is symmetric PP NAT, use PP method (this method should be optional, as PP methods may fail due to port number collisions in networks with many devices); advertise comedia active mode. 4) if symmetric not-PP, fall back to private IP addresses and advertise symmetric support comedia; (other party will honor comedia or an RTP relay in the middle will help out) We mandate also the following NAT-friendly features: - Be symmetric. Send both signaling and media from IP:port where you receive; always advertise symmetric signaling using the rport Via parameter (RFC3581). Advertise symmetric active mode in SDP using comedia support if behind a symmetric NAT. - If behind any type of NAT, send dummy packets (4-byte packets are typically used) each 30 seconds to SIP proxy server to keep NAT bindings alive. - Send few primer packets in beginning of media session even if silence detection is turned on. That helps to traverse some more restrictive NATs and open up RTP relay. - Allow configuration of media port number range. That's helpful in cases of manual NAT provisioning and firewall traversal. - Have an option to randomize SIP source port numbers to avoid conflicts in symmetric-PP case. This must be optional since in some firewall scenarios, a fixed port number is desirable. - Randomize STUN source port numbers for nat type detection to make sure that STUN NAT-type test yields proper value even on quick phone reboot. Otherwise, the tests may fail to detect symmetric NAT and fail to traverse it consequently. We also recommend telephones describe detected type of NAT in a REGISTER header field. There is no standard for doing so today, but this piece of information is extremely helpful in troubleshooting. So a working call-flow for a STUN-enabled phone is as follows: on boot: a) use STUN to detect type of NAT - test I to primary STUN server if MAPPED_ADDRESS same as phone's address -> no NAT, done - test II to primary STUN server with change_IP,change_port if reply received -- it is full cone, begin using STUN address; done - test I to STUN server as in CHANGED_ADDRESS from the first test I if MAPPED_ADDRESS different from MAPPED_ADDRESS in test 1, it is a symmetric NAT; give up on use of STUN address; done; otherwise, it is restrictive or port-restrictive: begin using STUN address, done; - test III to primary STUN server with change_port can be imho skipped, I'm not aware of a practical difference between restrictive and port-restrictive NATs so at this point of time, the phone knows what kind of NAT it is behind and which IP address to use. It is reasonable to run the STUN NAT-type detection test from a random number. That avoids false NAT-type assertion on phone reboot which may fail to detect symmetric NATs. (The reason is that before reboot the second run of test I opened up a binding for secondary STUN server; after the reboot, test II will result in received replies and consequently a mistaken NAT type assertion. ) b) if the phone operates in STUN mode (behind asymmetric NAT), learn external SIP address using a STUN binding query sent from phone's signaling port (which is at best random). c) REGISTER the phone; - as always, include rport parameter (RFC3581) in Via. Use of rport makes reply deliver less brittle during NAT instabilities. - if behind a NAT which is not symmetric, use the address:port pair learned in b) using STUN for Via and Contact. - otherwise (no NAT or symmetric NAT) proceed as if there was no STUN with phone's default IP address. d) if behind any type of NAT, keep NAT binding for signaling alive. send dummy keep-alive packet (BCP is four zero bytes) to SIP server every 30 seconds or so. An even better way is to generate STUN binding requests regularly. That's is more robust in that the phone can recognize changed NAT binding which occurred due to NAT reboot, forcible IP address change or other external interference. If a change to IP address or port is detected, the phone must re-REGISTER. Also, the keep-alive packet must be sent _after_ STUN reply is received to make sure that port-restrictive NATs permit packets coming from SIP server. e) if a call is initiated or received and the phone is behind a NAT which is not symmetric: - determine NAT binding for media. STUN test I is sufficient for this purpose. Alternatively, you can run this test periodically in advance to avoid an additional call-setup delay. Use the STUN-learned values in SDP. Print Contact and Via the same way like in step c). - send few primer packets even if silence detection turned on if a call is initiated or received and the phone is behind a NAT which is symmetric, advertise symmetric active mode in SDP using comedia support. Optionally, port-preserving NATs may be special-cased. A phone would have to detect such NATs and if so, use IP address as learned using STUN and port numbers as allocated locally.