Merge "res_rtp_asterisk.c: Add "seqno" strictrtp option" into 16

This commit is contained in:
George Joseph 2018-09-28 07:28:39 -05:00 committed by Gerrit Code Review
commit de43d25716
3 changed files with 65 additions and 23 deletions

11
CHANGES
View File

@ -8,6 +8,17 @@
===
==============================================================================
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 16.0.0 to Asterisk 16.1.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 15 to Asterisk 16 --------------------
------------------------------------------------------------------------------

View File

@ -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
;

View File

@ -157,6 +157,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
*
@ -166,7 +172,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;
@ -3154,28 +3160,31 @@ 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:
case AST_MEDIA_TYPE_END:
break;
}
break;
case AST_MEDIA_TYPE_VIDEO:
case AST_MEDIA_TYPE_IMAGE:
case AST_MEDIA_TYPE_TEXT:
case AST_MEDIA_TYPE_END:
break;
}
info->max_seq = seq;
@ -6737,6 +6746,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;
@ -6823,6 +6834,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;
@ -8111,7 +8132,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) {