SIP Crossing Multiple Transports and Address Families
At the SIPit earlier this month, the multiparty testing uncovered a few implementations that assumed that since they only used SIP over IPv4 with protocols like TCP and UDP, they would never encounter an IPv6 addresses or tokens related to other transports like SCTP or DTLS in the SIP messages they receive. This is becoming more unlikely as more advanced transports are being deployed and as we go further into the IPv4 to IPv6
transition.
During rendezvous, a SIP request may traverse several SIP proxies. The RFC 3263 rules for locating the server at each hop can result in different transport protocols.
For example:

The Via stack and the Record-Route stack that are created as the message is forwarded will contain tokens and addresses from each of the traversed networks. Here’s what the Via and Record-Route header fields from the last message in the diagram might look like:
Via: SIP/2.0/UDP 192.0.2.1;received=198.51.100.15;rport=55021;branch=z9hG4bK8h23i5
Via: SIP/2.0/TLS proxy1.example.net;received=[2001:db8::2:1];branch=z9hG4bK3udn3z13
Via: SIP/2.0/SCTP proxy2.example.net;received=198.51.100.18;branch=z9hG4bK23sd093n42
Via: SIP/2.0/UDP proxy3.example.net;branch=z9hG4bK3s09ujnsnnen3
Record-Route: <sip:proxy1udp.example.net;lr>
Record-Route: <sips:proxy1tls.example.net;lr>
Record-Route: <sips:proxy2tls.example.net;lr>
Record-Route: <sip:proxy2sctp.example.net;lr>
Record-Route: <sip:proxy3sctp.example.net;lr>
Record-Route: <sip:proxy3udp.example.net;lr>
Note the double-record-route technique used by the proxies. For more information, see RFC 5658.
Now, these endpoints don’t need to be able to parse these tokens and addresses, at least not to the level of understanding their internal structure – they just need to be able to preserve them, following the requirements in the standards for including them in subsequent messages. This is where a few implementations ran into trouble – resulting in errors from failed parses of information they didn’t need in the first place. For instance, some IPv4-only endpoints assumed they would never see IPv6 addresses in the messages they received, so they dropped the incoming message above as malformed when parsing across the [2001:db8::2:1] address in the second Via header field value. These implementations didn’t really need to parse the value at all. They only need to reflect it, unchanged, in any response they send to the request. Following Postel’s Maxim in this case would result in higher levels of interoperability.
An earlier article went deeper into how RFC3263′s requirements provide for switching between transports like UDP, TCP, and SCTP at each hop. One thing that RFC doesn’t specify well is when to use IPv6 or IPv4 when both are available. As IPv6 becomes more available, dual-stack hosts (those able to use IPv6 and IPv4 at the same time) will encounter usability conditions that change over time. As a new IPv6 path is formed between endpoints, configuration and optimization changes may lead to IPv6 significantly outperforming IPv4 early in a given day, but not work as well (if at all) later that afternoon. How does a host choose which address family to use when it needs a new connection for a request?
Work is ongoing in the IETF to provide an algorithm answer that question. The current working document focuses on TCP and uses a weighting parameter, P, that affects what order the different address families are tried and how long to delay before trying the other family.
When P is 0, both families are tried simultaneously, each starting with the A or AAAA DNS lookup, followed by a TCP connection attempt. Whichever connects successfully first causes P to be adjusted in the direction that favors the quicker family. Positive values of P favor IPv6, negative favor IPv4. The size of the adjustments depend on the several factors, including whether the quickest family was the one currently favored.

When P is non-zero, the attempt to use the second family is delayed by 10*abs(P) milliseconds.
In all cases, when the attempts using both families succeed, the connection that was established first is kept. The subsequent connection is reset.
These ideas are still being refined – the current working draft anticipates that algorithm will be adjusted before it is proposed as a standard. For instance, there may need to be more clarity around which address family to issue the DNS queries over. There is also work proposed to specify what to do when the choices are richer than TCP over IPv6 vs. TCP over IPv4.


