Some more technical challenges with SIP for our new SIP2SIM service...
We are acting like a SIP client, i.e. like a SIP phone, registering with a server or VoIP provider. This could a system in an office, e.g. asterisk based, or even using one of our FireBricks as an office PABX, but it could also be a commercial SIP/VoIP service that is designed to work with the likes of a snom phone.
To do this we have to not only comply with SIP specifications, but all of the quirks and security restrictions that VoIP providers have dreamt up.
We also have multiple call servers our end, and we want to keep it that way to allow us to scale up to more call servers. So we deliberately started with two servers (and a third test server) so we solve the problems we find as we go.
Balancing the load.
We split the SIMs that are registering between the call servers using a hash, and based on the currently in-user call servers. This keeps the registering server pretty consistent. When we change call servers we de-register SIMs and re-register from a different call server.
Asterisk losing registrations.
We seem to have a snag with asterisk that will see a new register and a de-register from previous call server, and may see them in that order and decide the client is no longer registered, even though the de-register does not match the previous register or even come from the same IP. This is asterisk being an arse, sorry, and we have yet to work out a sensible fix for this. It works on next registration, and obviously calls from the SIM work. We do maintenance rarely and will probably move to overnight changes to minimise the impact of this.
Asterisk boxes deciding to challenge.
We hit a snag with asterisk boxes, as they tell if they need to ask for credentials (challenge the registration or invite) based solely on IP. Well, the config takes a hostname and they look up just one IP for that hostname and check that. This means that we cannot send calls to a customer from one IP address for both authenticated (i.e. we expect to have the call/registration challenged) and non authenticated, such as calls we have for their service from the PSTN where they may simply trust our IPs and not take a user/pass.
To fix this we gave each server two IPs, one for authenticated messages and one for not (also two IPv6 addresses, obviously). This allows a distinct config for both types of INVITE message on asterisk. Messy, but works.
Register and call from different IP.
Incoming calls to the registered contact, and outgoing calls from a SIP, should ideally be quite independent things. There is no reason they need to come from the same IP address. They both have credentials that are challenged to confirm they are genuine.
However, it seems some VoIP services will not accept calls unless a registration has been made first, and then only accept calls from the same IP from which the REGISTRATION is made.
This means we now have to bounce calls to the call server that does the registration for the SIM in question before sending to the VoIP provider. Annoying, but works.
Providers editing the contact URL!
We send a contact that has a sip:user@ip part and an attribute ;line=xxxx as part of the contact URI. This is a simple and valid technique used by lots of devices. Some send ;instance=, and some send all sorts or extra tags in the URI. It is a way for the client to be sure that calls they receive are genuine (even if from a different IP to which the registration went).
Sadly, at least one provider strips this from the URI. Why? This is not a valid thing to do!!!
OK, so we have a work around, we now only register a contact as sip:user@host, where the host has a prefix and we use wildcard DNS to ensure that is the IP or our call server.
We did run in to a snag with one server expecting INVITEs from the IP that they resolve the contact host part to, and we were setting the wildcard URL to the main IP of our server not the IP that we use for authenticated requests. We have fixed that now, and we think we finally have a reliable way to register to a wide range of VoIP servers now.
Well, until the next snag!