Asterisk - The Open Source Telephony Project  18.5.0
SIP TCP and TLS support
tcpfixes TCP implementation changes needed
Todo:

Fix TCP/TLS handling in dialplan, SRV records, transfers and much more

Save TCP/TLS sessions in registry If someone registers a SIPS uri, this forces us to set up a TLS connection back.

Add TCP/TLS information to function SIPPEER and CHANNEL function

If tcpenable=yes, we must open a TCP socket on the same address as the IP for UDP. The tcpbindaddr config option should only be used to open ADDITIONAL ports So we should propably go back to bindaddr= the default address to bind to. If tcpenable=yes, then bind this to both udp and TCP if tlsenable=yes, open TLS port (provided we also have cert) tcpbindaddr = extra address for additional TCP connections tlsbindaddr = extra address for additional TCP/TLS connections udpbindaddr = extra address for additional UDP connections These three options should take multiple IP/port pairs Note: Since opening additional listen sockets is a new feature we do not have today the XXXbindaddr options needs to be disabled until we have support for it

We need to test TCP sessions with SIP proxies and in regards to the SIP outbound specs.

;transport=tls was deprecated in RFC3261 and should not be used at all. See section 26.2.2.

Since we have had multidomain support in Asterisk for quite a while, we need to support multiple domains in our TLS implementation, meaning one socket and one cert per domain

Selection of transport for a request needs to be done after we've parsed all route headers, also considering outbound proxy options. First request: Outboundproxy, routes, (reg contact or URI. If URI doesn't have port: DNS naptr, srv, AAA) Intermediate requests: Outboundproxy(only when forced), routes, contact/uri DNS naptr support is crucial. A SIP uri might lead to a TLS connection. Also note that due to outbound proxy settings, a SIPS uri might have to be sent on UDP (not to recommend though)

Default transports are set to UDP, which cause the wrong behaviour when contacting remote devices directly from the dialplan. UDP is only a fallback if no other method works, in order to be compatible with RFC2543 (SIP/1.0) devices. For transactions that exceed the MTU (like INIVTE with video, audio and RTT) TCP should be preferred.

Todo:
re-evaluate the transport= setting in sip.conf. This is right now not well thought of. If a device in sip.conf contacts us via TCP, we should not switch transport, even if udp is the configured first transport.
Todo:
Be prepared for one outbound and another incoming socket per pvt. This applies specially to communication with other peers (proxies).
Todo:
If the message is smaller than the given Content-length, the request should get a 400 Bad request message. If it's a response, it should be dropped. (RFC 3261, Section 18.3)

When dialling unconfigured peers (with no port number) or devices in external domains NAPTR records MUST be consulted to find configured transport. If they are not found, SRV records for both TCP and UDP should be checked. If there's a record for TCP, use that. If there's no record for TCP, then use UDP as a last resort. If there's no SRV records,

Note
this only applies if there's no outbound proxy configured for the session. If an outbound proxy is configured, these procedures might apply for locating the proxy and determining the transport to use for communication with the proxy.
Other bugs to fix -—
__set_address_from_contact(const char *fullcontact, struct sockaddr_in *sin, int tcp)
  • sets TLS port as default for all TCP connections, unless other port is given in contact. parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
  • assumes that the contact the UA registers is using the same transport as the REGISTER request, which is a bad guess.
    • Does not save any information about TCP/TLS connected devices, which is a severe BUG, as discussed on the mailing list. get_destination(struct sip_pvt *p, struct sip_request *oreq)
  • Doesn't store the information that we got an incoming SIPS request in the channel, so that we can require a secure signalling path OUT of Asterisk (on SIP or IAX2). Possibly, the call should fail on in-secure signalling paths if there's no override in our configuration. At least, provide a channel variable in the dialplan. get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req)
  • As above, if we have a SIPS: uri in the refer-to header
  • Does not check transport in refer_to uri.