diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2016-11-14 06:13:01 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2016-11-14 06:13:01 +0000 |
commit | e297e570a9b9eebe2209f3013972d560eae31f1a (patch) | |
tree | a8b2d7ffda16c83b6ff42649cecb62ea584058f0 | |
parent | 5edcbe5108e722951f3dc1f6453a33d25184973c (diff) |
Re #1971: Request IPv4 relay address to an IPv6 TURN server for IPv6-IPv4 connectivity.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5481 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjnath/include/pjnath/config.h | 2 | ||||
-rw-r--r-- | pjnath/include/pjnath/turn_session.h | 10 | ||||
-rw-r--r-- | pjnath/src/pjnath/ice_strans.c | 15 | ||||
-rw-r--r-- | pjnath/src/pjnath/turn_session.c | 33 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 31 |
5 files changed, 81 insertions, 10 deletions
diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h index d5f69164..90dde5f3 100644 --- a/pjnath/include/pjnath/config.h +++ b/pjnath/include/pjnath/config.h @@ -263,7 +263,7 @@ * Default: 2 */ #ifndef PJ_ICE_MAX_TURN -# define PJ_ICE_MAX_TURN 2 +# define PJ_ICE_MAX_TURN 3 #endif diff --git a/pjnath/include/pjnath/turn_session.h b/pjnath/include/pjnath/turn_session.h index e4ae4d7b..cc3d5d8d 100644 --- a/pjnath/include/pjnath/turn_session.h +++ b/pjnath/include/pjnath/turn_session.h @@ -330,6 +330,16 @@ typedef struct pj_turn_alloc_param */ int ka_interval; + /** + * The requested ADDRESS-FAMILY. Default is zero to request relay with + * address family matched to the one specified in TURN session creation. + * Valid values are zero, pj_AF_INET(), and pj_AF_INET6(). + * + * Default value is zero. + */ + int af; + + } pj_turn_alloc_param; diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c index 19e3bb12..1b0148de 100644 --- a/pjnath/src/pjnath/ice_strans.c +++ b/pjnath/src/pjnath/ice_strans.c @@ -1991,6 +1991,21 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, /* Set default candidate to relay */ comp->default_cand = (unsigned)(cand - comp->cand_list); + /* Prefer IPv4 relay as default candidate for better connectivity + * with IPv4 endpoints. + */ + if (cand->addr.addr.sa_family != pj_AF_INET()) { + for (i=0; i<comp->cand_cnt; ++i) { + if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && + comp->cand_list[i].addr.addr.sa_family == pj_AF_INET() && + comp->cand_list[i].status == PJ_SUCCESS) + { + comp->default_cand = i; + break; + } + } + } + PJ_LOG(4,(comp->ice_st->obj_name, "Comp %d: TURN allocation complete, relay address is %s", comp->comp_id, diff --git a/pjnath/src/pjnath/turn_session.c b/pjnath/src/pjnath/turn_session.c index 521bf978..d3ff6ced 100644 --- a/pjnath/src/pjnath/turn_session.c +++ b/pjnath/src/pjnath/turn_session.c @@ -724,6 +724,12 @@ PJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, sess->state<=PJ_TURN_STATE_RESOLVED, PJ_EINVALIDOP); + /* Verify address family in allocation param */ + if (param && param->af) { + PJ_ASSERT_RETURN(param->af==pj_AF_INET() || param->af==pj_AF_INET6(), + PJ_EINVAL); + } + pj_grp_lock_acquire(sess->grp_lock); if (param && param != &sess->alloc_param) @@ -770,11 +776,21 @@ PJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, sess->alloc_param.lifetime); } - /* Include ADDRESS-FAMILY for IPv6 request */ - if (sess->af == pj_AF_INET6()) { - enum { IPV6_AF_TYPE = 0x02 << 24 }; - pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, - PJ_STUN_ATTR_REQ_ADDR_TYPE, IPV6_AF_TYPE); + /* Include ADDRESS-FAMILY if requested */ + if (sess->alloc_param.af || sess->af == pj_AF_INET6()) { + enum { IPV4_AF_TYPE = 0x01 << 24, + IPV6_AF_TYPE = 0x02 << 24 }; + + if (sess->alloc_param.af == pj_AF_INET6() || + (sess->alloc_param.af == 0 && sess->af == pj_AF_INET6())) + { + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REQ_ADDR_TYPE, IPV6_AF_TYPE); + } else if (sess->alloc_param.af == pj_AF_INET()) { + /* For IPv4, only add the attribute when explicitly requested */ + pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, + PJ_STUN_ATTR_REQ_ADDR_TYPE, IPV4_AF_TYPE); + } } /* Server address must be set */ @@ -1358,7 +1374,12 @@ static void on_allocate_success(pj_turn_session *sess, "RELAY-ADDRESS attribute")); return; } - if (raddr_attr && raddr_attr->sockaddr.addr.sa_family != sess->af) { + if (raddr_attr && + ((sess->alloc_param.af != 0 && + raddr_attr->sockaddr.addr.sa_family != sess->alloc_param.af) || + (sess->alloc_param.af == 0 && + raddr_attr->sockaddr.addr.sa_family != sess->af))) + { on_session_fail(sess, method, PJNATH_EINSTUNMSG, pj_cstr(&s, "Error: Mismatched RELAY-ADDRESS " "address family")); diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index a2dfc118..8bca8700 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -926,10 +926,16 @@ static pj_status_t create_ice_media_transport( if (acc_cfg->turn_cfg.enable_turn) { ice_cfg.turn_tp_cnt = 1; pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[0]); - if (use_ipv6 && PJ_ICE_MAX_TURN >= 2) { - ice_cfg.turn_tp_cnt = 2; + if (use_ipv6 && PJ_ICE_MAX_TURN >= 3) { + ice_cfg.turn_tp_cnt = 3; + pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[1]); ice_cfg.turn_tp[1].af = pj_AF_INET6(); + + /* Additional candidate: IPv4 relay via IPv6 TURN server */ + pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[2]); + ice_cfg.turn_tp[2].af = pj_AF_INET6(); + ice_cfg.turn_tp[2].alloc_param.af = pj_AF_INET(); } /* Configure TURN server */ @@ -956,6 +962,13 @@ static pj_status_t create_ice_media_transport( pj_memcpy(&ice_cfg.turn_tp[1].auth_cred, &acc_cfg->turn_cfg.turn_auth_cred, sizeof(ice_cfg.turn_tp[1].auth_cred)); + + ice_cfg.turn_tp[2].server = ice_cfg.turn_tp[0].server; + ice_cfg.turn_tp[2].port = ice_cfg.turn_tp[0].port; + ice_cfg.turn_tp[2].conn_type = ice_cfg.turn_tp[0].conn_type; + pj_memcpy(&ice_cfg.turn_tp[2].auth_cred, + &acc_cfg->turn_cfg.turn_auth_cred, + sizeof(ice_cfg.turn_tp[2].auth_cred)); } /* Configure QoS setting */ @@ -966,6 +979,10 @@ static pj_status_t create_ice_media_transport( ice_cfg.turn_tp[1].cfg.qos_type = cfg->qos_type; pj_memcpy(&ice_cfg.turn_tp[1].cfg.qos_params, &cfg->qos_params, sizeof(cfg->qos_params)); + + ice_cfg.turn_tp[2].cfg.qos_type = cfg->qos_type; + pj_memcpy(&ice_cfg.turn_tp[2].cfg.qos_params, &cfg->qos_params, + sizeof(cfg->qos_params)); } /* Configure binding address */ @@ -983,12 +1000,20 @@ static pj_status_t create_ice_media_transport( &IN6_ADDR_ANY, (pj_uint16_t)cfg->port); ice_cfg.turn_tp[1].cfg.port_range = ice_cfg.turn_tp[0].cfg.port_range; + + pj_sockaddr_init(pj_AF_INET6(), + &ice_cfg.turn_tp[2].cfg.bound_addr, + &IN6_ADDR_ANY, (pj_uint16_t)cfg->port); + ice_cfg.turn_tp[2].cfg.port_range = + ice_cfg.turn_tp[0].cfg.port_range; } /* Configure max packet size */ ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; - if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) + if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) { ice_cfg.turn_tp[1].cfg.max_pkt_size = PJMEDIA_MAX_MRU; + ice_cfg.turn_tp[2].cfg.max_pkt_size = PJMEDIA_MAX_MRU; + } } pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb)); |