diff --git a/CHANGES b/CHANGES index 0398781499b538b97d391227dfe34a02ecb31d27..45c964e98c4971440bd77ca2b8e21f23f5760200 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,17 @@ === ============================================================================== +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 13.23.0 to Asterisk 13.24.0 ---------- +------------------------------------------------------------------------------ + +res_rtp_asterisk +------------------ + * The existing strictrtp option in rtp.conf has a new choice availabe, called + 'seqno', which behaves the same way as setting strictrtp to 'yes', but will + ignore the time interval during learning so that bursts of packets can still + trigger learning our source. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.22.0 to Asterisk 13.23.0 ---------- ------------------------------------------------------------------------------ diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample index de9d59007c7e219c596c0fbb39ecca20f64475ed..26a70d2e16cc05fea59693df27f9172adc041780 100644 --- a/configs/samples/rtp.conf.sample +++ b/configs/samples/rtp.conf.sample @@ -31,6 +31,10 @@ rtpend=20000 ; seconds after starting learning mode. Once learning mode completes the ; current stream is locked in and cannot change until the next ; renegotiation. +; Valid options are "no" to disable strictrtp, "yes" to enable strictrtp, +; and "seqno", which does the same thing as strictrtp=yes, but only checks +; to make sure the sequence number is correct rather than checking the time +; interval as well. ; This option is enabled by default. ; strictrtp=yes ; diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index ad04e493e5eddcbc559c856b8048a177b5b9f67d..7b006cec9ded9056b2760a7406ae1772fc90db0a 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -149,6 +149,12 @@ enum strict_rtp_state { STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */ }; +enum strict_rtp_mode { + STRICT_RTP_NO = 0, /*! Don't adhere to any strict RTP rules */ + STRICT_RTP_YES, /*! Strict RTP that restricts packets based on time and sequence number */ + STRICT_RTP_SEQNO, /*! Strict RTP that restricts packets based on sequence number */ +}; + /*! * \brief Strict RTP learning timeout time in milliseconds * @@ -158,7 +164,7 @@ enum strict_rtp_state { */ #define STRICT_RTP_LEARN_TIMEOUT 5000 -#define DEFAULT_STRICT_RTP -1 /*!< Enabled */ +#define DEFAULT_STRICT_RTP STRICT_RTP_YES /*!< Enabled by default */ #define DEFAULT_ICESUPPORT 1 extern struct ast_srtp_res *res_srtp; @@ -2834,27 +2840,30 @@ static int rtp_learning_rtp_seq_update(struct rtp_learning_info *info, uint16_t info->received = ast_tvnow(); } - switch (info->stream_type) { - case AST_MEDIA_TYPE_UNKNOWN: - case AST_MEDIA_TYPE_AUDIO: - /* - * Protect against packet floods by checking that we - * received the packet sequence in at least the minimum - * allowed time. - */ - if (ast_tvzero(info->received)) { - info->received = ast_tvnow(); - } else if (!info->packets - && ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) { - /* Packet flood; reset */ - info->packets = learning_min_sequential - 1; - info->received = ast_tvnow(); + /* Only check time if strictrtp is set to yes. Otherwise, we only needed to check seqno */ + if (strictrtp == STRICT_RTP_YES) { + switch (info->stream_type) { + case AST_MEDIA_TYPE_UNKNOWN: + case AST_MEDIA_TYPE_AUDIO: + /* + * Protect against packet floods by checking that we + * received the packet sequence in at least the minimum + * allowed time. + */ + if (ast_tvzero(info->received)) { + info->received = ast_tvnow(); + } else if (!info->packets + && ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) { + /* Packet flood; reset */ + info->packets = learning_min_sequential - 1; + info->received = ast_tvnow(); + } + break; + case AST_MEDIA_TYPE_VIDEO: + case AST_MEDIA_TYPE_IMAGE: + case AST_MEDIA_TYPE_TEXT: + break; } - break; - case AST_MEDIA_TYPE_VIDEO: - case AST_MEDIA_TYPE_IMAGE: - case AST_MEDIA_TYPE_TEXT: - break; } info->max_seq = seq; @@ -5432,6 +5441,8 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc && STRICT_RTP_LEARN_TIMEOUT < ast_tvdiff_ms(ast_tvnow(), rtp->rtp_source_learn.start)) { ast_verb(4, "%p -- Strict RTP learning complete - Locking on source address %s\n", rtp, ast_sockaddr_stringify(&rtp->strict_rtp_address)); + ast_test_suite_event_notify("STRICT_RTP_LEARN", "Source: %s", + ast_sockaddr_stringify(&rtp->strict_rtp_address)); rtp->strict_rtp_state = STRICT_RTP_CLOSED; } else { struct ast_sockaddr target_address; @@ -5518,6 +5529,16 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc } ast_debug(1, "%p -- Received RTP packet from %s, dropping due to strict RTP protection.\n", rtp, ast_sockaddr_stringify(&addr)); +#ifdef TEST_FRAMEWORK + { + static int strict_rtp_test_event = 1; + if (strict_rtp_test_event) { + ast_test_suite_event_notify("STRICT_RTP_CLOSED", "Source: %s", + ast_sockaddr_stringify(&addr)); + strict_rtp_test_event = 0; /* Only run this event once to prevent possible spam */ + } + } +#endif return &ast_null_frame; case STRICT_RTP_OPEN: break; @@ -6657,7 +6678,13 @@ static int rtp_reload(int reload) }; } if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) { - strictrtp = ast_true(s); + if (ast_true(s)) { + strictrtp = STRICT_RTP_YES; + } else if (!strcasecmp(s, "seqno")) { + strictrtp = STRICT_RTP_SEQNO; + } else { + strictrtp = STRICT_RTP_NO; + } } if ((s = ast_variable_retrieve(cfg, "general", "probation"))) { if ((sscanf(s, "%d", &learning_min_sequential) != 1) || learning_min_sequential <= 1) {