Summary:ASTERISK-16794: Early bind of UDPTL ports can create a DoS condition
Reporter:Elazar Broad (ebroad)Labels:
Date Opened:2010-10-12 10:11:47Date Closed:2012-01-16 13:15:54.000-0600
Versions:Frequency of
is related toASTERISK-16698 large memory consumption of udptl.c module
Environment:Attachments:( 0) chan_sip.c.patch-issue18121
( 1) udptl_20120113.diff
Description:The issue is that we bind udptl ports early on in the game, in sip_alloc(), which can exhaust the port limit in udptl.conf quite quickly, when a flood of invites from a (rogue) scanner with a udptl sdp payload is processed by Asterisk. Even though the invite is ultimately challenged and/or rejected, the port is bound, and is not released until the 32 second retry before destroy window is up, and once all the ports are bound, service will be denied to legitimate calls; bear in mind we don't do this with voice, video and text ports.


The simplest way to reproduce this on a consistent basis is with sipp(in this case 3.1.1 on Windows), and run simply:

sipp <host>

Watching the Asterisk message log, and netstat confirm the issue.  
Comments:By: Loic Didelot (voipgate) 2010-10-14 11:12:47

I confirm this issue on asterisk 1.8 rc3.

By: Elazar Broad (ebroad) 2010-10-14 14:54:25

I am wondering if we can take this(http://www.asterisk.org/doxygen/trunk/chan__sip_8c-source.html#l07200) out of sip_alloc() altogether, handle_request_invite() has the exact same code-block(http://www.asterisk.org/doxygen/trunk/chan__sip_8c-source.html#l21320).

By: Stefan Schmidt (schmidts) 2010-10-14 15:28:10

i think this could be a problem on a reinvite situation if udptl was not created earlier on a pvt but i am not sure if this could ever happens. Only if the SIP_PAGE2_T38SUPPORT flag is changed after the invite is processed and before a reinvite is received.

By: Elazar Broad (ebroad) 2010-10-14 15:35:31

In testing, taking out the block resolves the issue when testing with sipp. I need to test further and make sure t.38 is still working.

By: Stefan Schmidt (schmidts) 2010-10-14 15:53:28

btw nice catch ;)

By: Elazar Broad (ebroad) 2010-10-14 15:56:29

Thanks :)

By: Stefan Schmidt (schmidts) 2010-10-15 05:14:29

i have runnend into this not only on trunk this is also possible in 1.6.2 but the solution is the same.
just remove the udptl part of sip_alloc solves this problem as well. i hope your t38 tests will work!

By: Stefan Schmidt (schmidts) 2010-10-18 02:10:01

i have attached a patch and set this to review cause i think its nearly a blocker to 1.8.0

By: Rob Gagnon (rgagnon) 2011-01-28 01:24:21.000-0600

Under this patch does not fix anything.  The early binding of the port does not appear to harm anything.  It just removes a duplicate piece of code.  Lingering session-timers, and T38 timer reference to the dialog appear to be what stops the ports from being disconnected.

See related issue ASTERISK-1701255 for a patch that resolves these things.

By: Walter Doekes (wdoekes) 2011-03-18 11:35:02

In all rtp allocation is done in if(..need_rtp)-block.

Either everthing should be allocated on an if-needed basis, or nothing. It makes no sense to me to only delay T38 allocation.

I'd rather see a patch that delays all allocation, or -- if that's undesirable/impossible -- one that closes unneeded ports when the dialog is established.

By: Rob Gagnon (rgagnon) 2011-03-18 11:37:04

ASTERISK-16023 also resolves this for T38 by not early binding.  Testing of this has shown speed improvements

By: Matt Jordan (mjordan) 2012-01-13 17:50:59.162-0600

I've attached a patch that moves the initialization of the udptl object until later in the lifetime of a dialog.  In current 1.8, we create the udptl object in sip_alloc, handle_request_invite, and create_addr_from_peer - two of these, at least, nearly guarantee that any sip_pvt associated with a peer that support T.38 will have a udptl object assigned to it.  This patch only creates the udptl object if we (a) receive a media invite that specifies image as a supported media, or (b) chan_sip receives a T38 control frame.

I've passed this through the udptl tests in the Asterisk testsuite, and will be testing it with the T.38 gateway tests in Asterisk 10 when I create a patch for that version.  That being said, given the complexities of media negotiation, this patch needs some additional testing.

Walter: I definitely agree we need to think about how we handle media / media negotiation as part of a larger effort - if nothing else, finding all the locations (and ways in which you can mess up the media getting kicked off correctly) convinced me of that.  I'd view this as a small step moving towards that.

[edit] - by the way, the original patch on this issue will cause problems with passing T.38 frames from res_fax up to chan_sip in the current 1.8 patch.  Simply removing the udptl creation from sip_alloc runs the risk that the associated SIP channel object doesn't get its udptl file descriptor.

By: Elazar Broad (ebroad) 2012-01-16 13:13:41.048-0600

Thanks for reviving this. I haven't looked at the code in a while, however, I took a quick look at the patch you posted, and it should fix the issue, albeit more elegantly. I should have some time later in the week to get back into this and test it out.


By: Matt Jordan (mjordan) 2012-01-16 13:16:40.318-0600

Thanks Elazar - I went ahead and did the commit, but I'd definitely appreciate some advance testing of the patch before 1.8.10 / 10.2 get put into RCs.