Your new SIP proxy is up and running. You are successfully handling most NAT issues. You have read about many new interesting things, nonetheless you are happy to close this chapter for a while. Keepalives, STUN, Mediaproxy: you suffered a lot. You learned a lot. But right now, finally everything seems to run fine.
Time to sit back and relax? Probably not. Sooner or later you'll stumble over the next fustrating issue: fragmented UDP packets. While one might argue that SIP packets are allowed to be 64 kBytes large and fragmentation has been part of IP since it's very early days, daily practice teaches us that we are definitively not living in the same perfect world as RFC3261 authors seem to have lived in.
We are living in a bad world
There are lots of devices out there still unable to handle fragmented UDP packets. Regardless of whether this might be a braindead router, firewall or SIP component: your customer doesn't care. It could be the fault of his router, your SIP peer - or even the bad weather. He expects VoIP to work as reliable as his traditional phone: if the cable is attached and some lights are blinking, it has to work - the rest is your problem.
When asking for help you'll often hear the suggestion to use TCP. While such suggestions are correct, it is not that easy as it might seem. NAT handling for TCP works different than it does for UDP. TCP will add more load to your proxy. Switch from UDP to TCP within a single call makes no fun. So once again: sit down, learn and study. And even that would not help if you have to deal with clients that speak nothing but UDP.
Let's break the rules!
Game over? Not yet. If your client has a braindead router, disabling a few SIP codecs in it's user agent usually helps. And for all the other UDP fragmentation issues I'd like to show you how you could reduce the size of your SIP packets with your proxy. Some of the tricks you'll learn are not operations a proxy should do. At least not, if you're striclty following the rules. If you care, stop reading here.
You don't? Welcome to the club! Sometimes we are required to break the rules. To be honest, I like to break rules. Breaking rules makes fun! So let's start. SIP provides many informational headers, useful for different purposes - but not essential. OpenSIPS provides the textops module, and as a first step you could get rid of such headers by doing as follows:
if(is_present_hf("User-Agent"))
{
remove_hf("User-Agent");
}
Other candidates for removal you'll find in the wild: Server, Warning, P-Hint, Date - and more. Before applying such manipulations please make sure that you REALLY understood what this server is used for - and what implications it could have, if you remove them.
For packets going to your PSTN gateway(s), there are probably even more headers you could remove, such as Accept, Accept-Encoding, Allow-Events: just rip off anyhing without use for your gateway.
Your packets already got smaller? Great! But there is even more we can do! As you probably noticed, the large packets are those carrying an SDP body. So why not also try to make our SDP body smaller?
With OpenSIPS 1.6 there have been added some very cool codec-handling functions. Let me show you an example:
if (codec_exists("Speex"))
{
codec_delete("Speex");
}
You better should not do so for all of your packets, but you can do such replacements if you are sure that the destination does not support a specific codec. Many PSTN gateways do not speak Speex, iLBC, H261, H263, H264, Theora and others - so why not remove them?
But you can go even farther: let's assume your PST gateway speaks G.711 (A-law and µ-law), G.729, G.723 and G.726 variants, G.711 and G.729 are your preferred codecs. So if an announcement already contains one of them - why not rip off for example all those G.726 variants (and the related RTP-maps) some clients put in their SDP? Let me show you another example:
if (codec_exists("PCMU") || codec_exists("PCMA")
|| codec_exists("G729"))
{
if (codec_exists_re("^G726-\d+$"))
{
codec_delete_re("^G726-\d+$");
}
}
I'm using the regular expression variant in this example, to avoid multiple calls for each G.726 variant (G726-16, -24, -32...) a client might announce. By the way, those functions derived from a feature request I posted some time ago
If you feel adventurous you could also try to remove rtpmaps for well known payload numbers. That's a little bit risky, and I'm not sure whether it could cause some harm - at least in my tests it didn't:
if(has_body("application/sdp"))
{
replace_body("^a=rtpmap:0 PCMU/8000\r\n", "");
replace_body("^a=rtpmap:8 PCMA/8000\r\n", "");
}
Compact SIP headers
You want to go even farther? The next thing I'd try would be to replace SIP header names with their short/compact variant. Replacing From (f), To (t), Via (v), Contact (m), Call-ID (i), Content-Type (c) and Content-Length (l) would give us 43 more bytes. However, I never did so - some OpenSIPS functions could react allergic if all those headers get modified by textops. But I could be wrong: be careful, try it out - and please let me know the results!
That's all for now, I'd be glad if this was helpful to someone. And now: please try it out and have fun!