summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2010-01-04 16:54:50 +0000
committerNanang Izzuddin <nanang@teluu.com>2010-01-04 16:54:50 +0000
commit2e7c2feace463e9dc191465271866b51d79e4f1f (patch)
treeb5178f94aa2d7be1f32951bd3e37bb47a4a148f2
parent2507130ab774b4f3bc9d9d2021629f5dbf111404 (diff)
Ticket #1010:
- Fixed bug in some APIs of address resolver and IP helper to reset sin_len member of sockaddr. - Added purity test of sin_len member checking in pjlib test. - Fixed bug in pj_getaddrinfo() when address family param set to PJ_AF_UNSPEC (assertion raised as it called pj_sockaddr_get_addr() with PJ_AF_UNSPEC too). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3044 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/addr_resolv_sock.c62
-rw-r--r--pjlib/src/pj/ip_helper_generic.c3
-rw-r--r--pjlib/src/pjlib-test/sock.c84
3 files changed, 129 insertions, 20 deletions
diff --git a/pjlib/src/pj/addr_resolv_sock.c b/pjlib/src/pj/addr_resolv_sock.c
index c88cc8f5..57bcd8f1 100644
--- a/pjlib/src/pj/addr_resolv_sock.c
+++ b/pjlib/src/pj/addr_resolv_sock.c
@@ -73,18 +73,28 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
/* Check if nodename is IP address */
pj_bzero(&ai[0], sizeof(ai[0]));
- ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
- if (pj_inet_pton(af, nodename, pj_sockaddr_get_addr(&ai[0].ai_addr))
- == PJ_SUCCESS)
- {
- pj_str_t tmp;
+ if (af == PJ_AF_UNSPEC) {
+ if (pj_inet_pton(PJ_AF_INET, nodename,
+ &ai[0].ai_addr.ipv4.sin_addr) == PJ_SUCCESS)
+ {
+ af = PJ_AF_INET;
+ }
+ else if (pj_inet_pton(PJ_AF_INET6, nodename,
+ &ai[0].ai_addr.ipv6.sin6_addr) == PJ_SUCCESS)
+ {
+ af = PJ_AF_INET6;
+ }
- tmp.ptr = ai[0].ai_canonname;
- pj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);
- ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
- *count = 1;
+ if (af != PJ_AF_UNSPEC) {
+ pj_str_t tmp;
- return PJ_SUCCESS;
+ tmp.ptr = ai[0].ai_canonname;
+ pj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);
+ ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
+ *count = 1;
+
+ return PJ_SUCCESS;
+ }
}
/* Copy node name to null terminated string. */
@@ -121,6 +131,7 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
/* Store address */
PJ_ASSERT_ON_FAIL(res->ai_addrlen <= sizeof(pj_sockaddr), continue);
pj_memcpy(&ai[i].ai_addr, res->ai_addr, res->ai_addrlen);
+ PJ_SOCKADDR_RESET_LEN(&ai[i].ai_addr);
/* Next slot */
++i;
@@ -139,18 +150,28 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
/* Check if nodename is IP address */
pj_bzero(&ai[0], sizeof(ai[0]));
- ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
- if (pj_inet_pton(af, nodename, pj_sockaddr_get_addr(&ai[0].ai_addr))
- == PJ_SUCCESS)
- {
- pj_str_t tmp;
+ if (af == PJ_AF_UNSPEC) {
+ if (pj_inet_pton(PJ_AF_INET, nodename,
+ &ai[0].ai_addr.ipv4.sin_addr) == PJ_SUCCESS)
+ {
+ af = PJ_AF_INET;
+ }
+ else if (pj_inet_pton(PJ_AF_INET6, nodename,
+ &ai[0].ai_addr.ipv6.sin6_addr) == PJ_SUCCESS)
+ {
+ af = PJ_AF_INET6;
+ }
- tmp.ptr = ai[0].ai_canonname;
- pj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);
- ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
- *count = 1;
+ if (af != PJ_AF_UNSPEC) {
+ pj_str_t tmp;
- return PJ_SUCCESS;
+ tmp.ptr = ai[0].ai_canonname;
+ pj_strncpy_with_null(&tmp, nodename, PJ_MAX_HOSTNAME);
+ ai[0].ai_addr.addr.sa_family = (pj_uint16_t)af;
+ *count = 1;
+
+ return PJ_SUCCESS;
+ }
}
if (af == PJ_AF_INET || af == PJ_AF_UNSPEC) {
@@ -180,6 +201,7 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
ai[*count].ai_addr.ipv4.sin_family = PJ_AF_INET;
pj_memcpy(&ai[*count].ai_addr.ipv4.sin_addr,
he.h_addr_list[i], he.h_length);
+ PJ_SOCKADDR_RESET_LEN(&ai[*count].ai_addr);
(*count)++;
}
diff --git a/pjlib/src/pj/ip_helper_generic.c b/pjlib/src/pj/ip_helper_generic.c
index 79c2edaa..331579c0 100644
--- a/pjlib/src/pj/ip_helper_generic.c
+++ b/pjlib/src/pj/ip_helper_generic.c
@@ -121,6 +121,7 @@ static pj_status_t if_enum_by_af(int af,
pj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));
pj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));
+ PJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);
(*p_cnt)++;
}
@@ -215,6 +216,7 @@ static pj_status_t if_enum_by_af(int af,
pj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));
pj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));
+ PJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);
(*p_cnt)++;
}
@@ -305,6 +307,7 @@ static pj_status_t if_enum_by_af(int af, unsigned *p_cnt, pj_sockaddr ifs[])
pj_bzero(&ifs[*p_cnt], sizeof(ifs[0]));
pj_memcpy(&ifs[*p_cnt], ad, pj_sockaddr_get_len(ad));
+ PJ_SOCKADDR_RESET_LEN(&ifs[*p_cnt]);
(*p_cnt)++;
}
diff --git a/pjlib/src/pjlib-test/sock.c b/pjlib/src/pjlib-test/sock.c
index 30c87711..d64586bc 100644
--- a/pjlib/src/pjlib-test/sock.c
+++ b/pjlib/src/pjlib-test/sock.c
@@ -72,6 +72,18 @@
static char bigdata[BIG_DATA_LEN];
static char bigbuffer[BIG_DATA_LEN];
+/* Macro for checking the value of "sin_len" member of sockaddr
+ * (it must always be zero).
+ */
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+# define CHECK_SA_ZERO_LEN(addr, ret) \
+ if (((pj_addr_hdr*)(addr))->sa_zero_len != 0) \
+ return ret
+#else
+# define CHECK_SA_ZERO_LEN(addr, ret)
+#endif
+
+
static int format_test(void)
{
pj_str_t s = pj_str(ADDRESS);
@@ -284,6 +296,9 @@ static int parse_test(void)
return -10;
}
+ /* Check "sin_len" member of parse result */
+ CHECK_SA_ZERO_LEN(&addr, -20);
+
/* Build the correct result */
status = pj_sockaddr_init(valid_tests[i].result_af,
&result,
@@ -312,6 +327,9 @@ static int parse_test(void)
return -50;
}
+ /* Check "sin_len" member of parse result */
+ CHECK_SA_ZERO_LEN(&addr, -55);
+
/* Compare the result again */
if (pj_sockaddr_cmp(&addr, &result) != 0) {
PJ_LOG(1,("test", ".... parsed result mismatched for %s",
@@ -351,6 +369,68 @@ static int parse_test(void)
return 0;
}
+static int purity_test(void)
+{
+ PJ_LOG(3,("test", "...purity_test()"));
+
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+ /* Check on "sin_len" member of sockaddr */
+ {
+ const pj_str_t str_ip = {"1.1.1.1", 7};
+ pj_sockaddr addr[16];
+ pj_addrinfo ai[16];
+ unsigned cnt;
+ pj_status_t rc;
+
+ /* pj_enum_ip_interface() */
+ cnt = PJ_ARRAY_SIZE(addr);
+ rc = pj_enum_ip_interface(pj_AF_UNSPEC(), &cnt, addr);
+ if (rc == PJ_SUCCESS) {
+ while (cnt--)
+ CHECK_SA_ZERO_LEN(&addr[cnt], -10);
+ }
+
+ /* pj_gethostip() on IPv4 */
+ rc = pj_gethostip(pj_AF_INET(), &addr[0]);
+ if (rc == PJ_SUCCESS)
+ CHECK_SA_ZERO_LEN(&addr[0], -20);
+
+ /* pj_gethostip() on IPv6 */
+ rc = pj_gethostip(pj_AF_INET6(), &addr[0]);
+ if (rc == PJ_SUCCESS)
+ CHECK_SA_ZERO_LEN(&addr[0], -30);
+
+ /* pj_getdefaultipinterface() on IPv4 */
+ rc = pj_getdefaultipinterface(pj_AF_INET(), &addr[0]);
+ if (rc == PJ_SUCCESS)
+ CHECK_SA_ZERO_LEN(&addr[0], -40);
+
+ /* pj_getdefaultipinterface() on IPv6 */
+ rc = pj_getdefaultipinterface(pj_AF_INET6(), &addr[0]);
+ if (rc == PJ_SUCCESS)
+ CHECK_SA_ZERO_LEN(&addr[0], -50);
+
+ /* pj_getaddrinfo() on a host name */
+ cnt = PJ_ARRAY_SIZE(ai);
+ rc = pj_getaddrinfo(pj_AF_UNSPEC(), pj_gethostname(), &cnt, ai);
+ if (rc == PJ_SUCCESS) {
+ while (cnt--)
+ CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -60);
+ }
+
+ /* pj_getaddrinfo() on an IP address */
+ cnt = PJ_ARRAY_SIZE(ai);
+ rc = pj_getaddrinfo(pj_AF_UNSPEC(), &str_ip, &cnt, ai);
+ if (rc == PJ_SUCCESS) {
+ pj_assert(cnt == 1);
+ CHECK_SA_ZERO_LEN(&ai[0].ai_addr, -70);
+ }
+ }
+#endif
+
+ return 0;
+}
+
static int simple_sock_test(void)
{
int types[2];
@@ -760,6 +840,10 @@ int sock_test()
if (rc != 0)
return rc;
+ rc = purity_test();
+ if (rc != 0)
+ return rc;
+
rc = gethostbyname_test();
if (rc != 0)
return rc;