aboutsummaryrefslogtreecommitdiffstats
path: root/main/rtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/rtp.c')
-rw-r--r--main/rtp.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/main/rtp.c b/main/rtp.c
index 6a806911c..1e6a438e0 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -146,6 +146,7 @@ struct ast_rtp {
unsigned int flags;
struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
+ struct sockaddr_in altthem; /*!< Alternate source of remote media */
struct timeval rxcore;
struct timeval txcore;
double drxcore; /*!< The double representation of the first received packet */
@@ -230,6 +231,7 @@ struct ast_rtcp {
int s; /*!< Socket */
struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
+ struct sockaddr_in altthem; /*!< Alternate source for RTCP */
unsigned int soc; /*!< What they told us */
unsigned int spc; /*!< What they told us */
unsigned int themrxlsr; /*!< The middle 32 bits of the NTP timestamp in the last received SR*/
@@ -1207,8 +1209,10 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
if (rtp->nat) {
/* Send to whoever sent to us */
- if ((rtp->rtcp->them.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
- (rtp->rtcp->them.sin_port != sock_in.sin_port)) {
+ if (((rtp->rtcp->them.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
+ (rtp->rtcp->them.sin_port != sock_in.sin_port)) &&
+ ((rtp->rtcp->altthem.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
+ (rtp->rtcp->altthem.sin_port != sock_in.sin_port))) {
memcpy(&rtp->rtcp->them, &sock_in, sizeof(rtp->rtcp->them));
if (option_debug || rtpdebug)
ast_debug(0, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
@@ -1639,8 +1643,10 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
/* Send to whoever send to us if NAT is turned on */
if (rtp->nat) {
- if ((rtp->them.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
- (rtp->them.sin_port != sock_in.sin_port)) {
+ if (((rtp->them.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
+ (rtp->them.sin_port != sock_in.sin_port)) &&
+ ((rtp->altthem.sin_addr.s_addr != sock_in.sin_addr.s_addr) ||
+ (rtp->altthem.sin_port != sock_in.sin_port))) {
rtp->them = sock_in;
if (rtp->rtcp) {
int h = 0;
@@ -2650,6 +2656,16 @@ void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
rtp->strict_rtp_state = STRICT_RTP_LEARN;
}
+void ast_rtp_set_alt_peer(struct ast_rtp *rtp, struct sockaddr_in *alt)
+{
+ rtp->altthem.sin_port = alt->sin_port;
+ rtp->altthem.sin_addr = alt->sin_addr;
+ if (rtp->rtcp) {
+ rtp->rtcp->altthem.sin_port = htons(ntohs(alt->sin_port) + 1);
+ rtp->rtcp->altthem.sin_addr = alt->sin_addr;
+ }
+}
+
int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
{
if ((them->sin_family != AF_INET) ||