[asterisk-commits] res pjsip: Add common ast sip get host ip API. (asterisk[13])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 27 15:42:00 CDT 2015


Joshua Colp has submitted this change and it was merged.

Change subject: res_pjsip: Add common ast_sip_get_host_ip API.
......................................................................


res_pjsip: Add common ast_sip_get_host_ip API.

Modules commonly used the pj_gethostip function for retrieving the
IP address of the host. This function does not cache the result and may
result in a DNS lookup occurring, or additional work. If the DNS
server is unreachable or network issues arise this can cause the
pj_gethostip function to block for a period of time.

This change adds an ast_sip_get_host_ip and ast_sip_get_host_ip_string
function which does the same thing but caches the host IP address at
module load time. This results in no additional work being done each
time the local host IP address is needed.

ASTERISK-25342 #close

Change-Id: I3205deb679b01fa5ac05a94b623bfd620a2abe1e
---
M include/asterisk/res_pjsip.h
M res/res_pjsip.c
M res/res_pjsip_multihomed.c
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_session.c
M res/res_pjsip_t38.c
6 files changed, 94 insertions(+), 42 deletions(-)

Approvals:
  Mark Michelson: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Ashley Sanders: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved



diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 7c7b058..d1bf388 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -2071,4 +2071,31 @@
 const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status);
 const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status);
 
+/*!
+ * \brief Retrieve the local host address in IP form
+ *
+ * \param af The address family to retrieve
+ * \param addr A place to store the local host address
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \since 13.6.0
+ */
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr);
+
+/*!
+ * \brief Retrieve the local host address in string form
+ *
+ * \param af The address family to retrieve
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \since 13.6.0
+ *
+ * \note An empty string may be returned if the address family is valid but no local address exists
+ */
+const char *ast_sip_get_host_ip_string(int af);
+
 #endif /* _RES_PJSIP_H */
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 76d013c..8bea767 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1906,6 +1906,18 @@
 
 static struct ast_threadpool *sip_threadpool;
 
+/*! Local host address for IPv4 */
+static pj_sockaddr host_ip_ipv4;
+
+/*! Local host address for IPv4 (string form) */
+static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN + 2];
+
+/*! Local host address for IPv6 */
+static pj_sockaddr host_ip_ipv6;
+
+/*! Local host address for IPv6 (string form) */
+static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN + 2];
+
 static int register_service_noref(void *data)
 {
 	pjsip_module **module = data;
@@ -3697,6 +3709,30 @@
 	return res;
 }
 
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr)
+{
+	if (af == pj_AF_INET() && !ast_strlen_zero(host_ip_ipv4_string)) {
+		pj_sockaddr_copy_addr(addr, &host_ip_ipv4);
+		return 0;
+	} else if (af == pj_AF_INET6() && !ast_strlen_zero(host_ip_ipv6_string)) {
+		pj_sockaddr_copy_addr(addr, &host_ip_ipv6);
+		return 0;
+	}
+
+	return -1;
+}
+
+const char *ast_sip_get_host_ip_string(int af)
+{
+	if (af == pj_AF_INET()) {
+		return host_ip_ipv4_string;
+	} else if (af == pj_AF_INET6()) {
+		return host_ip_ipv6_string;
+	}
+
+	return NULL;
+}
+
 static void remove_request_headers(pjsip_endpoint *endpt)
 {
 	const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
@@ -3811,6 +3847,16 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
+	if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
+		pj_sockaddr_print(&host_ip_ipv4, host_ip_ipv4_string, sizeof(host_ip_ipv4_string), 2);
+		ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ip_ipv4_string);
+	}
+
+	if (!pj_gethostip(pj_AF_INET6(), &host_ip_ipv6)) {
+		pj_sockaddr_print(&host_ip_ipv6, host_ip_ipv6_string, sizeof(host_ip_ipv6_string), 2);
+		ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
+	}
+
 	if (ast_sip_initialize_system()) {
 		ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
 		pj_pool_release(memory_pool);
diff --git a/res/res_pjsip_multihomed.c b/res/res_pjsip_multihomed.c
index e1abff3..437a1cbe 100644
--- a/res/res_pjsip_multihomed.c
+++ b/res/res_pjsip_multihomed.c
@@ -30,12 +30,6 @@
 #include "asterisk/res_pjsip.h"
 #include "asterisk/module.h"
 
-/*! \brief Local host address for IPv4 */
-static char host_ipv4[PJ_INET_ADDRSTRLEN + 2];
-
-/*! \brief Local host address for IPv6 */
-static char host_ipv6[PJ_INET6_ADDRSTRLEN + 2];
-
 /*! \brief Helper function which returns a UDP transport bound to the given address and port */
 static pjsip_transport *multihomed_get_udp_transport(pj_str_t *address, int port)
 {
@@ -75,8 +69,10 @@
 	}
 
 	/* If the host address is used in the SDP replace it with the address of what this is going out on */
-	if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr, host_ipv4)) ||
-		(!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr, host_ipv6))) {
+	if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr,
+		ast_sip_get_host_ip_string(pj_AF_INET()))) ||
+		(!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr,
+		ast_sip_get_host_ip_string(pj_AF_INET6())))) {
 		return 1;
 	}
 
@@ -204,23 +200,12 @@
 static int load_module(void)
 {
 	char hostname[MAXHOSTNAMELEN] = "";
-	pj_sockaddr addr;
 
 	CHECK_PJSIP_MODULE_LOADED();
 
 	if (!gethostname(hostname, sizeof(hostname) - 1)) {
 		ast_verb(2, "Performing DNS resolution of local hostname '%s' to get local IPv4 and IPv6 address\n",
 			hostname);
-	}
-
-	if (!pj_gethostip(pj_AF_INET(), &addr)) {
-		pj_sockaddr_print(&addr, host_ipv4, sizeof(host_ipv4), 2);
-		ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ipv4);
-	}
-
-	if (!pj_gethostip(pj_AF_INET6(), &addr)) {
-		pj_sockaddr_print(&addr, host_ipv6, sizeof(host_ipv6), 2);
-		ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ipv6);
 	}
 
 	if (ast_sip_register_service(&multihomed_module)) {
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 0a5cbcb..5faf4d3 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1023,7 +1023,7 @@
 	static const pj_str_t STR_IP6 = { "IP6", 3};
 	static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
 	pjmedia_sdp_media *media;
-	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	const char *hostip = NULL;
 	struct ast_sockaddr addr;
 	char tmp[512];
 	pj_str_t stmp;
@@ -1071,16 +1071,16 @@
 
 	/* Add connection level details */
 	if (direct_media_enabled) {
-		ast_copy_string(hostip, ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR), sizeof(hostip));
+		hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR);
 	} else if (ast_strlen_zero(session->endpoint->media.address)) {
-		pj_sockaddr localaddr;
-
-		if (pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
-			return -1;
-		}
-		pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+		hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
 	} else {
-		ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+		hostip = session->endpoint->media.address;
+	}
+
+	if (ast_strlen_zero(hostip)) {
+		ast_log(LOG_ERROR, "No local host IP available for stream %s\n", session_media->stream_type);
+		return -1;
 	}
 
 	media->conn->net_type = STR_IN;
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 539bfc1..52bbc17 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2643,12 +2643,7 @@
 		if (!ast_strlen_zero(session->endpoint->media.address)) {
 			pj_strdup2(inv->pool_prov, &local->origin.addr, session->endpoint->media.address);
 		} else {
-			pj_sockaddr localaddr;
-			char our_ip[PJ_INET6_ADDRSTRLEN];
-
-			pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr);
-			pj_sockaddr_print(&localaddr, our_ip, sizeof(our_ip), 0);
-			pj_strdup2(inv->pool_prov, &local->origin.addr, our_ip);
+			pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()));
 		}
 	}
 
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 5a2357d..c867f7f 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -707,7 +707,7 @@
 	static const pj_str_t STR_T38UDPREDUNDANCY = { "t38UDPRedundancy", 16 };
 	struct t38_state *state;
 	pjmedia_sdp_media *media;
-	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	const char *hostip = NULL;
 	struct ast_sockaddr addr;
 	char tmp[512];
 	pj_str_t stmp;
@@ -732,14 +732,13 @@
 	media->desc.transport = STR_UDPTL;
 
 	if (ast_strlen_zero(session->endpoint->media.address)) {
-		pj_sockaddr localaddr;
-
-		if (pj_gethostip(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
-			return -1;
-		}
-		pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+		hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET());
 	} else {
-		ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+		hostip = session->endpoint->media.address;
+	}
+
+	if (ast_strlen_zero(hostip)) {
+		return -1;
 	}
 
 	media->conn->net_type = STR_IN;

-- 
To view, visit https://gerrit.asterisk.org/1137
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I3205deb679b01fa5ac05a94b623bfd620a2abe1e
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>



More information about the asterisk-commits mailing list