]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
rtp_engine: Allow more than 32 dynamic payload types. 81/3681/10
authorAlexander Traud <pabstraud@compuserve.com>
Tue, 13 Sep 2016 09:08:34 +0000 (11:08 +0200)
committerGeorge Joseph <gjoseph@digium.com>
Wed, 2 Nov 2016 14:47:55 +0000 (09:47 -0500)
The dynamic range (96-127) allows 32 RTP Payload Types. RFC 3551 section 3
allows to reassign other ranges. Consequently, when the dynamic range is
exhausted, you can go for "rtp_pt_dynamic = 35" (or 0) in asterisk.conf. This
enables the range 35-63 (or 0-63) giving room for another 29 (or 64) payload
types.

ASTERISK-26311 #close

Change-Id: I7bc96ab764bc30098a178b841cbf7146f9d64964
(cherry picked from commit 9ac53877f688c06acaa7c377f15da8770e4ee88b)

CHANGES
configs/samples/asterisk.conf.sample
include/asterisk/options.h
include/asterisk/rtp_engine.h
main/asterisk.c
main/rtp_engine.c

diff --git a/CHANGES b/CHANGES
index fbad201634ab65cccc3a7ab979b5fdf01233d40f..c550f3fda46a038ad4434a6ead93f35306b7a3be 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -39,6 +39,15 @@ CLI Commands
       Enable/disable debugging of an ARI application. When debugged, verbose
       information will be sent to the Asterisk CLI.
 
+RTP
+------------------
+ * New setting "rtp_pt_dynamic = 96" in asterisk.conf:
+   Normally the Dynamic RTP Payload Type numbers are 96-127, which allow 32
+   formats. When you use more and receive the message "No Dynamic RTP mapping
+   available", extend the dynamic range by going for rtp_pt_dynamic = 35 (or 0)
+   instead of 96. This allows 29 (or 64) additional formats. On default this is
+   disabled and the range is 96-127 because any number below might be rejected
+   by a remote implementation; although no such broken implementation is known.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.11.0 to Asterisk 13.12.0 ----------
index b0543d8033f94ff3afc4699d629559c728db530c..38cee250278aea1645ccdc57b0455f274be7569a 100644 (file)
@@ -96,6 +96,15 @@ documentation_language = en_US       ; Set the language you want documentation
                                ; This is currently is used by DUNDi and
                                ; Exchanging Device and Mailbox State
                                ; using protocols: XMPP, Corosync and PJSIP.
+;rtp_pt_dynamic = 96           ; Normally the Dynamic RTP Payload Type numbers
+                               ; are 96-127, which allow 32 formats. When you
+                               ; use more and receive the message "No Dynamic
+                               ; RTP mapping available", extend the dynamic
+                               ; range by going for 35 (or 0) instead of 96.
+                               ; This allows 29 (or 64) more formats. 96 is the
+                               ; default because any number below might be
+                               ; rejected by a remote implementation; although
+                               ; no such broken implementation is known, yet.
 
 ; Changing the following lines may compromise your security.
 ;[files]
index 0da5799aee6adca14d0dedd2a23c65f3d900ce95..21bd7a7047c95cb1da7f2dbf3ab0f025e8ae1b7a 100644 (file)
@@ -155,6 +155,8 @@ extern int dahdi_chan_name_len;
 
 extern int ast_language_is_prefix;
 
+extern unsigned int ast_option_rtpptdynamic;
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
index b7be5e8f4fa64de9cebbfc4d5e80b212aa82e414..24af05693cf2a25eb07ddf999806b07ad52d38de 100644 (file)
@@ -84,6 +84,9 @@ extern "C" {
 /*! First dynamic RTP payload type */
 #define AST_RTP_PT_FIRST_DYNAMIC 96
 
+/*! Last reassignable RTP payload type */
+#define AST_RTP_PT_LAST_REASSIGN 63
+
 /*! Maximum number of generations */
 #define AST_RED_MAX_GENERATION 5
 
index de00f4faa50132973b77997e4ea0a860b2d5189b..1c7a0e1885501e5e2446c72266e492ffd40a08ef 100644 (file)
@@ -249,6 +249,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/codec.h"
 #include "asterisk/format_cache.h"
 #include "asterisk/astdb.h"
+#include "asterisk/options.h"
 
 #include "../defaults.h"
 
@@ -331,6 +332,7 @@ unsigned int option_dtmfminduration;                /*!< Minimum duration of DTMF. */
 #if defined(HAVE_SYSINFO)
 long option_minmemfree;                                /*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
 #endif
+unsigned int ast_option_rtpptdynamic;
 
 /*! @} */
 
@@ -670,6 +672,19 @@ static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_c
        ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
        ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
 
+       if (ast_option_rtpptdynamic == AST_RTP_PT_LAST_REASSIGN) {
+               ast_cli(a->fd, "  RTP dynamic payload types:   %u,%u-%u\n",
+                       ast_option_rtpptdynamic,
+                       AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
+       } else if (ast_option_rtpptdynamic < AST_RTP_PT_LAST_REASSIGN) {
+               ast_cli(a->fd, "  RTP dynamic payload types:   %u-%u,%u-%u\n",
+                       ast_option_rtpptdynamic, AST_RTP_PT_LAST_REASSIGN,
+                       AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
+       } else {
+               ast_cli(a->fd, "  RTP dynamic payload types:   %u-%u\n",
+                       AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
+       }
+
        ast_cli(a->fd, "\n* Subsystems\n");
        ast_cli(a->fd, "  -------------\n");
        ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
@@ -3606,6 +3621,7 @@ static void ast_readconfig(void)
 
        /* Set default value */
        option_dtmfminduration = AST_MIN_DTMF_DURATION;
+       ast_option_rtpptdynamic = AST_RTP_PT_FIRST_DYNAMIC;
 
        if (ast_opt_override_config) {
                cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
@@ -3755,6 +3771,12 @@ static void ast_readconfig(void)
                        if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
                                option_dtmfminduration = AST_MIN_DTMF_DURATION;
                        }
+               /* http://www.iana.org/assignments/rtp-parameters
+                * RTP dynamic payload types start at 96 normally; extend down to 0 */
+               } else if (!strcasecmp(v->name, "rtp_pt_dynamic")) {
+                       ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE|PARSE_DEFAULT,
+                                     &ast_option_rtpptdynamic, AST_RTP_PT_FIRST_DYNAMIC,
+                                     0, AST_RTP_PT_LAST_REASSIGN);
                } else if (!strcasecmp(v->name, "maxcalls")) {
                        if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
                                ast_option_maxcalls = 0;
index 7a83783460310cd7d676bc5c246688bfd9b9b6f6..051253103226e74198a1bee6abd2dfa3bd8429c4 100644 (file)
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include <math.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/frame.h"
-#include "asterisk/module.h"
-#include "asterisk/rtp_engine.h"
+#include <math.h>                       /* for sqrt, MAX */
+#include <sched.h>                      /* for sched_yield */
+#include <sys/time.h>                   /* for timeval */
+#include <time.h>                       /* for time_t */
+
+#include "asterisk/_private.h"          /* for ast_rtp_engine_init prototype */
+#include "asterisk/astobj2.h"           /* for ao2_cleanup, ao2_ref, etc */
+#include "asterisk/channel.h"           /* for ast_channel_name, etc */
+#include "asterisk/codec.h"             /* for ast_codec_media_type2str, etc */
+#include "asterisk/format.h"            /* for ast_format_cmp, etc */
+#include "asterisk/format_cache.h"      /* for ast_format_adpcm, etc */
+#include "asterisk/format_cap.h"        /* for ast_format_cap_alloc, etc */
+#include "asterisk/json.h"              /* for ast_json_ref, etc */
+#include "asterisk/linkedlists.h"       /* for ast_rtp_engine::<anonymous>, etc */
+#include "asterisk/lock.h"              /* for ast_rwlock_unlock, etc */
+#include "asterisk/logger.h"            /* for ast_log, ast_debug, etc */
 #include "asterisk/manager.h"
-#include "asterisk/options.h"
-#include "asterisk/astobj2.h"
-#include "asterisk/pbx.h"
-#include "asterisk/translate.h"
-#include "asterisk/netsock2.h"
-#include "asterisk/_private.h"
-#include "asterisk/framehook.h"
-#include "asterisk/stasis.h"
-#include "asterisk/json.h"
-#include "asterisk/stasis_channels.h"
+#include "asterisk/module.h"            /* for ast_module_unref, etc */
+#include "asterisk/netsock2.h"          /* for ast_sockaddr_copy, etc */
+#include "asterisk/options.h"           /* for ast_option_rtpptdynamic */
+#include "asterisk/pbx.h"               /* for pbx_builtin_setvar_helper */
+#include "asterisk/res_srtp.h"          /* for ast_srtp_res */
+#include "asterisk/rtp_engine.h"        /* for ast_rtp_codecs, etc */
+#include "asterisk/stasis.h"            /* for stasis_message_data, etc */
+#include "asterisk/stasis_channels.h"   /* for ast_channel_stage_snapshot, etc */
+#include "asterisk/strings.h"           /* for ast_str_append, etc */
+#include "asterisk/time.h"              /* for ast_tvdiff_ms, ast_tvnow */
+#include "asterisk/translate.h"         /* for ast_translate_available_formats */
+#include "asterisk/utils.h"             /* for ast_free, ast_strdup, etc */
+#include "asterisk/vector.h"            /* for AST_VECTOR_GET, etc */
 
 struct ast_srtp_res *res_srtp = NULL;
 struct ast_srtp_policy_res *res_srtp_policy = NULL;
@@ -1796,6 +1809,48 @@ static void add_static_payload(int map, struct ast_format *format, int rtp_code)
                        }
                }
 
+               /* http://www.iana.org/assignments/rtp-parameters
+                * RFC 3551, Section 3: "[...] applications which need to define more
+                * than 32 dynamic payload types MAY bind codes below 96, in which case
+                * it is RECOMMENDED that unassigned payload type numbers be used
+                * first". Updated by RFC 5761, Section 4: "[...] values in the range
+                * 64-95 MUST NOT be used [to avoid conflicts with RTCP]". Summaries:
+                * https://tools.ietf.org/html/draft-roach-mmusic-unified-plan#section-3.2.1.2
+                * https://tools.ietf.org/html/draft-wu-avtcore-dynamic-pt-usage#section-3
+                */
+               if (map < 0) {
+                       for (x = MAX(ast_option_rtpptdynamic, 35); x <= AST_RTP_PT_LAST_REASSIGN; ++x) {
+                               if (!static_RTP_PT[x]) {
+                                       map = x;
+                                       break;
+                               }
+                       }
+               }
+               /* Yet, reusing mappings below 35 is not supported in Asterisk because
+                * when Compact Headers are activated, no rtpmap is send for those below
+                * 35. If you want to use 35 and below
+                * A) do not use Compact Headers,
+                * B) remove that code in chan_sip/res_pjsip, or
+                * C) add a flag that this RTP Payload Type got reassigned dynamically
+                *    and requires a rtpmap even with Compact Headers enabled.
+                */
+               if (map < 0) {
+                       for (x = MAX(ast_option_rtpptdynamic, 20); x < 35; ++x) {
+                               if (!static_RTP_PT[x]) {
+                                       map = x;
+                                       break;
+                               }
+                       }
+               }
+               if (map < 0) {
+                       for (x = MAX(ast_option_rtpptdynamic, 0); x < 20; ++x) {
+                               if (!static_RTP_PT[x]) {
+                                       map = x;
+                                       break;
+                               }
+                       }
+               }
+
                if (map < 0) {
                        if (format) {
                                ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n",