diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-12-01 08:59:25 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-12-01 08:59:25 +0000 |
commit | 223903c913565d00e54b55f9685a174f1f31ed49 (patch) | |
tree | c87466c8a333649fb6ca436199bd6f4f217d527c /pjsip/src/pjsua-lib | |
parent | 2e6a62f43b622320d69971cfc07a68ab59e29f1b (diff) |
Ticket #421: initial IPv6 support: UDP transport
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1602 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsua-lib')
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 114 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 6 |
2 files changed, 72 insertions, 48 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 578425e2..39a71f8e 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -1182,17 +1182,32 @@ PJ_DEF(pj_pool_factory*) pjsua_get_pool_factory(void) */ /* + * Tools to get address string. + */ +static const char *addr_string(const pj_sockaddr_t *addr) +{ + static char str[128]; + str[0] = '\0'; + pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family, + pj_sockaddr_get_addr(addr), + str, sizeof(str)); + return str; +} + +/* * Create and initialize SIP socket (and possibly resolve public * address via STUN, depending on config). */ -static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, +static pj_status_t create_sip_udp_sock(int af, + const pj_str_t *bind_param, int port, pj_sock_t *p_sock, - pj_sockaddr_in *p_pub_addr) + pj_sockaddr *p_pub_addr) { - char ip_addr[32]; + char stun_ip_addr[PJ_INET6_ADDRSTRLEN]; pj_str_t stun_srv; pj_sock_t sock; + pj_sockaddr bind_addr; pj_status_t status; /* Make sure STUN server resolution has completed */ @@ -1202,14 +1217,27 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, return status; } - status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock); + /* Initialize bound address */ + if (bind_param->slen) { + status = pj_sockaddr_init(af, &bind_addr, bind_param, + (pj_uint16_t)port); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, + "Unable to resolve transport bound address", + status); + return status; + } + } else { + pj_sockaddr_init(af, &bind_addr, NULL, (pj_uint16_t)port); + } + + status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "socket() error", status); return status; } - status = pj_sock_bind_in(sock, pj_ntohl(bound_addr.s_addr), - (pj_uint16_t)port); + status = pj_sock_bind(sock, &bind_addr, sizeof(bind_addr)); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "bind() error", status); pj_sock_close(sock); @@ -1218,7 +1246,7 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, /* If port is zero, get the bound port */ if (port == 0) { - pj_sockaddr_in bound_addr; + pj_sockaddr bound_addr; int namelen = sizeof(bound_addr); status = pj_sock_getsockname(sock, &bound_addr, &namelen); if (status != PJ_SUCCESS) { @@ -1227,12 +1255,12 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, return status; } - port = pj_ntohs(bound_addr.sin_port); + port = pj_sockaddr_get_port(&bound_addr); } if (pjsua_var.stun_srv.addr.sa_family != 0) { - pj_ansi_strcpy(ip_addr,pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr)); - stun_srv = pj_str(ip_addr); + pj_ansi_strcpy(stun_ip_addr,pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr)); + stun_srv = pj_str(stun_ip_addr); } else { stun_srv.slen = 0; } @@ -1240,22 +1268,28 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, /* Get the published address, either by STUN or by resolving * the name of local host. */ - if (p_pub_addr->sin_addr.s_addr != 0) { + if (pj_sockaddr_has_addr(p_pub_addr)) { /* * Public address is already specified, no need to resolve the * address, only set the port. */ - if (p_pub_addr->sin_port == 0) - p_pub_addr->sin_port = pj_htons((pj_uint16_t)port); + if (pj_sockaddr_get_port(p_pub_addr) == 0) + pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port); } else if (stun_srv.slen) { /* * STUN is specified, resolve the address with STUN. */ + if (af != pj_AF_INET()) { + pjsua_perror(THIS_FILE, "Cannot use STUN", PJ_EAFNOTSUP); + pj_sock_close(sock); + return PJ_EAFNOTSUP; + } + status = pjstun_get_mapped_addr(&pjsua_var.cp.factory, 1, &sock, &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port), &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port), - p_pub_addr); + &p_pub_addr->ipv4); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error contacting STUN server", status); pj_sock_close(sock); @@ -1263,25 +1297,24 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, } } else { + pj_bzero(p_pub_addr, sizeof(pj_sockaddr)); - pj_bzero(p_pub_addr, sizeof(pj_sockaddr_in)); - - status = pj_gethostip(&p_pub_addr->sin_addr); + status = pj_gethostip(af, p_pub_addr); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to get local host IP", status); pj_sock_close(sock); return status; } - p_pub_addr->sin_family = pj_AF_INET(); - p_pub_addr->sin_port = pj_htons((pj_uint16_t)port); + p_pub_addr->addr.sa_family = (pj_uint16_t)af; + pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port); } *p_sock = sock; PJ_LOG(4,(THIS_FILE, "SIP UDP socket reachable at %s:%d", - pj_inet_ntoa(p_pub_addr->sin_addr), - (int)pj_ntohs(p_pub_addr->sin_port))); + addr_string(p_pub_addr), + (int)pj_sockaddr_get_port(p_pub_addr))); return PJ_SUCCESS; } @@ -1313,14 +1346,14 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, } /* Create the transport */ - if (type == PJSIP_TRANSPORT_UDP) { + if (type & PJSIP_TRANSPORT_UDP) { /* - * Create UDP transport. + * Create UDP transport (IPv4 or IPv6). */ pjsua_transport_config config; + char hostbuf[PJ_INET6_ADDRSTRLEN]; pj_sock_t sock = PJ_INVALID_SOCKET; - pj_sockaddr_in bound_addr; - pj_sockaddr_in pub_addr; + pj_sockaddr pub_addr; pjsip_host_port addr_name; /* Supply default config if it's not specified */ @@ -1329,22 +1362,12 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, cfg = &config; } - /* 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); + pj_sockaddr_init(pjsip_transport_type_get_af(type), &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); + status = pj_sockaddr_set_str_addr(pjsip_transport_type_get_af(type), + &pub_addr, &cfg->public_addr); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to resolve transport public address", @@ -1356,18 +1379,19 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, /* 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, + status = create_sip_udp_sock(pjsip_transport_type_get_af(type), + &cfg->bound_addr, cfg->port, &sock, &pub_addr); if (status != PJ_SUCCESS) goto on_return; - addr_name.host = pj_str(pj_inet_ntoa(pub_addr.sin_addr)); - addr_name.port = pj_ntohs(pub_addr.sin_port); + pj_ansi_strcpy(hostbuf, addr_string(&pub_addr)); + addr_name.host = pj_str(hostbuf); + addr_name.port = pj_sockaddr_get_port(&pub_addr); /* Create UDP transport */ - status = pjsip_udp_transport_attach( pjsua_var.endpt, sock, - &addr_name, 1, - &tp); + status = pjsip_udp_transport_attach2(pjsua_var.endpt, type, sock, + &addr_name, 1, &tp); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating SIP UDP transport", status); diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 16dcbce8..6738284a 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -346,15 +346,15 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg, break; } else { - pj_in_addr addr; + pj_sockaddr addr; /* Get local IP address. */ - status = pj_gethostip(&addr); + status = pj_gethostip(pj_AF_INET(), &addr); if (status != PJ_SUCCESS) goto on_error; for (i=0; i<2; ++i) - mapped_addr[i].sin_addr = addr; + mapped_addr[i].sin_addr.s_addr = addr.ipv4.sin_addr.s_addr; 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)); |