diff options
Diffstat (limited to 'main/rtp.c')
-rw-r--r-- | main/rtp.c | 24 |
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) || |