diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 7c7b058cfddc4210bbd9463822837fedab53560b..d1bf3887158269e9c932426f1373855276537f78 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -2071,4 +2071,31 @@ unsigned int ast_sip_get_max_initial_qualify_time(void); 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 76d013c1c98420856ab4ff09c21b4aa7bf1b47f6..8bea76715faf8002f13a72bf400d2d3f6f6f1489 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1906,6 +1906,18 @@ static pjsip_endpoint *ast_pjsip_endpoint; 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 @@ int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code, 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 @@ static int load_module(void) 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 e1abff34f9a2b55bf9934547a0c8bdc052da8d7b..437a1cbe95079547bcd4f8c99ceb5c7949ae4228 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 @@ static int multihomed_rewrite_sdp(struct pjmedia_sdp_session *sdp) } /* 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,7 +200,6 @@ static int unload_module(void) static int load_module(void) { char hostname[MAXHOSTNAMELEN] = ""; - pj_sockaddr addr; CHECK_PJSIP_MODULE_LOADED(); @@ -213,16 +208,6 @@ static int load_module(void) 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)) { ast_log(LOG_ERROR, "Could not register multihomed module for incoming and outgoing requests\n"); return AST_MODULE_LOAD_FAILURE; diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 208d348334818a6032063331b00f01ddbfd08f30..f6c300f1fdf69d20ce89dd6547f96d1e24bb8d22 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -1026,7 +1026,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as 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; @@ -1074,16 +1074,16 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as /* 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 539bfc1fa11abae33aa6da314f873b72a8bd43f3..52bbc17742d4861e18e56aea36a30f64106f4f23 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2643,12 +2643,7 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru 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 5a2357dfc614647c57c72d2c4a220192a8c1b93e..c867f7f21914405eb811951c286dd263ae27d6b0 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -707,7 +707,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as 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 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as 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;