summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-12-31 11:26:21 +0000
committerBenny Prijono <bennylp@teluu.com>2007-12-31 11:26:21 +0000
commitbaa2f7d1c0e83897cc89fd8a02846af9f1eca4e6 (patch)
tree1e2618ba0671369ca7b701e4c97ad5f189d28b83 /pjlib
parentd378a0cda4735265cce253e38d636cb416ff8ad5 (diff)
Fixed IPv6/IPv4 address issue in Symbian: Symbian, at least 9.1, seems to have dual stack IP, so IPv4 address can be returned as a mapped IPv6 address
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1647 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/src/pj/addr_resolv_symbian.cpp76
-rw-r--r--pjlib/src/pj/ip_helper_symbian.cpp31
-rw-r--r--pjlib/src/pj/os_symbian.h15
-rw-r--r--pjlib/src/pj/sock_common.c51
-rw-r--r--pjlib/src/pj/sock_symbian.cpp4
5 files changed, 115 insertions, 62 deletions
diff --git a/pjlib/src/pj/addr_resolv_symbian.cpp b/pjlib/src/pj/addr_resolv_symbian.cpp
index d3698b51..9a28cbb9 100644
--- a/pjlib/src/pj/addr_resolv_symbian.cpp
+++ b/pjlib/src/pj/addr_resolv_symbian.cpp
@@ -20,12 +20,15 @@
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/ip_helper.h>
+#include <pj/log.h>
#include <pj/sock.h>
#include <pj/string.h>
#include <pj/unicode.h>
#include "os_symbian.h"
+#define THIS_FILE "addr_resolv_symbian.cpp"
+#define TRACE_ME 0
// PJLIB API: resolve hostname
@@ -86,32 +89,59 @@ static pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name,
i = 0;
while (reqStatus == KErrNone && i < *count) {
- // Get the resolved TInetAddr
- TInetAddr inetAddr(nameEntry().iAddr);
- int addrlen;
+ // Get the resolved TInetAddr
+ TInetAddr inetAddr(nameEntry().iAddr);
+ int addrlen;
- // Ignore if this is not the same address family
- if (inetAddr.Family() != (unsigned)af) {
- resv.Next(nameEntry, reqStatus);
- User::WaitForRequest(reqStatus);
- continue;
- }
-
- // Convert the official address to ANSI.
- pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(),
- nameEntry().iName.Length(),
- ai[i].ai_canonname, sizeof(ai[i].ai_canonname));
+#if TRACE_ME
+ if (1) {
+ pj_sockaddr a;
+ char ipaddr[PJ_INET6_ADDRSTRLEN+2];
+ int namelen;
+
+ namelen = sizeof(pj_sockaddr);
+ if (PjSymbianOS::Addr2pj(inetAddr, a, &namelen,
+ PJ_FALSE) == PJ_SUCCESS)
+ {
+ PJ_LOG(5,(THIS_FILE, "resolve %.*s: %s",
+ (int)name->slen, name->ptr,
+ pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));
+ }
+ }
+#endif
+
+ // Ignore if this is not the same address family
+ // Not a good idea, as Symbian mapps IPv4 to IPv6.
+ //fam = inetAddr.Family();
+ //if (fam != af) {
+ // resv.Next(nameEntry, reqStatus);
+ // User::WaitForRequest(reqStatus);
+ // continue;
+ //}
+
+ // Convert IP address first to get IPv4 mapped address
+ addrlen = sizeof(ai[i].ai_addr);
+ status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr,
+ &addrlen, PJ_TRUE);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ // Ignore if address family doesn't match
+ if (ai[i].ai_addr.addr.sa_family != af) {
+ resv.Next(nameEntry, reqStatus);
+ User::WaitForRequest(reqStatus);
+ continue;
+ }
- // Convert IP address
- addrlen = sizeof(ai[i].ai_addr);
- status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, &addrlen);
- if (status != PJ_SUCCESS)
- return status;
+ // Convert the official address to ANSI.
+ pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(),
+ nameEntry().iName.Length(),
+ ai[i].ai_canonname, sizeof(ai[i].ai_canonname));
- // Next
- ++i;
- resv.Next(nameEntry, reqStatus);
- User::WaitForRequest(reqStatus);
+ // Next
+ ++i;
+ resv.Next(nameEntry, reqStatus);
+ User::WaitForRequest(reqStatus);
}
*count = i;
diff --git a/pjlib/src/pj/ip_helper_symbian.cpp b/pjlib/src/pj/ip_helper_symbian.cpp
index 44b8012c..f10c57da 100644
--- a/pjlib/src/pj/ip_helper_symbian.cpp
+++ b/pjlib/src/pj/ip_helper_symbian.cpp
@@ -20,12 +20,16 @@
#include <pj/addr_resolv.h>
#include <pj/assert.h>
#include <pj/errno.h>
+#include <pj/log.h>
#include <pj/string.h>
#include <pj/compat/socket.h>
#include "os_symbian.h"
+#define THIS_FILE "ip_helper_symbian.cpp"
+#define TRACE_ME 0
+
static pj_status_t rsock_enum_interface(int af,
unsigned *p_cnt,
pj_sockaddr ifs[])
@@ -58,14 +62,31 @@ static pj_status_t rsock_enum_interface(int af,
{
TInetAddr &iAddress = info().iAddress;
int namelen;
-
- if (iAddress.Family() != (unsigned)af) {
- continue;
- }
+
+#if TRACE_ME
+ if (1) {
+ pj_sockaddr a;
+ char ipaddr[PJ_INET6_ADDRSTRLEN+2];
+
+ namelen = sizeof(pj_sockaddr);
+ if (PjSymbianOS::Addr2pj(iAddress, a, &namelen,
+ PJ_FALSE) == PJ_SUCCESS)
+ {
+ PJ_LOG(5,(THIS_FILE, "Enum: found address %s",
+ pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));
+ }
+ }
+#endif
namelen = sizeof(ifs[i]);
- if (PjSymbianOS::Addr2pj(iAddress, ifs[i], &namelen) != PJ_SUCCESS)
+ if (PjSymbianOS::Addr2pj(iAddress, ifs[i], &namelen,
+ PJ_TRUE) != PJ_SUCCESS)
+ {
continue;
+ }
+
+ if (ifs[i].addr.sa_family != af)
+ continue;
++i;
}
diff --git a/pjlib/src/pj/os_symbian.h b/pjlib/src/pj/os_symbian.h
index 36ecb653..c0e2045a 100644
--- a/pjlib/src/pj/os_symbian.h
+++ b/pjlib/src/pj/os_symbian.h
@@ -239,18 +239,25 @@ public:
// Convert TInetAddr to pj_sockaddr_in
static inline pj_status_t Addr2pj(const TInetAddr & sym_addr,
pj_sockaddr &pj_addr,
- int *addr_len)
+ int *addr_len,
+ pj_bool_t convert_ipv4_mapped_addr = PJ_FALSE)
{
+ TUint fam = sym_addr.Family();
pj_bzero(&pj_addr, *addr_len);
- pj_addr.addr.sa_family = (pj_uint16_t)sym_addr.Family();
- if (pj_addr.addr.sa_family == PJ_AF_INET) {
+ if (fam == PJ_AF_INET ||
+ (convert_ipv4_mapped_addr &&
+ fam == PJ_AF_INET6 &&
+ sym_addr.IsV4Mapped()))
+ {
+ pj_addr.addr.sa_family = PJ_AF_INET;
PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in), PJ_ETOOSMALL);
pj_addr.ipv4.sin_addr.s_addr = pj_htonl(sym_addr.Address());
pj_addr.ipv4.sin_port = pj_htons((pj_uint16_t) sym_addr.Port());
*addr_len = sizeof(pj_sockaddr_in);
- } else if (pj_addr.addr.sa_family == PJ_AF_INET6) {
+ } else if (fam == PJ_AF_INET6) {
PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in6), PJ_ETOOSMALL);
const TIp6Addr & ip6 = sym_addr.Ip6Address();
+ pj_addr.addr.sa_family = PJ_AF_INET6;
pj_memcpy(&pj_addr.ipv6.sin6_addr, ip6.u.iAddr8, 16);
pj_addr.ipv6.sin6_port = pj_htons((pj_uint16_t) sym_addr.Port());
pj_addr.ipv6.sin6_scope_id = pj_htonl(sym_addr.Scope());
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 71cd02e7..a91b3c61 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -455,9 +455,8 @@ PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)
count = 1;
status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai);
if (status == PJ_SUCCESS) {
- pj_memcpy(pj_sockaddr_get_addr(addr),
- pj_sockaddr_get_addr(&ai.ai_addr),
- pj_sockaddr_get_addr_len(&ai.ai_addr));
+ pj_assert(ai.ai_addr.addr.sa_family == (pj_uint16_t)af);
+ pj_sockaddr_copy_addr(addr, &ai.ai_addr);
}
@@ -465,37 +464,35 @@ PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)
* interface to connect to some public host.
*/
if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(addr) ||
- (af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127))
+ (af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127))
{
- status = pj_getdefaultipinterface(af, addr);
+ status = pj_getdefaultipinterface(af, addr);
}
/* If failed, get the first available interface */
if (status != PJ_SUCCESS) {
- pj_sockaddr itf[1];
- unsigned count = PJ_ARRAY_SIZE(itf);
-
- status = pj_enum_ip_interface(af, &count, itf);
- if (status == PJ_SUCCESS) {
- itf[0].addr.sa_family = (pj_uint16_t)af;
- pj_memcpy(pj_sockaddr_get_addr(addr),
- pj_sockaddr_get_addr(&itf[0]),
- pj_sockaddr_get_addr_len(&itf[0]));
- }
+ pj_sockaddr itf[1];
+ unsigned count = PJ_ARRAY_SIZE(itf);
+
+ status = pj_enum_ip_interface(af, &count, itf);
+ if (status == PJ_SUCCESS) {
+ pj_assert(itf[0].addr.sa_family == (pj_uint16_t)af);
+ pj_sockaddr_copy_addr(addr, &itf[0]);
+ }
}
/* If else fails, returns loopback interface as the last resort */
if (status != PJ_SUCCESS) {
- if (af==PJ_AF_INET) {
- addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
- } else {
- pj_in6_addr *s6_addr;
-
- s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
- pj_bzero(s6_addr, sizeof(pj_in6_addr));
- s6_addr->s6_addr[15] = 1;
- }
- status = PJ_SUCCESS;
+ if (af==PJ_AF_INET) {
+ addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
+ } else {
+ pj_in6_addr *s6_addr;
+
+ s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
+ pj_bzero(s6_addr, sizeof(pj_in6_addr));
+ s6_addr->s6_addr[15] = 1;
+ }
+ status = PJ_SUCCESS;
}
return status;
@@ -552,9 +549,7 @@ PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
return PJ_ENOTFOUND;
}
- pj_memcpy(pj_sockaddr_get_addr(addr),
- pj_sockaddr_get_addr(&a),
- pj_sockaddr_get_addr_len(&a));
+ pj_sockaddr_copy_addr(addr, &a);
/* Success */
return PJ_SUCCESS;
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index f53f657e..aab6d4d8 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -405,7 +405,7 @@ PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,
TBuf<PJ_INET_ADDRSTRLEN> str16;
pj_in_addr inaddr;
- if (size <= PJ_INET_ADDRSTRLEN)
+ if (size < PJ_INET_ADDRSTRLEN)
return PJ_ETOOSMALL;
pj_memcpy(&inaddr, src, 4);
@@ -421,7 +421,7 @@ PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,
} else if (af==PJ_AF_INET6) {
TBuf<PJ_INET6_ADDRSTRLEN> str16;
- if (size <= PJ_INET6_ADDRSTRLEN)
+ if (size < PJ_INET6_ADDRSTRLEN)
return PJ_ETOOSMALL;
TIp6Addr ip6;