mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 20:20:07 +00:00
res_rtp_asterisk.c: Add "seqno" strictrtp option
When networks experience disruptions, there can be large gaps of time between receiving packets. When strictrtp is enabled, this created issues where a flood of packets could come in and be seen as an attack. Another option - seqno - has been added to the strictrtp option that ignores the time interval and goes strictly by sequence number for validity. Change-Id: I8a42b8d193673899c8fc22fe7f98ea87df89be71
This commit is contained in:
committed by
Benjamin Keith Ford
parent
94ef074cc7
commit
67e1e49e08
11
CHANGES
11
CHANGES
@@ -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 --------------------
|
--- Functionality changes from Asterisk 15 to Asterisk 16 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@@ -31,6 +31,10 @@ rtpend=20000
|
|||||||
; seconds after starting learning mode. Once learning mode completes the
|
; seconds after starting learning mode. Once learning mode completes the
|
||||||
; current stream is locked in and cannot change until the next
|
; current stream is locked in and cannot change until the next
|
||||||
; renegotiation.
|
; 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.
|
; This option is enabled by default.
|
||||||
; strictrtp=yes
|
; strictrtp=yes
|
||||||
;
|
;
|
||||||
|
@@ -157,6 +157,12 @@ enum strict_rtp_state {
|
|||||||
STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
|
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
|
* \brief Strict RTP learning timeout time in milliseconds
|
||||||
*
|
*
|
||||||
@@ -166,7 +172,7 @@ enum strict_rtp_state {
|
|||||||
*/
|
*/
|
||||||
#define STRICT_RTP_LEARN_TIMEOUT 5000
|
#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
|
#define DEFAULT_ICESUPPORT 1
|
||||||
|
|
||||||
extern struct ast_srtp_res *res_srtp;
|
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();
|
info->received = ast_tvnow();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info->stream_type) {
|
/* Only check time if strictrtp is set to yes. Otherwise, we only needed to check seqno */
|
||||||
case AST_MEDIA_TYPE_UNKNOWN:
|
if (strictrtp == STRICT_RTP_YES) {
|
||||||
case AST_MEDIA_TYPE_AUDIO:
|
switch (info->stream_type) {
|
||||||
/*
|
case AST_MEDIA_TYPE_UNKNOWN:
|
||||||
* Protect against packet floods by checking that we
|
case AST_MEDIA_TYPE_AUDIO:
|
||||||
* received the packet sequence in at least the minimum
|
/*
|
||||||
* allowed time.
|
* Protect against packet floods by checking that we
|
||||||
*/
|
* received the packet sequence in at least the minimum
|
||||||
if (ast_tvzero(info->received)) {
|
* allowed time.
|
||||||
info->received = ast_tvnow();
|
*/
|
||||||
} else if (!info->packets
|
if (ast_tvzero(info->received)) {
|
||||||
&& ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) {
|
info->received = ast_tvnow();
|
||||||
/* Packet flood; reset */
|
} else if (!info->packets
|
||||||
info->packets = learning_min_sequential - 1;
|
&& ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) {
|
||||||
info->received = ast_tvnow();
|
/* 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;
|
info->max_seq = seq;
|
||||||
@@ -6736,6 +6745,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)) {
|
&& 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",
|
ast_verb(4, "%p -- Strict RTP learning complete - Locking on source address %s\n",
|
||||||
rtp, ast_sockaddr_stringify(&rtp->strict_rtp_address));
|
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;
|
rtp->strict_rtp_state = STRICT_RTP_CLOSED;
|
||||||
} else {
|
} else {
|
||||||
struct ast_sockaddr target_address;
|
struct ast_sockaddr target_address;
|
||||||
@@ -6822,6 +6833,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",
|
ast_debug(1, "%p -- Received RTP packet from %s, dropping due to strict RTP protection.\n",
|
||||||
rtp, ast_sockaddr_stringify(&addr));
|
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;
|
return &ast_null_frame;
|
||||||
case STRICT_RTP_OPEN:
|
case STRICT_RTP_OPEN:
|
||||||
break;
|
break;
|
||||||
@@ -8110,7 +8131,13 @@ static int rtp_reload(int reload)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {
|
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 ((s = ast_variable_retrieve(cfg, "general", "probation"))) {
|
||||||
if ((sscanf(s, "%d", &learning_min_sequential) != 1) || learning_min_sequential <= 1) {
|
if ((sscanf(s, "%d", &learning_min_sequential) != 1) || learning_min_sequential <= 1) {
|
||||||
|
Reference in New Issue
Block a user