]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
rtp_engine: Allow more than 32 dynamic payload types. 80/3680/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 13:44:26 +0000 (08:44 -0500)
Since adding all remaining rates of Signed Linear (ASTERISK-24274), SILK
(Gerrit 3136) and Codec 2 (ASTERISK-26217), no RTP Payload Type is left in the
dynamic range (96-127). RFC 3551 section 3 allows to reassign other ranges.
Consequently, when the dynamic range is exhausted, this change utilizes payload
types in the range between 35 and 63 giving room for another 29 payload types.

ASTERISK-26311 #close

Change-Id: I7bc96ab764bc30098a178b841cbf7146f9d64964

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 f4c5148a74e09bea920f7ee0ff820667360111c8..2131fee3ca8e0bbdeac95641d4be835e5c42a779 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -49,6 +49,15 @@ cel_radius
  * To fix a memory leak the syslog channel is now empty if it has not been set
    and used by a syslog channel in the logger.
 
+RTP
+------------------
+ * New setting "rtp_pt_dynamic = 35" in asterisk.conf:
+   Normally the Dynamic RTP Payload Type numbers are 96-127, which allow just 32
+   formats. To avoid the message "No Dynamic RTP mapping available", the range
+   was changed to 35-63,96-127. This is allowed by RFC 3551 section 3. However,
+   when you use more than 32 formats and calls are not accepted by a remote
+   implementation, please report this and go back to rtp_pt_dynamic = 96.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 14.1.0 to Asterisk 14.2.0 ----------
 ------------------------------------------------------------------------------
index 6d6d2f0bb137c4ea5129c1b82287c0e9de7deda4..e13a944b06ac029aae04e4a1fbd4b9f73326703b 100644 (file)
@@ -97,6 +97,14 @@ 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 = 35           ; Normally the Dynamic RTP Payload Type numbers
+                               ; are 96-127, which allow just 32 formats. The
+                               ; starting point 35 enables the range 35-63 and
+                               ; allows 29 additional formats. When you use
+                               ; more than 32 formats in the dynamic range and
+                               ; calls are not accepted by a remote
+                               ; implementation, please report this and go
+                               ; back to value 96.
 
 ; Changing the following lines may compromise your security.
 ;[files]
index e2709f9188f0b3362d18146bfbaf37e38d474626..345bacf6c58de95173464ce80f5b0c9bd0bb1fde 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 a40472e9d5e418a75f080b21191e020522794e67..017bb7b7acd19a4470d48076e58ff8adea893903 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 56fc107dba07332dc5d2d25919367ea7daf0bf5a..be6c7cc3242c72b8ba767b46daeef2c9efd25d10 100644 (file)
@@ -248,6 +248,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/format_cache.h"
 #include "asterisk/media_cache.h"
 #include "asterisk/astdb.h"
+#include "asterisk/options.h"
 
 #include "../defaults.h"
 
@@ -336,6 +337,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;
 
 /*! @} */
 
@@ -599,6 +601,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");
@@ -3464,6 +3479,7 @@ static void ast_readconfig(void)
 
        /* Set default value */
        option_dtmfminduration = AST_MIN_DTMF_DURATION;
+       ast_option_rtpptdynamic = 35;
 
        /* init with buildtime config */
        ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
@@ -3619,6 +3635,11 @@ 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,
+                                     &ast_option_rtpptdynamic, 0, AST_RTP_PT_FIRST_DYNAMIC);
                } else if (!strcasecmp(v->name, "maxcalls")) {
                        if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
                                ast_option_maxcalls = 0;
index c9d228c5677f6cfc688fcc79b8eacea14123c029..4fc1414f0089a93280adc5705d1b6bfcc55460b6 100644 (file)
 
 #include "asterisk.h"
 
-#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;
@@ -2301,6 +2314,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",