From 552cab385937207ea50cc7a0db9f78bb1fa7411a Mon Sep 17 00:00:00 2001 From: Richard Good Date: Fri, 1 Jul 2016 14:22:28 +0200 Subject: [PATCH] modules/ims_qos: make Rx use of SDP IP info more robust ims_qos uses SDP IP connection info. Previously only SDP IP connection info at session level was supported (before m= line). Now SDP connection IP connection info at stream level (after m= line) is also supported. --- modules/ims_qos/mod.c | 97 ++++++++++++++++++++++++++++++---------- modules/ims_qos/rx_aar.c | 47 ++++++++++++++----- 2 files changed, 110 insertions(+), 34 deletions(-) diff --git a/modules/ims_qos/mod.c b/modules/ims_qos/mod.c index 4c6140b7c19..1021672b997 100644 --- a/modules/ims_qos/mod.c +++ b/modules/ims_qos/mod.c @@ -616,6 +616,27 @@ static int get_identifier(str* src) return 0; } +uint16_t check_ip_version(str ip) +{ + struct addrinfo hint, *res = NULL; + memset(&hint, '\0', sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_flags = AI_NUMERICHOST; + int getaddrret = getaddrinfo(ip.s, NULL, &hint, &res); + if (getaddrret) { + LM_ERR("GetAddrInfo returned an error !\n"); + return 0; + } + if (res->ai_family == AF_INET) { + return AF_INET; + } else if (res->ai_family == AF_INET6) { + return AF_INET6; + } else { + LM_ERR("unknown IP format \n"); + return 0; + } +} + /* Wrapper to send AAR from config file - this only allows for AAR for calls - not register, which uses r_rx_aar_register * return: 1 - success, <=0 failure. 2 - message not a AAR generating message (ie proceed without PCC if you wish) */ @@ -639,6 +660,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int int identifier_type; int ip_version = 0; sdp_session_cell_t* sdp_session; + sdp_stream_cell_t* sdp_stream; str s_id; struct hdr_field *h = 0; struct dlg_cell* dlg = 0; @@ -939,13 +961,37 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int } ip = sdp_session->ip_addr; ip_version = sdp_session->pf; - free_sdp((sdp_info_t**) (void*) &orig_sip_request_msg->body); - + + LM_DBG("IP retrieved from Request SDP to use for framed IP address: [%.*s]", ip.len, ip.s); + + if (ip.len <= 0) { + LM_DBG("Request SDP connection IP could not be retrieved, so we use SDP stream IP"); + sdp_stream = get_sdp_stream(orig_sip_request_msg, 0, 0); + if (!sdp_stream) { + LM_ERR("Missing SDP stream information from request\n"); + goto error; + } + + ip = sdp_stream->ip_addr; + if (ip.len <= 0) { + LM_ERR("Request SDP IP information could not be retrieved"); + goto error; + } + ip_version = check_ip_version(ip); + if (!ip_version) { + LM_ERR("check_ip_version returned 0 \n"); + goto error; + } + + } + + free_sdp((sdp_info_t**) (void*) &t->uas.request->body); + } else { LM_DBG("terminating direction\n"); //get ip from reply sdp (we use first SDP session) if (parse_sdp(msg) < 0) { - LM_ERR("Unable to parse req SDP\n"); + LM_ERR("Unable to parse reply SDP\n"); goto error; } @@ -956,6 +1002,30 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int } ip = sdp_session->ip_addr; ip_version = sdp_session->pf; + + LM_DBG("IP retrieved from Reply SDP to use for framed IP address: [%.*s]", ip.len, ip.s); + + if (ip.len <= 0) { + LM_DBG("Reply SDP connection IP could not be retrieved, so we use SDP stream IP"); + sdp_stream = get_sdp_stream(msg, 0, 0); + if (!sdp_stream) { + LM_ERR("Missing SDP stream information from reply\n"); + goto error; + } + + ip = sdp_stream->ip_addr; + if (ip.len <= 0) { + LM_ERR("Reply SDP IP information could not be retrieved"); + goto error; + } + ip_version = check_ip_version(ip); + if (!ip_version) { + LM_ERR("check_ip_version returned 0 \n"); + goto error; + } + + } + free_sdp((sdp_info_t**) (void*) &msg->body); } @@ -1033,27 +1103,6 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int return result; } -uint16_t check_ip_version(str ip) -{ - struct addrinfo hint, *res = NULL; - memset(&hint, '\0', sizeof(hint)); - hint.ai_family = AF_UNSPEC; - hint.ai_flags = AI_NUMERICHOST; - int getaddrret = getaddrinfo(ip.s, NULL, &hint, &res); - if (getaddrret) { - LM_ERR("GetAddrInfo returned an error !\n"); - return 0; - } - if (res->ai_family == AF_INET) { - return AF_INET; - } else if (res->ai_family == AF_INET6) { - return AF_INET6; - } else { - LM_ERR("unknown IP format \n"); - return 0; - } -} - /* Wrapper to send AAR from config file - only used for registration */ static int w_rx_aar_register(struct sip_msg *msg, char* route, char* str1, char* bar) { diff --git a/modules/ims_qos/rx_aar.c b/modules/ims_qos/rx_aar.c index ea7b72640dd..f90e7f5bf3a 100644 --- a/modules/ims_qos/rx_aar.c +++ b/modules/ims_qos/rx_aar.c @@ -407,7 +407,7 @@ int add_media_components_using_current_flow_description(AAAMessage* aar, rx_auth add_flow = 0; } } - + if(add_flow) { rx_add_media_component_description_avp(aar, flow_description->stream_num, &flow_description->media, &flow_description->req_sdp_ip_addr, @@ -435,17 +435,17 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req, int add_flow = 1; if (!req || !rpl) { - return CSCF_RETURN_FALSE; + goto error; } if (parse_sdp(req) < 0) { LM_ERR("Unable to parse req SDP\n"); - return CSCF_RETURN_FALSE; + goto error; } if (parse_sdp(rpl) < 0) { LM_ERR("Unable to parse res SDP\n"); - return CSCF_RETURN_FALSE; + goto error; } sdp_session_num = 0; @@ -465,7 +465,8 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req, if (!rpl_sdp_session) LM_ERR("Missing SDP session information from rpl\n"); - break; + + goto error; } sdp_stream_num = 0; @@ -492,17 +493,39 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req, } if(add_flow) { - //add this to auth session data + + str ipA = req_sdp_session->ip_addr; + str ipB = rpl_sdp_session->ip_addr; + + if (ipA.len <= 0) { + LM_DBG("Request SDP connection IP could not be retrieved, so we use SDP 1st stream IP"); + ipA = req_sdp_stream->ip_addr; + if (ipA.len <= 0) { + LM_ERR("Requested SDP IP information could not be retrieved"); + goto error; + } + } + + if (ipB.len <= 0) { + LM_DBG("Reply SDP connection IP could not be retrieved, so we use SDP 1st stream IP"); + ipB = rpl_sdp_stream->ip_addr; + if (ipB.len <= 0) { + LM_ERR("Request SDP IP information could not be retrieved"); + goto error; + } + } + + //add this to auth session data add_flow_description((rx_authsessiondata_t*) auth->u.auth.generic_data, sdp_stream_num + 1, - &req_sdp_stream->media, &req_sdp_session->ip_addr, - &req_sdp_stream->port, &rpl_sdp_session->ip_addr, + &req_sdp_stream->media, &ipA, + &req_sdp_stream->port, &ipB, &rpl_sdp_stream->port, &rpl_sdp_stream->transport, &req_sdp_stream->raw_stream, &rpl_sdp_stream->raw_stream, direction, 0 /*This is a new mcd, we are not setting it as active*/); rx_add_media_component_description_avp(aar, sdp_stream_num + 1, - &req_sdp_stream->media, &req_sdp_session->ip_addr, - &req_sdp_stream->port, &rpl_sdp_session->ip_addr, + &req_sdp_stream->media, &ipA, + &req_sdp_stream->port, &ipB, &rpl_sdp_stream->port, &rpl_sdp_stream->transport, &req_sdp_stream->raw_stream, &rpl_sdp_stream->raw_stream, direction); @@ -518,6 +541,10 @@ int add_media_components(AAAMessage* aar, struct sip_msg *req, free_sdp((sdp_info_t**) (void*) &req->body); free_sdp((sdp_info_t**) (void*) &rpl->body); + return 1; + + error: + return 0; }