mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Merge in strictrtp branch. This adds a strictrtp option to rtp.conf which drops packets that do not come from the remote party.
(closes issue #8952) Reported by: amorsen git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@100206 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -500,3 +500,5 @@ Miscellaneous
|
|||||||
specifying which socket to use to connect to the running Asterisk daemon
|
specifying which socket to use to connect to the running Asterisk daemon
|
||||||
(-s)
|
(-s)
|
||||||
* Added logging to 'make update' command. See update.log
|
* Added logging to 'make update' command. See update.log
|
||||||
|
* Added strictrtp option to rtp.conf. If enabled this will drop RTP packets that
|
||||||
|
do not come from the remote party.
|
||||||
|
@@ -20,3 +20,7 @@ rtpend=20000
|
|||||||
;dtmftimeout=3000
|
;dtmftimeout=3000
|
||||||
; rtcpinterval = 5000 ; Milliseconds between rtcp reports
|
; rtcpinterval = 5000 ; Milliseconds between rtcp reports
|
||||||
;(min 500, max 60000, default 5000)
|
;(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.
|
||||||
|
; strictrtp=yes
|
||||||
|
33
main/rtp.c
33
main/rtp.c
@@ -78,6 +78,13 @@ static struct sockaddr_in rtcpdebugaddr; /*!< Debug RTCP packets to/from this ho
|
|||||||
#ifdef SO_NO_CHECK
|
#ifdef SO_NO_CHECK
|
||||||
static int nochecksums;
|
static int nochecksums;
|
||||||
#endif
|
#endif
|
||||||
|
static int strictrtp;
|
||||||
|
|
||||||
|
enum strict_rtp_state {
|
||||||
|
STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
|
||||||
|
STRICT_RTP_LEARN, /*! Accept next packet as source */
|
||||||
|
STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
|
||||||
|
};
|
||||||
|
|
||||||
/* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
|
/* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
|
||||||
/* #define P2P_INTENSE */
|
/* #define P2P_INTENSE */
|
||||||
@@ -165,6 +172,9 @@ struct ast_rtp {
|
|||||||
struct ast_rtcp *rtcp;
|
struct ast_rtcp *rtcp;
|
||||||
struct ast_codec_pref pref;
|
struct ast_codec_pref pref;
|
||||||
struct ast_rtp *bridged; /*!< Who we are Packet bridged to */
|
struct ast_rtp *bridged; /*!< Who we are Packet bridged to */
|
||||||
|
|
||||||
|
enum strict_rtp_state strict_rtp_state; /*!< Current state that strict RTP protection is in */
|
||||||
|
struct sockaddr_in strict_rtp_address; /*!< Remote address information for strict RTP purposes */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
@@ -1391,6 +1401,21 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
|
|||||||
res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
|
res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
|
||||||
0, (struct sockaddr *)&sin, &len);
|
0, (struct sockaddr *)&sin, &len);
|
||||||
|
|
||||||
|
/* If strict RTP protection is enabled see if we need to learn this address or if the packet should be dropped */
|
||||||
|
if (rtp->strict_rtp_state == STRICT_RTP_LEARN) {
|
||||||
|
/* Copy over address that this packet was received on */
|
||||||
|
memcpy(&rtp->strict_rtp_address, &sin, sizeof(rtp->strict_rtp_address));
|
||||||
|
/* Now move over to actually protecting the RTP port */
|
||||||
|
rtp->strict_rtp_state = STRICT_RTP_CLOSED;
|
||||||
|
ast_debug(1, "Learned remote address is %s:%d for strict RTP purposes, now protecting the port.\n", ast_inet_ntoa(rtp->strict_rtp_address.sin_addr), ntohs(rtp->strict_rtp_address.sin_port));
|
||||||
|
} else if (rtp->strict_rtp_state == STRICT_RTP_CLOSED) {
|
||||||
|
/* If the address we previously learned doesn't match the address this packet came in on simply drop it */
|
||||||
|
if ((rtp->strict_rtp_address.sin_addr.s_addr != sin.sin_addr.s_addr) || (rtp->strict_rtp_address.sin_port != sin.sin_port)) {
|
||||||
|
ast_debug(1, "Received RTP packet from %s:%d, dropping due to strict RTP protection. Expected it to be from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), ast_inet_ntoa(rtp->strict_rtp_address.sin_addr), ntohs(rtp->strict_rtp_address.sin_port));
|
||||||
|
return &ast_null_frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
|
rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (errno == EBADF)
|
if (errno == EBADF)
|
||||||
@@ -2191,6 +2216,7 @@ void ast_rtp_new_init(struct ast_rtp *rtp)
|
|||||||
rtp->ssrc = ast_random();
|
rtp->ssrc = ast_random();
|
||||||
rtp->seqno = ast_random() & 0xffff;
|
rtp->seqno = ast_random() & 0xffff;
|
||||||
ast_set_flag(rtp, FLAG_HAS_DTMF);
|
ast_set_flag(rtp, FLAG_HAS_DTMF);
|
||||||
|
rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_LEARN : STRICT_RTP_OPEN);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2312,6 +2338,9 @@ void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
|
|||||||
rtp->rtcp->them.sin_addr = them->sin_addr;
|
rtp->rtcp->them.sin_addr = them->sin_addr;
|
||||||
}
|
}
|
||||||
rtp->rxseqno = 0;
|
rtp->rxseqno = 0;
|
||||||
|
/* If strict RTP protection is enabled switch back to the learn state so we don't drop packets from above */
|
||||||
|
if (strictrtp)
|
||||||
|
rtp->strict_rtp_state = STRICT_RTP_LEARN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
|
int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
|
||||||
@@ -4025,6 +4054,7 @@ static int __ast_rtp_reload(int reload)
|
|||||||
rtpstart = 5000;
|
rtpstart = 5000;
|
||||||
rtpend = 31000;
|
rtpend = 31000;
|
||||||
dtmftimeout = DEFAULT_DTMF_TIMEOUT;
|
dtmftimeout = DEFAULT_DTMF_TIMEOUT;
|
||||||
|
strictrtp = STRICT_RTP_OPEN;
|
||||||
if (cfg) {
|
if (cfg) {
|
||||||
if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
|
if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
|
||||||
rtpstart = atoi(s);
|
rtpstart = atoi(s);
|
||||||
@@ -4068,6 +4098,9 @@ static int __ast_rtp_reload(int reload)
|
|||||||
dtmftimeout = DEFAULT_DTMF_TIMEOUT;
|
dtmftimeout = DEFAULT_DTMF_TIMEOUT;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {
|
||||||
|
strictrtp = ast_true(s);
|
||||||
|
}
|
||||||
ast_config_destroy(cfg);
|
ast_config_destroy(cfg);
|
||||||
}
|
}
|
||||||
if (rtpstart >= rtpend) {
|
if (rtpstart >= rtpend) {
|
||||||
|
Reference in New Issue
Block a user