diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-09-26 13:21:02 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-09-26 13:21:02 +0000 |
commit | 506917fa7dfa0cec64586417feb081b6dcf1f97e (patch) | |
tree | 9627c2f90727f171fbe2c82fcb256a6efb8b0c12 /pjsip/src/pjsua-lib | |
parent | decb295824ef9cf2df5683d11b1c40fb6eff6ab5 (diff) |
Added support for specifying IP address in PJSUA-LIB/pjsua.
This option can be used for example to select the IP
interface of SIP/RTP/RTCP transports, or to specify the
public IP address of NAT/router in case port forwarding is
used.
For SIP transports, this feature works for both UDP and
TCP transports.
Changes:
- added public_ip field in pjsua_transport_config, and
change SIP and media transport creation to consider this
option.
- added --ip-addr option in pjsua
- added pjsip_tcp_transport_start2() which allows
specifying alternate TCP published address when creating
TCP transports.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@742 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsua-lib')
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 102 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 29 |
2 files changed, 116 insertions, 15 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index d26094ab..6b39fdbb 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -798,6 +798,9 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, * the name of local host. */ if (stun.stun_srv1.slen) { + /* + * STUN is specified, resolve the address with STUN. + */ status = pj_stun_get_mapped_addr(&pjsua_var.cp.factory, 1, &sock, &stun.stun_srv1, stun.stun_port1, @@ -810,6 +813,13 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, return status; } + } else if (p_pub_addr->sin_addr.s_addr != 0) { + /* + * Public address is already specified, no need to resolve the + * address, only set the port. + */ + /* Do nothing */ + } else { pj_bzero(p_pub_addr, sizeof(pj_sockaddr_in)); @@ -866,6 +876,7 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, */ pjsua_transport_config config; pj_sock_t sock = PJ_INVALID_SOCKET; + pj_sockaddr_in bound_addr; pj_sockaddr_in pub_addr; pjsip_host_port addr_name; @@ -875,9 +886,36 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, cfg = &config; } - /* Create the socket and possibly resolve the address with STUN */ - status = create_sip_udp_sock(cfg->ip_addr, cfg->port, cfg->use_stun, - &cfg->stun_config, &sock, &pub_addr); + /* Initialize bound address, if any */ + bound_addr.sin_addr.s_addr = PJ_INADDR_ANY; + if (cfg->bound_addr.slen) { + status = pj_sockaddr_in_set_str_addr(&bound_addr,&cfg->bound_addr); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, + "Unable to resolve transport bound address", + status); + goto on_return; + } + } + + /* Initialize the public address from the config, if any */ + pj_sockaddr_in_init(&pub_addr, NULL, (pj_uint16_t)cfg->port); + if (cfg->public_addr.slen) { + status = pj_sockaddr_in_set_str_addr(&pub_addr, &cfg->public_addr); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, + "Unable to resolve transport public address", + status); + goto on_return; + } + } + + /* Create the socket and possibly resolve the address with STUN + * (only when public address is not specified). + */ + status = create_sip_udp_sock(bound_addr.sin_addr, cfg->port, + cfg->use_stun, &cfg->stun_config, + &sock, &pub_addr); if (status != PJ_SUCCESS) goto on_return; @@ -906,6 +944,7 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, * Create TCP transport. */ pjsua_transport_config config; + pjsip_host_port a_name; pjsip_tpfactory *tcp; pj_sockaddr_in local_addr; @@ -921,12 +960,24 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, if (cfg->port) local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port); - if (cfg->ip_addr.s_addr) - local_addr.sin_addr.s_addr = cfg->ip_addr.s_addr; + if (cfg->bound_addr.slen) { + status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, + "Unable to resolve transport bound address", + status); + goto on_return; + } + } + + /* Init published name */ + pj_bzero(&a_name, sizeof(pjsip_host_port)); + if (cfg->public_addr.slen) + a_name.host = cfg->public_addr; /* Create the TCP transport */ - status = pjsip_tcp_transport_start(pjsua_var.endpt, &local_addr, 1, - &tcp); + status = pjsip_tcp_transport_start2(pjsua_var.endpt, &local_addr, + &a_name, 1, &tcp); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating SIP TCP listener", @@ -1029,6 +1080,7 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id, pjsua_transport_info *info) { struct transport_data *t = &pjsua_var.tpdata[id]; + pj_status_t status; pj_bzero(info, sizeof(*info)); @@ -1059,6 +1111,8 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id, info->local_name = tp->local_name; info->usage_count = pj_atomic_get(tp->ref_cnt); + status = PJ_SUCCESS; + } else if (pjsua_var.tpdata[id].type == PJSIP_TRANSPORT_TCP) { pjsip_tpfactory *factory = t->data.factory; @@ -1078,12 +1132,17 @@ PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id, info->local_name = factory->addr_name; info->usage_count = 0; + status = PJ_SUCCESS; + + } else { + pj_assert(!"Unsupported transport"); + status = PJ_EINVALIDOP; } PJSUA_UNLOCK(); - return PJ_EINVALIDOP; + return status; } @@ -1120,12 +1179,29 @@ 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); + /* Note: destroy() may not work if there are objects still referencing + * the transport. + */ + if (force) { + switch (pjsua_var.tpdata[id].type) { + case PJSIP_TRANSPORT_UDP: + return pjsip_transport_destroy(pjsua_var.tpdata[id].data.tp); + case PJSIP_TRANSPORT_TCP: + break; + } + + } else { + switch (pjsua_var.tpdata[id].type) { + case PJSIP_TRANSPORT_UDP: + return pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp); + case PJSIP_TRANSPORT_TCP: + return (*pjsua_var.tpdata[id].data.factory->destroy) + (pjsua_var.tpdata[id].data.factory); + } + } - /* To be done!! */ - PJ_UNUSED_ARG(force); - - PJ_TODO(pjsua_transport_close); - + /* Unreachable */ + pj_assert(!"Unknown transport"); return PJ_EINVALIDOP; } diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index e37275a2..13ff542c 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -209,6 +209,7 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, }; int i; static pj_uint16_t rtp_port; + pj_sockaddr_in bound_addr; pj_sockaddr_in mapped_addr[2]; pj_status_t status = PJ_SUCCESS; pj_sock_t sock[2]; @@ -219,6 +220,15 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, for (i=0; i<2; ++i) sock[i] = PJ_INVALID_SOCKET; + bound_addr.sin_addr.s_addr = PJ_INADDR_ANY; + if (cfg->bound_addr.slen) { + status = pj_sockaddr_in_set_str_addr(&bound_addr, &cfg->bound_addr); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to resolve transport bind address", + status); + return status; + } + } /* Loop retry to bind RTP and RTCP sockets. */ for (i=0; i<RTP_RETRY; ++i, rtp_port += 2) { @@ -230,7 +240,8 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, return status; } - status = pj_sock_bind_in(sock[0], cfg->ip_addr.s_addr, rtp_port); + status = pj_sock_bind_in(sock[0], bound_addr.sin_addr.s_addr, + rtp_port); if (status != PJ_SUCCESS) { pj_sock_close(sock[0]); sock[0] = PJ_INVALID_SOCKET; @@ -245,7 +256,7 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, return status; } - status = pj_sock_bind_in(sock[1], cfg->ip_addr.s_addr, + status = pj_sock_bind_in(sock[1], bound_addr.sin_addr.s_addr, (pj_uint16_t)(rtp_port+1)); if (status != PJ_SUCCESS) { pj_sock_close(sock[0]); @@ -285,6 +296,20 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, pj_sock_close(sock[1]); sock[1] = PJ_INVALID_SOCKET; + } else if (cfg->public_addr.slen) { + + status = pj_sockaddr_in_init(&mapped_addr[0], &cfg->public_addr, + (pj_uint16_t)rtp_port); + if (status != PJ_SUCCESS) + goto on_error; + + status = pj_sockaddr_in_init(&mapped_addr[1], &cfg->public_addr, + (pj_uint16_t)(rtp_port+1)); + if (status != PJ_SUCCESS) + goto on_error; + + break; + } else { pj_in_addr addr; |