Allow for media to arrive from an alternate source when responding to a reinvite with 491.

When we receive a SIP reinvite, it is possible that we may not be able to process the
reinvite immediately since we have also sent a reinvite out ourselves. The problem is
that whoever sent us the reinvite may have also sent a reinvite out to another party,
and that reinvite may have succeeded.

As a result, even though we are not going to accept the reinvite we just received, it
is important for us to not have problems if we suddenly start receiving RTP from a new
source. The fix for this is to grab the media source information from the SDP of the
reinvite that we receive. This information is passed to the RTP layer so that it will
know about the alternate source for media.

Review: https://reviewboard.asterisk.org/r/252



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@197588 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Michelson
2009-05-28 15:27:49 +00:00
parent 26cec158af
commit 590408dca3
3 changed files with 110 additions and 5 deletions

View File

@@ -151,6 +151,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 */
@@ -209,6 +210,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*/
@@ -899,11 +901,13 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
}
packetwords = res / 4;
if (rtp->nat) {
/* Send to whoever sent to us */
if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->rtcp->them.sin_port != sin.sin_port)) {
if (((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->rtcp->them.sin_port != sin.sin_port)) &&
((rtp->rtcp->altthem.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->rtcp->altthem.sin_port != sin.sin_port))) {
memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them));
if (option_debug || rtpdebug)
ast_log(LOG_DEBUG, "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));
@@ -1203,8 +1207,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 != sin.sin_addr.s_addr) ||
(rtp->them.sin_port != sin.sin_port)) {
if (((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->them.sin_port != sin.sin_port)) &&
((rtp->altthem.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->altthem.sin_port != sin.sin_port))) {
rtp->them = sin;
if (rtp->rtcp) {
memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them));
@@ -2061,6 +2067,16 @@ void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
rtp->rxseqno = 0;
}
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) ||