summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pjlib/include/pj/addr_resolv.h12
-rw-r--r--pjlib/src/pj/addr_resolv_sock.c84
-rw-r--r--pjlib/src/pj/addr_resolv_symbian.cpp99
-rw-r--r--pjlib/src/pj/ip_helper_generic.c4
4 files changed, 130 insertions, 69 deletions
diff --git a/pjlib/include/pj/addr_resolv.h b/pjlib/include/pj/addr_resolv.h
index e69abcf8..b066bc95 100644
--- a/pjlib/include/pj/addr_resolv.h
+++ b/pjlib/include/pj/addr_resolv.h
@@ -106,6 +106,18 @@ PJ_DECL(pj_status_t) pj_gethostip(pj_in_addr *ip_addr);
/**
+ * Get the IP address of the default interface. Default interface is the
+ * interface of the default route.
+ *
+ * @param ip_addr On successful resolution, this will be filled up with
+ * the IP address, in network byte order.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_getdefaultipinterface(pj_in_addr *ip_addr);
+
+
+/**
* This function translates the name of a service location (for example,
* a host name) and returns a set of addresses and associated information
* to be used in creating a socket with which to address the specified
diff --git a/pjlib/src/pj/addr_resolv_sock.c b/pjlib/src/pj/addr_resolv_sock.c
index 5e8cde59..a4599ef7 100644
--- a/pjlib/src/pj/addr_resolv_sock.c
+++ b/pjlib/src/pj/addr_resolv_sock.c
@@ -20,6 +20,7 @@
#include <pj/assert.h>
#include <pj/string.h>
#include <pj/errno.h>
+#include <pj/ip_helper.h>
#include <pj/compat/socket.h>
@@ -54,6 +55,45 @@ PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *hostname, pj_hostent *phe)
return PJ_SUCCESS;
}
+/* Get the default IP interface */
+PJ_DEF(pj_status_t) pj_getdefaultipinterface(pj_in_addr *addr)
+{
+ pj_sock_t fd;
+ pj_str_t cp;
+ pj_sockaddr_in a;
+ int len;
+ pj_status_t status;
+
+ status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ cp = pj_str("1.1.1.1");
+ pj_sockaddr_in_init(&a, &cp, 53);
+
+ status = pj_sock_connect(fd, &a, sizeof(a));
+ if (status != PJ_SUCCESS) {
+ pj_sock_close(fd);
+ return status;
+ }
+
+ len = sizeof(a);
+ status = pj_sock_getsockname(fd, &a, &len);
+ if (status != PJ_SUCCESS) {
+ pj_sock_close(fd);
+ return status;
+ }
+
+ pj_sock_close(fd);
+
+ *addr = a.sin_addr;
+
+ /* Success */
+ return PJ_SUCCESS;
+}
+
+
/* Resolve the IP address of local machine */
PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr)
{
@@ -80,37 +120,23 @@ PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr)
if (status != PJ_SUCCESS || (pj_ntohl(addr->s_addr) >> 24)==127 ||
addr->s_addr == 0)
{
- pj_sock_t fd;
- pj_str_t cp;
- pj_sockaddr_in a;
- int len;
-
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd);
- if (status != PJ_SUCCESS) {
- return status;
- }
-
- cp = pj_str("1.1.1.1");
- pj_sockaddr_in_init(&a, &cp, 53);
-
- status = pj_sock_connect(fd, &a, sizeof(a));
- if (status != PJ_SUCCESS) {
- pj_sock_close(fd);
- /* Return 127.0.0.1 as the address */
- return PJ_SUCCESS;
- }
+ status = pj_getdefaultipinterface(addr);
+ }
- len = sizeof(a);
- status = pj_sock_getsockname(fd, &a, &len);
- if (status != PJ_SUCCESS) {
- pj_sock_close(fd);
- /* Return 127.0.0.1 as the address */
- return PJ_SUCCESS;
+ /* As the last resort, get the first available interface */
+ if (status != PJ_SUCCESS) {
+ pj_in_addr addrs[2];
+ unsigned count = PJ_ARRAY_SIZE(addrs);
+
+ status = pj_enum_ip_interface(&count, addrs);
+ if (status == PJ_SUCCESS) {
+ if (count != 0) {
+ *addr = addrs[0];
+ } else {
+ /* Just return 127.0.0.1 */
+ addr->s_addr = pj_htonl (0x7f000001);
+ }
}
-
- pj_sock_close(fd);
-
- *addr = a.sin_addr;
}
return status;
diff --git a/pjlib/src/pj/addr_resolv_symbian.cpp b/pjlib/src/pj/addr_resolv_symbian.cpp
index 7bdc4a6f..496c1f8b 100644
--- a/pjlib/src/pj/addr_resolv_symbian.cpp
+++ b/pjlib/src/pj/addr_resolv_symbian.cpp
@@ -19,6 +19,8 @@
#include <pj/addr_resolv.h>
#include <pj/assert.h>
#include <pj/errno.h>
+#include <pj/ip_helper.h>
+#include <pj/sock.h>
#include <pj/string.h>
#include <pj/unicode.h>
@@ -84,17 +86,52 @@ PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he)
}
+/* Get the default IP interface */
+PJ_DEF(pj_status_t) pj_getdefaultipinterface(pj_in_addr *addr)
+{
+ pj_sock_t fd;
+ pj_str_t cp;
+ pj_sockaddr_in a;
+ int len;
+ pj_status_t status;
+
+ status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ cp = pj_str("1.1.1.1");
+ pj_sockaddr_in_init(&a, &cp, 53);
+
+ status = pj_sock_connect(fd, &a, sizeof(a));
+ if (status != PJ_SUCCESS) {
+ pj_sock_close(fd);
+ return status;
+ }
+
+ len = sizeof(a);
+ status = pj_sock_getsockname(fd, &a, &len);
+ if (status != PJ_SUCCESS) {
+ pj_sock_close(fd);
+ return status;
+ }
+
+ pj_sock_close(fd);
+
+ *addr = a.sin_addr;
+
+ /* Success */
+ return PJ_SUCCESS;
+}
+
+
/* Resolve the IP address of local machine */
PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr)
{
const pj_str_t *hostname = pj_gethostname();
struct pj_hostent he;
- pj_str_t cp;
- pj_in_addr loopip;
pj_status_t status;
- cp = pj_str("127.0.0.1");
- loopip = pj_inet_addr(&cp);
/* Try with resolving local hostname first */
status = pj_gethostbyname(hostname, &he);
@@ -103,46 +140,32 @@ PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr)
}
- /* If we end up with 127.0.0.1 or 0.0.0.0, resolve the IP by getting
- * the default interface to connect to some public host.
+ /* If we end up with 127.x.x.x, resolve the IP by getting the default
+ * interface to connect to some public host.
*/
- if (status!=PJ_SUCCESS || addr->s_addr == loopip.s_addr || !addr->s_addr) {
- pj_sock_t fd;
- pj_sockaddr_in a;
- int len;
-
- status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd);
- if (status != PJ_SUCCESS) {
- return status;
- }
-
- cp = pj_str("1.1.1.1");
- pj_sockaddr_in_init(&a, &cp, 53);
-
- status = pj_sock_connect(fd, &a, sizeof(a));
- if (status != PJ_SUCCESS) {
- pj_sock_close(fd);
- return status;
- }
+ if (status != PJ_SUCCESS || (pj_ntohl(addr->s_addr) >> 24)==127 ||
+ addr->s_addr == 0)
+ {
+ status = pj_getdefaultipinterface(addr);
+ }
- len = sizeof(a);
- status = pj_sock_getsockname(fd, &a, &len);
- if (status != PJ_SUCCESS || a.sin_addr.s_addr==0) {
- pj_sock_close(fd);
- /* May return 127.0.0.1 */
- return status;
+ /* As the last resort, get the first available interface */
+ if (status != PJ_SUCCESS) {
+ pj_in_addr addrs[2];
+ unsigned count = PJ_ARRAY_SIZE(addrs);
+
+ status = pj_enum_ip_interface(&count, addrs);
+ if (status == PJ_SUCCESS) {
+ if (count != 0) {
+ *addr = addrs[0];
+ } else {
+ /* Just return 127.0.0.1 */
+ addr->s_addr = pj_htonl(0x7f000001);
+ }
}
-
- pj_sock_close(fd);
-
- *addr = a.sin_addr;
-
- if (a.sin_addr.s_addr == 0)
- return PJ_ENOTFOUND;
}
return status;
}
-
diff --git a/pjlib/src/pj/ip_helper_generic.c b/pjlib/src/pj/ip_helper_generic.c
index 092bb28e..a9284807 100644
--- a/pjlib/src/pj/ip_helper_generic.c
+++ b/pjlib/src/pj/ip_helper_generic.c
@@ -33,7 +33,7 @@ static pj_status_t dummy_enum_ip_interface(unsigned *p_cnt,
pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));
/* Just get one default route */
- status = pj_gethostip(&ifs[0]);
+ status = pj_getdefaultipinterface(&ifs[0]);
if (status != PJ_SUCCESS)
return status;
@@ -111,7 +111,7 @@ PJ_DEF(pj_status_t) pj_enum_ip_route(unsigned *p_cnt,
pj_bzero(routes, sizeof(routes[0]) * (*p_cnt));
/* Just get one default route */
- status = pj_gethostip(&routes[0].ipv4.if_addr);
+ status = pj_getdefaultipinterface(&routes[0].ipv4.if_addr);
if (status != PJ_SUCCESS)
return status;