diff options
author | Jenkins2 <jenkins2@gerrit.asterisk.org> | 2017-12-15 12:14:55 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-12-15 12:14:55 -0600 |
commit | f06f311497350a9bee91e93fcd576145f23fa28a (patch) | |
tree | 1821544e0141118534d195c6229a927f5e93707a | |
parent | 9f75ecb153c7774a707e66285432bca73105b615 (diff) | |
parent | 39c8d566ad78d9e726b5900f9b14241ec99492fb (diff) |
Merge "res_rtp_asterisk.c: Disable packet flood detection for video streams." into 15
-rw-r--r-- | configs/samples/rtp.conf.sample | 14 | ||||
-rw-r--r-- | include/asterisk/rtp_engine.h | 10 | ||||
-rw-r--r-- | main/rtp_engine.c | 19 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 45 |
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", |