summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia/transport_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjmedia/src/pjmedia/transport_udp.c')
-rw-r--r--pjmedia/src/pjmedia/transport_udp.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/pjmedia/src/pjmedia/transport_udp.c b/pjmedia/src/pjmedia/transport_udp.c
index 59d2dc70..63178599 100644
--- a/pjmedia/src/pjmedia/transport_udp.c
+++ b/pjmedia/src/pjmedia/transport_udp.c
@@ -83,6 +83,7 @@ struct transport_udp
pj_sock_t rtcp_sock; /**< RTCP socket */
pj_sockaddr rtcp_addr_name; /**< Published RTCP address. */
pj_sockaddr rtcp_src_addr; /**< Actual source RTCP address. */
+ unsigned rtcp_src_cnt; /**< How many pkt from this addr. */
int rtcp_addr_len; /**< Length of RTCP src address. */
pj_ioqueue_key_t *rtcp_key; /**< RTCP socket key in ioqueue */
pj_ioqueue_op_key_t rtcp_read_op; /**< Pending read operation */
@@ -452,6 +453,7 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
do {
void (*cb)(void*,void*,pj_ssize_t);
void *user_data;
+ pj_bool_t discard = PJ_FALSE;
cb = udp->rtp_cb;
user_data = udp->user_data;
@@ -462,14 +464,10 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
PJ_LOG(5,(udp->base.name,
"RX RTP packet dropped because of pkt lost "
"simulation"));
- goto read_next_packet;
+ discard = PJ_TRUE;
}
}
-
- if (udp->attached && cb)
- (*cb)(user_data, udp->rtp_pkt, bytes_read);
-
/* See if source address of RTP packet is different than the
* configured address, and switch RTP remote address to
* source packet address after several consecutive packets
@@ -478,11 +476,15 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
if (bytes_read>0 &&
(udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)
{
- if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) != 0) {
-
+ if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) == 0) {
+ /* We're still receiving from rem_rtp_addr. Don't switch. */
+ udp->rtp_src_cnt = 0;
+ } else {
udp->rtp_src_cnt++;
- if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) {
+ if (udp->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {
+ discard = PJ_TRUE;
+ } else {
char addr_text[80];
@@ -516,7 +518,8 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
sizeof(pj_sockaddr));
PJ_LOG(4,(udp->base.name,
- "Remote RTCP address switched to %s",
+ "Remote RTCP address switched to predicted"
+ " address %s",
pj_sockaddr_print(&udp->rtcp_src_addr,
addr_text,
sizeof(addr_text), 3)));
@@ -526,7 +529,9 @@ static void on_rx_rtp( pj_ioqueue_key_t *key,
}
}
-read_next_packet:
+ if (!discard && udp->attached && cb)
+ (*cb)(user_data, udp->rtp_pkt, bytes_read);
+
bytes_read = sizeof(udp->rtp_pkt);
udp->rtp_addrlen = sizeof(udp->rtp_src_addr);
status = pj_ioqueue_recvfrom(udp->rtp_key, &udp->rtp_read_op,
@@ -568,18 +573,27 @@ static void on_rx_rtcp(pj_ioqueue_key_t *key,
* different.
*/
if (bytes_read>0 &&
- (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 &&
- pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) != 0)
+ (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)
{
- char addr_text[80];
+ if (pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) == 0) {
+ /* Still receiving from rem_rtcp_addr, don't switch */
+ udp->rtcp_src_cnt = 0;
+ } else {
+ ++udp->rtcp_src_cnt;
- pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,
- sizeof(pj_sockaddr));
+ if (udp->rtcp_src_cnt >= PJMEDIA_RTCP_NAT_PROBATION_CNT ) {
+ char addr_text[80];
+
+ udp->rtcp_src_cnt = 0;
+ pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,
+ sizeof(pj_sockaddr));
- PJ_LOG(4,(udp->base.name,
- "Remote RTCP address switched to %s",
- pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,
- sizeof(addr_text), 3)));
+ PJ_LOG(4,(udp->base.name,
+ "Remote RTCP address switched to %s",
+ pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,
+ sizeof(addr_text), 3)));
+ }
+ }
}
bytes_read = sizeof(udp->rtcp_pkt);
@@ -677,6 +691,7 @@ static pj_status_t transport_attach( pjmedia_transport *tp,
pj_bzero(&udp->rtp_src_addr, sizeof(udp->rtp_src_addr));
pj_bzero(&udp->rtcp_src_addr, sizeof(udp->rtcp_src_addr));
udp->rtp_src_cnt = 0;
+ udp->rtcp_src_cnt = 0;
/* Unlock keys */
pj_ioqueue_unlock_key(udp->rtcp_key);