summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2012-10-04 13:49:45 +0000
committerJoshua Colp <jcolp@digium.com>2012-10-04 13:49:45 +0000
commitd78f7f92b2afa033ff959e84bf164454ca9a5de8 (patch)
tree6d34c64a2148b1b0eb340a6c27f39b3d024ee168
parent4af961a03a5d00601ad18e75887e882602dc24fe (diff)
Add support for applying direct media ACLs between differing channel technologies.
Review: https://reviewboard.asterisk.org/r/2122/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@374414 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_sip.c85
-rw-r--r--include/asterisk/rtp_engine.h6
-rw-r--r--main/rtp_engine.c26
3 files changed, 41 insertions, 76 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 8e071e11d..b938d2d81 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -31867,25 +31867,6 @@ static int reload_config(enum channelreloadreason reason)
return 0;
}
-static int apply_directmedia_acl(struct sip_pvt *p, struct ast_acl_list *directmediaacl, const char *op)
-{
- struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
- int res = AST_SENSE_ALLOW;
-
- ast_rtp_instance_get_remote_address(p->rtp, &them);
- ast_rtp_instance_get_local_address(p->rtp, &us);
-
- if ((res = ast_apply_acl(directmediaacl, &them, "SIP Direct Media ACL: ")) == AST_SENSE_DENY) {
- const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
- const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
-
- ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
- op, them_addr, us_addr);
- }
-
- return res;
-}
-
static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
{
struct sip_pvt *p;
@@ -31947,72 +31928,56 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
return 0;
}
-static int sip_allow_anyrtp_remote(struct ast_channel *chan1, struct ast_channel *chan2, char *rtptype)
+static int sip_allow_anyrtp_remote(struct ast_channel *chan1, struct ast_rtp_instance *instance, const char *rtptype)
{
- struct sip_pvt *p1 = NULL, *p2 = NULL;
- struct ast_acl_list *p2_directmediaacl = NULL; /* opposed directmediaha for comparing against first channel host address */
- struct ast_acl_list *p1_directmediaacl = NULL; /* opposed directmediaha for comparing against second channel host address */
+ struct sip_pvt *p;
+ struct ast_acl_list *acl = NULL;
int res = 1;
- if (!(p1 = ast_channel_tech_pvt(chan1))) {
+ if (!(p = ast_channel_tech_pvt(chan1))) {
return 0;
}
- if (!(p2 = ast_channel_tech_pvt(chan2))) {
- return 0;
+ sip_pvt_lock(p);
+ if (p->relatedpeer && p->relatedpeer->directmediaacl) {
+ acl = ast_duplicate_acl_list(p->relatedpeer->directmediaacl);
}
+ sip_pvt_unlock(p);
- sip_pvt_lock(p2);
- if (p2->relatedpeer && p2->relatedpeer->directmediaacl) {
- p2_directmediaacl = ast_duplicate_acl_list(p2->relatedpeer->directmediaacl);
+ if (!acl) {
+ return res;
}
- sip_pvt_unlock(p2);
- sip_pvt_lock(p1);
- if (p1->relatedpeer && p1->relatedpeer->directmediaacl) {
- p1_directmediaacl = ast_duplicate_acl_list(p1->relatedpeer->directmediaacl);
- }
+ if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
+ struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
- if (p2_directmediaacl && ast_test_flag(&p1->flags[0], SIP_DIRECT_MEDIA)) {
- if (!apply_directmedia_acl(p1, p2_directmediaacl, rtptype)) {
- res = 0;
- }
- }
- sip_pvt_unlock(p1);
+ ast_rtp_instance_get_remote_address(instance, &them);
+ ast_rtp_instance_get_local_address(instance, &us);
- if (res == 0) {
- goto allow_anyrtp_remote_end;
- }
+ if (ast_apply_acl(acl, &them, "SIP Direct Media ACL: ") == AST_SENSE_DENY) {
+ const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
+ const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
+
+ ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
+ rtptype, them_addr, us_addr);
- sip_pvt_lock(p2);
- if (p1_directmediaacl && ast_test_flag(&p2->flags[0], SIP_DIRECT_MEDIA)) {
- if (!apply_directmedia_acl(p2, p1_directmediaacl, rtptype)) {
res = 0;
}
}
- sip_pvt_unlock(p2);
-
-allow_anyrtp_remote_end:
-
- if (p2_directmediaacl) {
- p2_directmediaacl = ast_free_acl_list(p2_directmediaacl);
- }
- if (p1_directmediaacl) {
- p1_directmediaacl = ast_free_acl_list(p1_directmediaacl);
- }
+ ast_free_acl_list(acl);
return res;
}
-static int sip_allow_rtp_remote(struct ast_channel *chan1, struct ast_channel *chan2)
+static int sip_allow_rtp_remote(struct ast_channel *chan1, struct ast_rtp_instance *instance)
{
- return sip_allow_anyrtp_remote(chan1, chan2, "audio");
+ return sip_allow_anyrtp_remote(chan1, instance, "audio");
}
-static int sip_allow_vrtp_remote(struct ast_channel *chan1, struct ast_channel *chan2)
+static int sip_allow_vrtp_remote(struct ast_channel *chan1, struct ast_rtp_instance *instance)
{
- return sip_allow_anyrtp_remote(chan1, chan2, "video");
+ return sip_allow_anyrtp_remote(chan1, instance, "video");
}
static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index 293a7a792..72c162d20 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -509,10 +509,9 @@ struct ast_rtp_glue {
/*!
* \brief Used to prevent two channels from remotely bridging audio rtp if the channel tech has a
* reason for prohibiting it based on qualities that need to be compared from both channels.
- * \note This function should only be called with two channels of the same technology
* \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, function this is not used.
*/
- int (*allow_rtp_remote)(struct ast_channel *chan1, struct ast_channel *chan2);
+ int (*allow_rtp_remote)(struct ast_channel *chan1, struct ast_rtp_instance *instance);
/*!
* \brief Callback for retrieving the RTP instance carrying video
* \note This function increases the reference count on the returned RTP instance.
@@ -521,10 +520,9 @@ struct ast_rtp_glue {
/*!
* \brief Used to prevent two channels from remotely bridging video rtp if the channel tech has a
* reason for prohibiting it based on qualities that need to be compared from both channels.
- * \note This function should only be called with two channels of the same technology
* \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, this function is not used.
*/
- int (*allow_vrtp_remote)(struct ast_channel *chan1, struct ast_channel *chan2);
+ int (*allow_vrtp_remote)(struct ast_channel *chan1, struct ast_rtp_instance *instance);
/*!
* \brief Callback for retrieving the RTP instance carrying text
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 4bcdb138a..55ca0f2b7 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -1484,19 +1484,21 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as
audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
- /* If the channels are of the same technology, they might have limitations on remote bridging */
- if (ast_channel_tech(c0) == ast_channel_tech(c1)) {
- if (audio_glue0_res == audio_glue1_res && audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
- if (glue0->allow_rtp_remote && !(glue0->allow_rtp_remote(c0, c1))) {
- /* If the allow_rtp_remote indicates that remote isn't allowed, revert to local bridge */
- audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
- }
+ /* Apply any limitations on direct media bridging that may be present */
+ if (audio_glue0_res == audio_glue1_res && audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
+ if (glue0->allow_rtp_remote && !(glue0->allow_rtp_remote(c0, instance1))) {
+ /* If the allow_rtp_remote indicates that remote isn't allowed, revert to local bridge */
+ audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
+ } else if (glue1->allow_rtp_remote && !(glue1->allow_rtp_remote(c1, instance0))) {
+ audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
}
- if (video_glue0_res == video_glue1_res && video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
- if (glue0->allow_vrtp_remote && !(glue0->allow_vrtp_remote(c0, c1))) {
- /* if the allow_vrtp_remote indicates that remote isn't allowed, revert to local bridge */
- video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
- }
+ }
+ if (video_glue0_res == video_glue1_res && video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
+ if (glue0->allow_vrtp_remote && !(glue0->allow_vrtp_remote(c0, instance1))) {
+ /* if the allow_vrtp_remote indicates that remote isn't allowed, revert to local bridge */
+ video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
+ } else if (glue1->allow_vrtp_remote && !(glue1->allow_vrtp_remote(c1, instance0))) {
+ video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
}
}