summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2012-08-07 02:18:15 +0000
committerBenny Prijono <bennylp@teluu.com>2012-08-07 02:18:15 +0000
commited7f9eba764e5fb47f7bc881bd96ceeb359bb3cc (patch)
tree76d7643b5b7725d63a0c85694394d4d4ca6e34d4 /pjlib
parent3c0866d754867d94b8d3160d61e01b6b362d1ccb (diff)
Fixed #1412: Account specific NAT settings: STUN, ICE, and TURN
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4218 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/addr_resolv.h25
-rw-r--r--pjlib/src/pj/sock_common.c70
2 files changed, 73 insertions, 22 deletions
diff --git a/pjlib/include/pj/addr_resolv.h b/pjlib/include/pj/addr_resolv.h
index 096dde14..7e89936c 100644
--- a/pjlib/include/pj/addr_resolv.h
+++ b/pjlib/include/pj/addr_resolv.h
@@ -117,6 +117,31 @@ PJ_DECL(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr);
/**
+ * Get the interface IP address to send data to the specified destination.
+ *
+ * @param af The desired address family to query. Valid values
+ * are pj_AF_INET() or pj_AF_INET6().
+ * @param dst The destination host.
+ * @param itf_addr On successful resolution, the address family and address
+ * part of this socket address will be filled up with the host
+ * IP address, in network byte order. Other parts of the socket
+ * address should be ignored.
+ * @param allow_resolve If \a dst may contain hostname (instead of IP
+ * address), specify whether hostname resolution should
+ * be performed. If not, default interface address will
+ * be returned.
+ * @param p_dst_addr If not NULL, it will be filled with the IP address of
+ * the destination host.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_getipinterface(int af,
+ const pj_str_t *dst,
+ pj_sockaddr *itf_addr,
+ pj_bool_t allow_resolve,
+ pj_sockaddr *p_dst_addr);
+
+/**
* Get the IP address of the default interface. Default interface is the
* interface of the default route.
*
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 948d47da..7aaf6689 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -956,42 +956,54 @@ PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)
return PJ_SUCCESS;
}
-/* Get the default IP interface */
-PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
+/* Get IP interface for sending to the specified destination */
+PJ_DEF(pj_status_t) pj_getipinterface(int af,
+ const pj_str_t *dst,
+ pj_sockaddr *itf_addr,
+ pj_bool_t allow_resolve,
+ pj_sockaddr *p_dst_addr)
{
+ pj_sockaddr dst_addr;
pj_sock_t fd;
- pj_str_t cp;
- pj_sockaddr a;
int len;
pj_uint8_t zero[64];
pj_status_t status;
- addr->addr.sa_family = (pj_uint16_t)af;
-
- status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd);
+ pj_sockaddr_init(af, &dst_addr, NULL, 53);
+ status = pj_inet_pton(af, dst, pj_sockaddr_get_addr(&dst_addr));
if (status != PJ_SUCCESS) {
- return status;
- }
+ /* "dst" is not an IP address. */
+ if (allow_resolve) {
+ status = pj_sockaddr_init(af, &dst_addr, dst, 53);
+ } else {
+ pj_str_t cp;
- if (af == PJ_AF_INET) {
- cp = pj_str("1.1.1.1");
- } else {
- cp = pj_str("1::1");
+ if (af == PJ_AF_INET) {
+ cp = pj_str("1.1.1.1");
+ } else {
+ cp = pj_str("1::1");
+ }
+ status = pj_sockaddr_init(af, &dst_addr, &cp, 53);
+ }
+
+ if (status != PJ_SUCCESS)
+ return status;
}
- status = pj_sockaddr_init(af, &a, &cp, 53);
+
+ /* Create UDP socket and connect() to the destination IP */
+ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd);
if (status != PJ_SUCCESS) {
- pj_sock_close(fd);
return status;
}
- status = pj_sock_connect(fd, &a, pj_sockaddr_get_len(&a));
+ status = pj_sock_connect(fd, &dst_addr, pj_sockaddr_get_len(&dst_addr));
if (status != PJ_SUCCESS) {
pj_sock_close(fd);
return status;
}
- len = sizeof(a);
- status = pj_sock_getsockname(fd, &a, &len);
+ len = sizeof(*itf_addr);
+ status = pj_sock_getsockname(fd, itf_addr, &len);
if (status != PJ_SUCCESS) {
pj_sock_close(fd);
return status;
@@ -1001,18 +1013,32 @@ PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
/* Check that the address returned is not zero */
pj_bzero(zero, sizeof(zero));
- if (pj_memcmp(pj_sockaddr_get_addr(&a), zero,
- pj_sockaddr_get_addr_len(&a))==0)
+ if (pj_memcmp(pj_sockaddr_get_addr(itf_addr), zero,
+ pj_sockaddr_get_addr_len(itf_addr))==0)
{
return PJ_ENOTFOUND;
}
- pj_sockaddr_copy_addr(addr, &a);
+ if (p_dst_addr)
+ *p_dst_addr = dst_addr;
- /* Success */
return PJ_SUCCESS;
}
+/* Get the default IP interface */
+PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
+{
+ pj_str_t cp;
+
+ if (af == PJ_AF_INET) {
+ cp = pj_str("1.1.1.1");
+ } else {
+ cp = pj_str("1::1");
+ }
+
+ return pj_getipinterface(af, &cp, addr, PJ_FALSE, NULL);
+}
+
/* Only need to implement these in DLL build */
#if defined(PJ_DLL)