Fixed #1921: Add support to handle IPv6 transports in pjsua_transport API and transport keep alive

Also:
- add more detailed transport info for TCP and TLS transport
- fixed pjsua sample app which tries to get IPv4 local address from IPv6 transport.



git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5308 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Sauw Ming 2016-05-19 06:55:16 +00:00
parent 6fbf7ce59b
commit 4048dad7c5
6 changed files with 45 additions and 15 deletions

View File

@ -1664,12 +1664,9 @@ static pj_status_t app_init()
if (app_config.udp_cfg.port == 0) {
pjsua_transport_info ti;
pj_sockaddr_in *a;
pjsua_transport_get_info(transport_id, &ti);
a = (pj_sockaddr_in*)&ti.local_addr;
tcp_cfg.port = pj_ntohs(a->sin_port);
tcp_cfg.port = pj_sockaddr_get_port(&ti.local_addr);
}
}

View File

@ -994,6 +994,7 @@ struct pjsip_tpfactory
pjsip_transport_type_e type; /**< Transport type. */
char *type_name; /**< Type string name. */
unsigned flag; /**< Transport flag. */
char *info; /**< Transport info/description.*/
pj_sockaddr local_addr; /**< Bound address. */
pjsip_host_port addr_name; /**< Published name. */

View File

@ -251,6 +251,8 @@ PJ_DEF(pj_status_t) pjsip_tcp_transport_start3(
pjsip_tpfactory **p_factory
)
{
enum { INFO_LEN = 100 };
char local_addr[PJ_INET6_ADDRSTRLEN+10];
pj_pool_t *pool;
pj_sock_t sock = PJ_INVALID_SOCKET;
struct tcp_listener *listener;
@ -474,6 +476,19 @@ PJ_DEF(pj_status_t) pjsip_tcp_transport_start3(
#endif
/* Set transport info. */
if (listener->factory.info == NULL) {
listener->factory.info = (char*) pj_pool_alloc(listener->factory.pool,
INFO_LEN);
}
pj_sockaddr_print(listener_addr, local_addr, sizeof(local_addr), 3);
pj_ansi_snprintf(
listener->factory.info, INFO_LEN, "tcp %s [published as %.*s:%d]",
local_addr,
(int)listener->factory.addr_name.host.slen,
listener->factory.addr_name.host.ptr,
listener->factory.addr_name.port);
if (has_listener) {
PJ_LOG(4,(listener->factory.obj_name,
"SIP TCP listener ready for incoming connections at %.*s:%d",

View File

@ -309,6 +309,8 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
unsigned async_cnt,
pjsip_tpfactory **p_factory)
{
enum { INFO_LEN = 100 };
char local_addr[PJ_INET6_ADDRSTRLEN+10];
pj_pool_t *pool;
pj_bool_t is_ipv6;
int af, sip_ssl_method;
@ -546,6 +548,19 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
goto on_error;
}
/* Set transport info. */
if (listener->factory.info == NULL) {
listener->factory.info = (char*) pj_pool_alloc(listener->factory.pool,
INFO_LEN);
}
pj_sockaddr_print(listener_addr, local_addr, sizeof(local_addr), 3);
pj_ansi_snprintf(
listener->factory.info, INFO_LEN, "tls %s [published as %.*s:%d]",
local_addr,
(int)listener->factory.addr_name.host.slen,
listener->factory.addr_name.host.ptr,
listener->factory.addr_name.port);
if (has_listener) {
PJ_LOG(4,(listener->factory.obj_name,
"SIP TLS listener is ready for incoming connections "

View File

@ -1944,7 +1944,7 @@ static void keep_alive_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te)
/* Send raw packet */
status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(pjsua_var.endpt),
PJSIP_TRANSPORT_UDP, &tp_sel,
acc->ka_transport->key.type, &tp_sel,
NULL, acc->cfg.ka_data.ptr,
acc->cfg.ka_data.slen,
&acc->ka_target, acc->ka_target_len,
@ -2011,7 +2011,8 @@ static void update_keep_alive(pjsua_acc *acc, pj_bool_t start,
*/
if (/*pjsua_var.stun_srv.ipv4.sin_family == 0 ||*/
acc->cfg.ka_interval == 0 ||
param->rdata->tp_info.transport->key.type != PJSIP_TRANSPORT_UDP)
(param->rdata->tp_info.transport->key.type & PJSIP_TRANSPORT_UDP)!=
PJSIP_TRANSPORT_UDP)
{
/* Keep alive is not necessary */
return;

View File

@ -2447,7 +2447,7 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id,
PJSUA_LOCK();
if (t->type == PJSIP_TRANSPORT_UDP) {
if ((t->type & PJSIP_TRANSPORT_UDP) == PJSIP_TRANSPORT_UDP) {
pjsip_transport *tp = t->data.tp;
@ -2468,8 +2468,8 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id,
status = PJ_SUCCESS;
} else if (t->type == PJSIP_TRANSPORT_TCP ||
t->type == PJSIP_TRANSPORT_TLS)
} else if ((t->type & PJSIP_TRANSPORT_TCP) == PJSIP_TRANSPORT_TCP ||
(t->type & PJSIP_TRANSPORT_TLS) == PJSIP_TRANSPORT_TLS)
{
pjsip_tpfactory *factory = t->data.factory;
@ -2481,10 +2481,8 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id,
info->id = id;
info->type = t->type;
info->type_name = (t->type==PJSIP_TRANSPORT_TCP)? pj_str("TCP"):
pj_str("TLS");
info->info = (t->type==PJSIP_TRANSPORT_TCP)? pj_str("TCP transport"):
pj_str("TLS transport");
info->type_name = pj_str(factory->type_name);
info->info = pj_str(factory->info);
info->flag = factory->flag;
info->addr_len = sizeof(factory->local_addr);
info->local_addr = factory->local_addr;
@ -2534,6 +2532,7 @@ PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
pj_bool_t force )
{
pj_status_t status;
pjsip_transport_type_e tp_type;
/* Make sure id is in range. */
PJ_ASSERT_RETURN(id>=0 && id<(int)PJ_ARRAY_SIZE(pjsua_var.tpdata),
@ -2542,11 +2541,13 @@ PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
/* Make sure that transport exists */
PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);
tp_type = pjsua_var.tpdata[id].type & ~PJSIP_TRANSPORT_IPV6;
/* Note: destroy() may not work if there are objects still referencing
* the transport.
*/
if (force) {
switch (pjsua_var.tpdata[id].type) {
switch (tp_type) {
case PJSIP_TRANSPORT_UDP:
status = pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
if (status != PJ_SUCCESS)
@ -2579,7 +2580,7 @@ PJ_DEF(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
* transport is closed thus it can't cleanup PJSUA transport
* descriptor.
*/
switch (pjsua_var.tpdata[id].type) {
switch (tp_type) {
case PJSIP_TRANSPORT_UDP:
return pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
case PJSIP_TRANSPORT_TLS: