Proxy Servers and Gateways. Summary
This page outlines how proxy servers and gateways are implemented as of 01/01/2022 in SR140. The outline is based on code investigation and testing. The corresponding Jira ticket: - BRKT-1269Getting issue details... STATUS
Configuration
There are 2 types of SIP intermediate entities in SR140 – (1) proxy servers and (2) gateways. They are very similar but operate differently. Both entities are configured in module section of call control file.
Proxy Servers
A set of proxy servers to use is configured by setting values to sip_proxy_server1, sip_proxy_server2 and so on up to sip_proxy_server10 (0-10 proxy servers allowed).
Gateways
A set of gateways to use is configured by setting values to sip_default_gateway (sets up the first gateway), and then sip_gateway2, sip_gateway3, and sip_gateway4 (0-4 gateways allowed).
NOTE. Gateways will not be used if registration servers are configured. It is also possible to set up registration servers in the same module section of the same call control file (using keys sip_registration_server_1, sip_registration_server_1 and so on). It is important that if at least one of them is set up, the gateways will NOT be used in this module. However, the proxy servers (if configured) WILL be used in REGISTER requests.
Maintaining Current Object in the Set
Proxy Servers
Initially, after proxy servers are read from call control file, they are placed in an array, and the first element of the array (at index 0) becomes the current proxy server. After that, the current proxy server is used for making outgoing call INVITEs.
There are only 2 cases of outgoing call failure that lead to current proxy server index needs to be adjusted. First, when the SIP stack timed out waiting for response to the outgoing INVITE. Second, when there was a network loss detected while waiting for response to the outgoing INVITE. Note that both cases are not characterized by any kind of SIP response received, but, contrary to that, by the absence of any SIP response, by something happened at a lower level, like network disconnect or proxy server down. If those outcomes happen, the current proxy server index is adjusted. If it already points to the last proxy in the array, it returns to 0. Otherwise, it is just increased to point to the next proxy in array.
Gateways
Initially, after gateways are read from call control file, they are placed in an array. The value of sip_default_gateway key becomes the first element of the array (at index 0) and it becomes the current gateway as well. After that, the current gateway is used for making outgoing call INVITEs.
If there is only one (default) gateway, it is always the current gateway.
If there is more than 1 gateway in the array (and only there), the separate thread (we’ll call it options thread) repeatedly sending OPTIONS requests to all gateways will start and that thread will be responsible for maintaining the current gateway index.
The options thread starts by sending one OPTIONS request to each gateway. If the response of 200 OK received from a gateway, that gate is marked as being “UP”. If the SIP response is not a 200 OK or there is no response at all (configurable time out), the gateway is marked as “DOWN”. That makes the states for some (configured) time interval after which it’s time to send OPTIONS again to refresh each gateway status. This continues until the module runs. So, each gateway in the array of gateways is UP or DOWN at any time. Then at any time the gateway with the lowest index in the array which is UP is considered the current gateway.
Automatic retry of outgoing call with the next proxy
Related to the 2 specific cases of failure causing the adjustment of the current proxy server pointer, is automatic retry feature (Epic link: - BRKT-1246Getting issue details... STATUS ). If one of those cases happened with the outgoing INVITE, the current proxy server index will get adjusted as described. That, in turn, could increases the possibility for the same identical call would succeed this time because the current proxy pointer is adjusted. The new feature aims to retry in those cases as many times as needed, no more than once with each proxy, before returning control to the client. This feature is already implemented but didn’t make it to SR140 v.6.15. The way it is implemented now, it only considers proxy servers, not gateways as its design calls for explicitly controlling which proxy server is used in each retry. It is impossible to implement the same strategy with gateways since the current gateway is controlled by response to OPTIONS.
Usage with SIP requests
INVITE
Most important use of the intermediate entities is in outgoing call INVITEs. The way proxy servers and gateways are used for outgoing call INVITE is the same. It relies on the fact that “current” object pointer is maintained in each set. That current object is all that is needed when constructing INVITE for the outgoing call. Of two current objects, current proxy server has higher priority. Only if there are no proxy servers configured, the current gateway will be in use.
NOTE 1. That policy prioritizing current proxy server over current gateway makes the very existence of gateways obsolete if at least one proxy is configured. It seems safe to say that if at least one of proxy servers is set up, the gateways will never be used in this module INVITEs. Therefore, the gateways can be discarded earlier, when reading call control for the module, the same way they are discarded in case a registration server is encountered for this module.
NOTE 2. As it is implemented now, regardless of the existence of proxy servers, if there are more than 1 gateway configured, the options thread repeatedly sending OPTIONS requests to maintain current gateway (it was explained earlier) will start. However, as explained in NOTE 1 above, if at least one proxy is configured, the current gateway will never be used for outgoing calls. Therefore, the options thread activity results are waisted. Even if the current gateway is properly kept up to date by options thread, nobody is using the current gateway.
REGISTER
Only proxy servers are used for REGISTER requests. Gateways are never used for REGISTER. The proxy servers are used only if another configuration flag, sip_registration_proxied is set to true for this module in the call control file.
Registration and registration maintenance process is implemented in its own thread. The main loop of that thread waits for when it’s time to re-register and begins sending the REGISTER requests to registrars in turn. If proxy servers are not used for registration or there is just one single proxy server, then the REGISTER messages are sent to configured registrars in turn. If first registrar fails, next time the REGISTER message will be sent to the second and so on, making it a loop through available registrars. With more than one proxy servers, this main loop stays the same, but for each registrar the inner loop through all proxy servers is added. In other words, the main loop does not move to try the next registrar until it tries this current registrar with all proxies available in turn. If REGISTER failed for this registrar for all proxy servers, the loop would move to the next registrar and try that next registrar with all proxies in turn.
Summary
This is precisely how things work.
For proxy servers, they are regarded as having equal priority. Initially the current server is the server at index 0. The change of the current proxy server to the next one (failover) occurs only if no SIP response to our INVITE received. In more details, once the outgoing INVITE is sent (to one of proxy servers that happen to be “current”), there are 2 distinct outcomes. First outcome is that the SIP dialog continues by getting a SIP response from the remote side. If that’s the case, the current proxy server never change, regardless of the SIP response code. In other words, it seems like the proxy server is considered being in good shape if 2-way SIP dialog can be started through it. The second outcome is the opposite to the first. It is when there will be no response from the remote side (this can be either a timeout or lower level network failure). In this case the current proxy server is considered being in bad shape (down or inaccessible) and is changed to the next one (if there is more than one).
As for gateways, they have different priorities. The first in the list (the value of “sip_default_gateway”) is placed first in the list, and has highest priority, the second in list (value of “sip_gateway2”) has next highest priority, and so on. In that setup, an outgoing call INVITE will always use the highest priority gateway that is available (UP). All gateways in the list are constantly “queried” with OPTIONS requests in the background. It’s the outcome of OPTIONS request that cause a gateway to be marked UP or DOWN for a period of time until the next OPTIONS request is sent. The OPTIONS request outcomes can be of 3 types. First, same as for proxy servers, no SIP response. In this case the gateway is marked “DOWN”. Second, when one of special SIP response codes “503 Service Unavailable” or “505 Version Not Supported” received, the gateway is considered “DOWN” as well. Third, everything else - if and other SIP response to OPTIONS request received, the gateway is marked “UP”.
So, for proxy servers, they have equal priority, there is one “current” proxy at any time. Then if an outgoing INVITE sent to that current proxy does not get any SIP response, the current proxy index is moved and the new current proxy will be used next time.
And for gateways, they have priorities, there is no “current” gateway. Instead, at any time each gateway is known to be “UP” or “DOWN” (that is determined with background OPTIONS requests). Then an outgoing INVITE just uses the highest priority gateway which is “UP”. No failover ever happens as there is no concept of “current” gateway.