Ticket #616: Ticket616.patch
File Ticket616.patch, 7.6 KB (added by nanang, 16 years ago) |
---|
-
pjmedia/include/pjmedia/transport_ice.h
62 62 63 63 64 64 /** 65 * Options that can be specified when creating ICE transport. 66 */ 67 enum pjmedia_transport_ice_options 68 { 69 /** 70 * Normally the ICE transport will continuously check the source address 71 * of incoming packets to see if it is different than the configured 72 * remote address, and switch the remote address to the source address 73 * of the packet if they are different after several packets are 74 * received. 75 * Specifying this option will disable this feature. 76 */ 77 PJMEDIA_ICE_NO_SRC_ADDR_CHECKING = 1 78 }; 79 80 81 /** 65 82 * Create the Interactive Connectivity Establishment (ICE) media transport 66 83 * using the specified configuration. When STUN or TURN (or both) is used, 67 84 * the creation operation will complete asynchronously, when STUN resolution … … 94 111 const pjmedia_ice_cb *cb, 95 112 pjmedia_transport **p_tp); 96 113 114 115 /** 116 * The same as @pjmedia_ice_create with additional \a options param. 117 * 118 * @param endpt The media endpoint. 119 * @param name Optional name to identify this ICE media transport 120 * for logging purposes. 121 * @param comp_cnt Number of components to be created. 122 * @param cfg Pointer to configuration settings. 123 * @param cb Optional structure containing ICE specific callbacks. 124 * @param options Options, see #pjmedia_transport_ice_options. 125 * @param p_tp Pointer to receive the media transport instance. 126 * 127 * @return PJ_SUCCESS on success, or the appropriate error code. 128 */ 129 PJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt, 130 const char *name, 131 unsigned comp_cnt, 132 const pj_ice_strans_cfg *cfg, 133 const pjmedia_ice_cb *cb, 134 unsigned options, 135 pjmedia_transport **p_tp); 136 97 137 PJ_END_DECL 98 138 99 139 -
pjmedia/src/pjmedia/transport_ice.c
49 49 pjmedia_transport base; 50 50 pj_pool_t *pool; 51 51 int af; 52 unsigned options; /**< Transport options. */ 52 53 53 54 unsigned comp_cnt; 54 55 pj_ice_strans *ice_st; … … 58 59 59 60 pj_bool_t initial_sdp; 60 61 enum oa_role oa_role; /**< Last role in SDP offer/answer */ 61 struct sdp_state rem_offer_state;/**< Describes the remote offer 62 struct sdp_state rem_offer_state;/**< Describes the remote offer */ 62 63 63 64 void *stream; 64 pj_sockaddr_in remote_rtp; 65 pj_sockaddr_in remote_rtcp; 65 pj_sockaddr remote_rtp; 66 pj_sockaddr remote_rtcp; 67 unsigned addr_len; /**< Length of addresses. */ 66 68 69 pj_bool_t ice_inited; 70 pj_sockaddr rtp_src_addr; /**< Actual source RTP address. */ 71 pj_sockaddr rtcp_src_addr; /**< Actual source RTCP address. */ 72 unsigned rtp_src_cnt; /**< How many pkt from this addr. */ 73 67 74 unsigned tx_drop_pct; /**< Percent of tx pkts to drop. */ 68 75 unsigned rx_drop_pct; /**< Percent of rx pkts to drop. */ 69 76 … … 181 188 const pjmedia_ice_cb *cb, 182 189 pjmedia_transport **p_tp) 183 190 { 191 return pjmedia_ice_create2(endpt, name, comp_cnt, cfg, cb, 0, p_tp); 192 } 193 194 /* 195 * Create ICE media transport. 196 */ 197 PJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt, 198 const char *name, 199 unsigned comp_cnt, 200 const pj_ice_strans_cfg *cfg, 201 const pjmedia_ice_cb *cb, 202 unsigned options, 203 pjmedia_transport **p_tp) 204 { 184 205 pj_pool_t *pool; 185 206 pj_ice_strans_cb ice_st_cb; 186 207 struct transport_ice *tp_ice; … … 193 214 tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice); 194 215 tp_ice->pool = pool; 195 216 tp_ice->af = cfg->af; 217 tp_ice->options = options; 196 218 tp_ice->comp_cnt = comp_cnt; 197 219 pj_ansi_strcpy(tp_ice->base.name, pool->obj_name); 198 220 tp_ice->base.op = &transport_ice_op; 199 221 tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE; 200 222 tp_ice->initial_sdp = PJ_TRUE; 201 223 tp_ice->oa_role = ROLE_NONE; 224 tp_ice->ice_inited = PJ_FALSE; 202 225 203 226 if (cb) 204 227 pj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb)); … … 241 264 } 242 265 243 266 pj_ice_strans_stop_ice(tp_ice->ice_st); 267 268 tp_ice->ice_inited = PJ_FALSE; 244 269 } 245 270 246 271 … … 1357 1382 } 1358 1383 1359 1384 /* Done */ 1385 tp_ice->ice_inited = PJ_TRUE; 1360 1386 1361 1387 return PJ_SUCCESS; 1362 1388 } … … 1422 1448 1423 1449 pj_memcpy(&tp_ice->remote_rtp, rem_addr, addr_len); 1424 1450 pj_memcpy(&tp_ice->remote_rtcp, rem_rtcp, addr_len); 1451 tp_ice->addr_len = addr_len; 1425 1452 1426 1453 return PJ_SUCCESS; 1427 1454 } … … 1460 1487 1461 1488 return pj_ice_strans_sendto(tp_ice->ice_st, 1, 1462 1489 pkt, size, &tp_ice->remote_rtp, 1463 sizeof(pj_sockaddr_in));1490 tp_ice->addr_len); 1464 1491 } 1465 1492 1466 1493 … … 1514 1541 1515 1542 (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size); 1516 1543 1517 } else if (comp_id==2 && tp_ice->rtcp_cb) 1544 /* See if source address of RTP packet is different than the 1545 * configured address, and switch RTP remote address to 1546 * source packet address after several consecutive packets 1547 * have been received. 1548 */ 1549 if (!tp_ice->ice_inited && 1550 (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING) == 0 && 1551 pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) != 0 ) 1552 { 1553 /* Check if the source address is recognized. */ 1554 if (pj_sockaddr_cmp(src_addr, &tp_ice->rtp_src_addr) != 0) { 1555 /* Remember the new source address. */ 1556 pj_sockaddr_cp(&tp_ice->rtp_src_addr, src_addr); 1557 1558 /* Reset counter */ 1559 tp_ice->rtp_src_cnt = 0; 1560 } 1561 1562 tp_ice->rtp_src_cnt++; 1563 1564 if (tp_ice->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 1565 1566 char addr_text[80]; 1567 1568 /* Set remote RTP address to source address */ 1569 pj_sockaddr_cp(&tp_ice->remote_rtp, &tp_ice->rtp_src_addr); 1570 tp_ice->addr_len = pj_sockaddr_get_len(&tp_ice->remote_rtp); 1571 1572 /* Reset counter */ 1573 tp_ice->rtp_src_cnt = 0; 1574 1575 PJ_LOG(4,(tp_ice->base.name, 1576 "Remote RTP address switched to %s", 1577 pj_sockaddr_print(&tp_ice->remote_rtp, addr_text, 1578 sizeof(addr_text), 3))); 1579 1580 /* Also update remote RTCP address if actual RTCP source 1581 * address is not heard yet. 1582 */ 1583 if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) { 1584 pj_uint16_t port; 1585 1586 pj_sockaddr_cp(&tp_ice->remote_rtcp, &tp_ice->remote_rtp); 1587 1588 port = (pj_uint16_t) 1589 (pj_sockaddr_get_port(&tp_ice->remote_rtp)+1); 1590 pj_sockaddr_set_port(&tp_ice->remote_rtcp, port); 1591 1592 PJ_LOG(4,(tp_ice->base.name, 1593 "Remote RTCP address switched to %s", 1594 pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text, 1595 sizeof(addr_text), 3))); 1596 1597 } 1598 } 1599 } 1600 } else if (comp_id==2 && tp_ice->rtcp_cb) { 1518 1601 (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); 1519 1602 1520 PJ_UNUSED_ARG(src_addr); 1603 /* Check if RTCP source address is the same as the configured 1604 * remote address, and switch the address when they are 1605 * different. 1606 */ 1607 if (!tp_ice->ice_inited && 1608 (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0 && 1609 pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) != 0) 1610 { 1611 char addr_text[80]; 1612 1613 pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr); 1614 pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr); 1615 1616 pj_assert(tp_ice->addr_len == pj_sockaddr_get_len(src_addr)); 1617 1618 PJ_LOG(4,(tp_ice->base.name, 1619 "Remote RTCP address switched to %s", 1620 pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text, 1621 sizeof(addr_text), 3))); 1622 } 1623 } 1624 1521 1625 PJ_UNUSED_ARG(src_addr_len); 1522 1626 } 1523 1627