summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsua-lib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2012-09-20 06:00:23 +0000
committerBenny Prijono <bennylp@teluu.com>2012-09-20 06:00:23 +0000
commitc1da22781bc970d7948f35e5fa6ede7b54f45549 (patch)
tree238d85c1b6e1375c207486e9f2c2f22188ae49ca /pjsip/src/pjsua-lib
parent8a001ec6f6a9c628eff9fbd9c9a478d127ed12d3 (diff)
Fixed #1585: IPv6 support for SIP TCP and TLS transports and PJSUA-LIB v2
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4262 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsua-lib')
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c23
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c94
3 files changed, 73 insertions, 46 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index caad41b6..105e24d1 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -1190,6 +1190,8 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
acc->cfg.rtp_cfg = cfg->rtp_cfg;
}
+ acc->cfg.ipv6_media_use = cfg->ipv6_media_use;
+
/* STUN and Media customization */
if (acc->cfg.sip_stun_use != cfg->sip_stun_use) {
acc->cfg.sip_stun_use = cfg->sip_stun_use;
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index f0b44119..fd6ab3bf 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -2067,8 +2067,10 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type,
pjsua_transport_config config;
pjsip_tpfactory *tcp;
pjsip_tcp_transport_cfg tcp_cfg;
+ int af;
- pjsip_tcp_transport_cfg_default(&tcp_cfg, pj_AF_INET());
+ af = (type==PJSIP_TRANSPORT_TCP6) ? pj_AF_INET6() : pj_AF_INET();
+ pjsip_tcp_transport_cfg_default(&tcp_cfg, af);
/* Supply default config if it's not specified */
if (cfg == NULL) {
@@ -2118,14 +2120,15 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type,
#endif /* PJ_HAS_TCP */
#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0
- } else if (type == PJSIP_TRANSPORT_TLS) {
+ } else if (type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_TLS6) {
/*
* Create TLS transport.
*/
pjsua_transport_config config;
pjsip_host_port a_name;
pjsip_tpfactory *tls;
- pj_sockaddr_in local_addr;
+ pj_sockaddr local_addr;
+ int af;
/* Supply default config if it's not specified */
if (cfg == NULL) {
@@ -2135,13 +2138,15 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type,
}
/* Init local address */
- pj_sockaddr_in_init(&local_addr, 0, 0);
+ af = (type==PJSIP_TRANSPORT_TLS) ? pj_AF_INET() : pj_AF_INET6();
+ pj_sockaddr_init(af, &local_addr, NULL, 0);
if (cfg->port)
- local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port);
+ pj_sockaddr_set_port(&local_addr, (pj_uint16_t)cfg->port);
if (cfg->bound_addr.slen) {
- status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr);
+ status = pj_sockaddr_set_str_addr(af, &local_addr,
+ &cfg->bound_addr);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE,
"Unable to resolve transport bound address",
@@ -2155,9 +2160,9 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type,
if (cfg->public_addr.slen)
a_name.host = cfg->public_addr;
- status = pjsip_tls_transport_start(pjsua_var.endpt,
- &cfg->tls_setting,
- &local_addr, &a_name, 1, &tls);
+ status = pjsip_tls_transport_start2(pjsua_var.endpt,
+ &cfg->tls_setting,
+ &local_addr, &a_name, 1, &tls);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error creating SIP TLS listener",
status);
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 483df783..3c1d16e8 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -236,14 +236,20 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
RTP_RETRY = 100
};
int i;
- pj_sockaddr_in bound_addr;
- pj_sockaddr_in mapped_addr[2];
+ pj_bool_t use_ipv6;
+ int af;
+ pj_sockaddr bound_addr;
+ pj_sockaddr mapped_addr[2];
pj_status_t status = PJ_SUCCESS;
- char addr_buf[PJ_INET6_ADDRSTRLEN+2];
+ char addr_buf[PJ_INET6_ADDRSTRLEN+10];
pj_sock_t sock[2];
+ use_ipv6 = (pjsua_var.acc[call_med->call->acc_id].cfg.ipv6_media_use !=
+ PJSUA_IPV6_DISABLED);
+ af = use_ipv6 ? pj_AF_INET6() : pj_AF_INET();
+
/* Make sure STUN server resolution has completed */
- if (pjsua_sip_acc_is_using_stun(call_med->call->acc_id)) {
+ if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id)) {
status = resolve_stun_server(PJ_TRUE);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
@@ -260,9 +266,9 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
for (i=0; i<2; ++i)
sock[i] = PJ_INVALID_SOCKET;
- bound_addr.sin_addr.s_addr = PJ_INADDR_ANY;
+ pj_sockaddr_init(af, &bound_addr, NULL, 0);
if (cfg->bound_addr.slen) {
- status = pj_sockaddr_in_set_str_addr(&bound_addr, &cfg->bound_addr);
+ status = pj_sockaddr_set_str_addr(af, &bound_addr, &cfg->bound_addr);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to resolve transport bind address",
status);
@@ -274,7 +280,7 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
for (i=0; i<RTP_RETRY; ++i, next_rtp_port += 2) {
/* Create RTP socket. */
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock[0]);
+ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[0]);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "socket() error", status);
return status;
@@ -286,8 +292,9 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
2, THIS_FILE, "RTP socket");
/* Bind RTP socket */
- status=pj_sock_bind_in(sock[0], pj_ntohl(bound_addr.sin_addr.s_addr),
- next_rtp_port);
+ pj_sockaddr_set_port(&bound_addr, next_rtp_port);
+ status=pj_sock_bind(sock[0], &bound_addr,
+ pj_sockaddr_get_len(&bound_addr));
if (status != PJ_SUCCESS) {
pj_sock_close(sock[0]);
sock[0] = PJ_INVALID_SOCKET;
@@ -295,7 +302,7 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
}
/* Create RTCP socket. */
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock[1]);
+ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[1]);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "socket() error", status);
pj_sock_close(sock[0]);
@@ -308,8 +315,9 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
2, THIS_FILE, "RTCP socket");
/* Bind RTCP socket */
- status=pj_sock_bind_in(sock[1], pj_ntohl(bound_addr.sin_addr.s_addr),
- (pj_uint16_t)(next_rtp_port+1));
+ pj_sockaddr_set_port(&bound_addr, (pj_uint16_t)(next_rtp_port+1));
+ status=pj_sock_bind(sock[1], &bound_addr,
+ pj_sockaddr_get_len(&bound_addr));
if (status != PJ_SUCCESS) {
pj_sock_close(sock[0]);
sock[0] = PJ_INVALID_SOCKET;
@@ -323,11 +331,12 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
* If we're configured to use STUN, then find out the mapped address,
* and make sure that the mapped RTCP port is adjacent with the RTP.
*/
- if (pjsua_sip_acc_is_using_stun(call_med->call->acc_id) &&
+ if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id) &&
pjsua_var.stun_srv.addr.sa_family != 0)
{
char ip_addr[32];
pj_str_t stun_srv;
+ pj_sockaddr_in resolved_addr[2];
pjstun_setting stun_opt;
pj_ansi_strcpy(ip_addr,
@@ -340,15 +349,18 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
stun_opt.port1 = stun_opt.port2 =
pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port);
status=pjstun_get_mapped_addr2(&pjsua_var.cp.factory, &stun_opt,
- 2, sock, mapped_addr);
+ 2, sock, resolved_addr);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "STUN resolve error", status);
goto on_error;
}
+ pj_sockaddr_cp(&mapped_addr[0], &resolved_addr[0]);
+ pj_sockaddr_cp(&mapped_addr[1], &resolved_addr[1]);
+
#if PJSUA_REQUIRE_CONSECUTIVE_RTCP_PORT
- if (pj_ntohs(mapped_addr[1].sin_port) ==
- pj_ntohs(mapped_addr[0].sin_port)+1)
+ if (pj_sockaddr_get_port(&mapped_addr[1]) ==
+ pj_sockaddr_get_port(&mapped_addr[0])+1)
{
/* Success! */
break;
@@ -360,14 +372,14 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
pj_sock_close(sock[1]);
sock[1] = PJ_INVALID_SOCKET;
#else
- if (pj_ntohs(mapped_addr[1].sin_port) !=
- pj_ntohs(mapped_addr[0].sin_port)+1)
+ if (pj_sockaddr_get_port(&mapped_addr[1]) !=
+ pj_sockaddr_get_port(&mapped_addr[0])+1)
{
PJ_LOG(4,(THIS_FILE,
"Note: STUN mapped RTCP port %d is not adjacent"
" to RTP port %d",
- pj_ntohs(mapped_addr[1].sin_port),
- pj_ntohs(mapped_addr[0].sin_port)));
+ pj_sockaddr_get_port(&mapped_addr[1]),
+ pj_sockaddr_get_port(&mapped_addr[0])));
}
/* Success! */
break;
@@ -375,13 +387,13 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
} else if (cfg->public_addr.slen) {
- status = pj_sockaddr_in_init(&mapped_addr[0], &cfg->public_addr,
- (pj_uint16_t)next_rtp_port);
+ status = pj_sockaddr_init(af, &mapped_addr[0], &cfg->public_addr,
+ (pj_uint16_t)next_rtp_port);
if (status != PJ_SUCCESS)
goto on_error;
- status = pj_sockaddr_in_init(&mapped_addr[1], &cfg->public_addr,
- (pj_uint16_t)(next_rtp_port+1));
+ status = pj_sockaddr_init(af, &mapped_addr[1], &cfg->public_addr,
+ (pj_uint16_t)(next_rtp_port+1));
if (status != PJ_SUCCESS)
goto on_error;
@@ -389,24 +401,24 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
} else {
- if (bound_addr.sin_addr.s_addr == 0) {
+ if (!pj_sockaddr_has_addr(&bound_addr)) {
pj_sockaddr addr;
/* Get local IP address. */
- status = pj_gethostip(pj_AF_INET(), &addr);
+ status = pj_gethostip(af, &addr);
if (status != PJ_SUCCESS)
goto on_error;
- bound_addr.sin_addr.s_addr = addr.ipv4.sin_addr.s_addr;
+ pj_sockaddr_copy_addr(&bound_addr, &addr);
}
for (i=0; i<2; ++i) {
- pj_sockaddr_in_init(&mapped_addr[i], NULL, 0);
- mapped_addr[i].sin_addr.s_addr = bound_addr.sin_addr.s_addr;
+ pj_sockaddr_init(af, &mapped_addr[i], NULL, 0);
+ pj_sockaddr_copy_addr(&mapped_addr[i], &bound_addr);
+ pj_sockaddr_set_port(&mapped_addr[i],
+ (pj_uint16_t)(next_rtp_port+i));
}
- mapped_addr[0].sin_port=pj_htons((pj_uint16_t)next_rtp_port);
- mapped_addr[1].sin_port=pj_htons((pj_uint16_t)(next_rtp_port+1));
break;
}
}
@@ -419,12 +431,10 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
skinfo->rtp_sock = sock[0];
- pj_memcpy(&skinfo->rtp_addr_name,
- &mapped_addr[0], sizeof(pj_sockaddr_in));
+ pj_sockaddr_cp(&skinfo->rtp_addr_name, &mapped_addr[0]);
skinfo->rtcp_sock = sock[1];
- pj_memcpy(&skinfo->rtcp_addr_name,
- &mapped_addr[1], sizeof(pj_sockaddr_in));
+ pj_sockaddr_cp(&skinfo->rtcp_addr_name, &mapped_addr[1]);
PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s",
pj_sockaddr_print(&skinfo->rtp_addr_name, addr_buf,
@@ -1908,10 +1918,20 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
/* Add connection line, if none */
if (m->conn == NULL && sdp->conn == NULL) {
+ pj_bool_t use_ipv6;
+
+ use_ipv6 = (pjsua_var.acc[call->acc_id].cfg.ipv6_media_use !=
+ PJSUA_IPV6_DISABLED);
+
m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
m->conn->net_type = pj_str("IN");
- m->conn->addr_type = pj_str("IP4");
- m->conn->addr = pj_str("127.0.0.1");
+ if (use_ipv6) {
+ m->conn->addr_type = pj_str("IP6");
+ m->conn->addr = pj_str("::1");
+ } else {
+ m->conn->addr_type = pj_str("IP4");
+ m->conn->addr = pj_str("127.0.0.1");
+ }
}
sdp->media[sdp->media_count++] = m;