瀏覽代碼

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.
Richard Good 9 年之前
父節點
當前提交
552cab3859
共有 2 個文件被更改,包括 110 次插入34 次删除
  1. 73 24
      modules/ims_qos/mod.c
  2. 37 10
      modules/ims_qos/rx_aar.c

+ 73 - 24
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 @@ ignore:
 		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)
 {

+ 37 - 10
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;
 }