summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins2 <jenkins2@gerrit.asterisk.org>2017-12-15 12:14:55 -0600
committerGerrit Code Review <gerrit2@gerrit.digium.api>2017-12-15 12:14:55 -0600
commitf06f311497350a9bee91e93fcd576145f23fa28a (patch)
tree1821544e0141118534d195c6229a927f5e93707a
parent9f75ecb153c7774a707e66285432bca73105b615 (diff)
parent39c8d566ad78d9e726b5900f9b14241ec99492fb (diff)
Merge "res_rtp_asterisk.c: Disable packet flood detection for video streams." into 15
-rw-r--r--configs/samples/rtp.conf.sample14
-rw-r--r--include/asterisk/rtp_engine.h10
-rw-r--r--main/rtp_engine.c19
-rw-r--r--res/res_rtp_asterisk.c45
4 files changed, 74 insertions, 14 deletions
diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample
index 9bc3de3cf..de9d59007 100644
--- a/configs/samples/rtp.conf.sample
+++ b/configs/samples/rtp.conf.sample
@@ -21,9 +21,17 @@ rtpend=20000
; rtcpinterval = 5000 ; Milliseconds between rtcp reports
;(min 500, max 60000, default 5000)
;
-; Enable strict RTP protection. This will drop RTP packets that
-; do not come from the source of the RTP stream. This option is
-; enabled by default.
+; Enable strict RTP protection. This will drop RTP packets that do not come
+; from the recoginized source of the RTP stream. Strict RTP qualifies RTP
+; packet stream sources before accepting them upon initial connection and
+; when the connection is renegotiated (e.g., transfers and direct media).
+; Initial connection and renegotiation starts a learning mode to qualify
+; stream source addresses. Once Asterisk has recognized a stream it will
+; allow other streams to qualify and replace the current stream for 5
+; seconds after starting learning mode. Once learning mode completes the
+; current stream is locked in and cannot change until the next
+; renegotiation.
+; This option is enabled by default.
; strictrtp=yes
;
; Number of packets containing consecutive sequence values needed
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index f9d686aca..c77be4584 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -1383,6 +1383,16 @@ int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs,
void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload);
/*!
+ * \brief Determine the type of RTP stream media from the codecs mapped.
+ * \since 13.19.0
+ *
+ * \param codecs Codecs structure to look in
+ *
+ * \return Media type or AST_MEDIA_TYPE_UNKNOWN if no codecs mapped.
+ */
+enum ast_media_type ast_rtp_codecs_get_stream_type(struct ast_rtp_codecs *codecs);
+
+/*!
* \brief Retrieve rx payload mapped information by payload type
*
* \param codecs Codecs structure to look in
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 2431ffc0c..68c53e7ff 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -1176,6 +1176,25 @@ void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp
ast_rwlock_unlock(&codecs->codecs_lock);
}
+enum ast_media_type ast_rtp_codecs_get_stream_type(struct ast_rtp_codecs *codecs)
+{
+ enum ast_media_type stream_type = AST_MEDIA_TYPE_UNKNOWN;
+ int payload;
+ struct ast_rtp_payload_type *type;
+
+ ast_rwlock_rdlock(&codecs->codecs_lock);
+ for (payload = 0; payload < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++payload) {
+ type = AST_VECTOR_GET(&codecs->payload_mapping_rx, payload);
+ if (type && type->asterisk_format) {
+ stream_type = ast_format_get_type(type->format);
+ break;
+ }
+ }
+ ast_rwlock_unlock(&codecs->codecs_lock);
+
+ return stream_type;
+}
+
struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload)
{
struct ast_rtp_payload_type *type = NULL;
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index bdc83301e..51e509c77 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -256,6 +256,8 @@ struct rtp_learning_info {
struct timeval received; /*!< The time of the first received packet */
int max_seq; /*!< The highest sequence number received */
int packets; /*!< The number of remaining packets before the source is accepted */
+ /*! Type of media stream carried by the RTP instance */
+ enum ast_media_type stream_type;
};
#ifdef HAVE_OPENSSL_SRTP
@@ -3095,18 +3097,30 @@ static int rtp_learning_rtp_seq_update(struct rtp_learning_info *info, uint16_t
info->received = ast_tvnow();
}
- /*
- * 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();
+ 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;
}
+
info->max_seq = seq;
return info->packets;
@@ -5951,6 +5965,15 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
* source and we should switch to it.
*/
if (!ast_sockaddr_cmp(&rtp->rtp_source_learn.proposed_address, &addr)) {
+ if (rtp->rtp_source_learn.stream_type == AST_MEDIA_TYPE_UNKNOWN) {
+ struct ast_rtp_codecs *codecs;
+
+ codecs = ast_rtp_instance_get_codecs(instance);
+ rtp->rtp_source_learn.stream_type =
+ ast_rtp_codecs_get_stream_type(codecs);
+ ast_verb(4, "%p -- Strict RTP qualifying stream type: %s\n",
+ rtp, ast_codec_media_type2str(rtp->rtp_source_learn.stream_type));
+ }
if (!rtp_learning_rtp_seq_update(&rtp->rtp_source_learn, seqno)) {
/* Accept the new RTP stream */
ast_verb(4, "%p -- Strict RTP switching source address to %s\n",