فهرست منبع

tm: use struct for rpc uac helper function

Daniel-Constantin Mierla 2 ماه پیش
والد
کامیت
099292b5c1
1فایلهای تغییر یافته به همراه103 افزوده شده و 72 حذف شده
  1. 103 72
      src/modules/tm/rpc_uac.c

+ 103 - 72
src/modules/tm/rpc_uac.c

@@ -547,7 +547,6 @@ static void rpc_print_uris(rpc_t *rpc, void *c, struct sip_msg *reply)
 	return;
 	return;
 }
 }
 
 
-
 /* t_uac callback */
 /* t_uac callback */
 static void rpc_uac_callback(struct cell *t, int type, struct tmcb_params *ps)
 static void rpc_uac_callback(struct cell *t, int type, struct tmcb_params *ps)
 {
 {
@@ -609,39 +608,32 @@ static void rpc_uac_block_callback(
 }
 }
 
 
 
 
-/** rpc t_uac version-
- * It expects the following list of strings as parameters:
- *  method
- *  request_uri
- *  dst_uri (next hop) -- can be empty (either "" or ".", which is still
- *                        supported for backwards compatibility with fifo)
- *  send_socket (socket from which the message will be sent)
- *  headers (message headers separated by CRLF, at least From and To
- *           must be present)
- *  body (optional, might be null or completely missing)
- *
- * If all the parameters are ok it will call t_uac() using them.
- * Note: this version will  wait for the transaction final reply
- * only if reply_wait is set to 1. Otherwise the rpc reply will be sent
- * immediately and it will be success if the parameters were ok and t_uac did
- * not report any error.
+/**
+ * structure for rpc t_uac
+ */
+typedef struct tm_rpc_uac_attrs
+{
+	str method;
+	str ruri;
+	str nexthop;
+	str send_socket;
+	str headers;
+	str body;
+	int reply_wait;
+	int cbflags;
+	int rpflags;
+} tm_rpc_uac_attrs_t;
+
+/** rpc t_uac with attributes
+ * See rpc_t_uac for the fields inside attrs structure
  * @param rpc - rpc handle
  * @param rpc - rpc handle
  * @param  c - rpc current context
  * @param  c - rpc current context
- * @param reply_wait - if 1 do not generate a rpc reply until final response
- *                     for the transaction arrives, if 0 immediately send
- *                     an rpc reply (see above). If 2 blocking wait until
- *                     final response for the transaction arrives.
- * @param cbflags - uac req callback flags
- * @param rpflags - rpc parameters flags
+ * @param tattrs - attributes structure
  */
  */
-static void rpc_t_uac(
-		rpc_t *rpc, void *c, int reply_wait, int cbflags, int rpflags)
+static void rpc_t_uac_attrs_helper(
+		rpc_t *rpc, void *c, tm_rpc_uac_attrs_t *tattrs)
 {
 {
-	/* rpc params */
-	str method, ruri, nexthop, send_socket, headers;
-	str body = STR_NULL;
 	str sraw = STR_NULL;
 	str sraw = STR_NULL;
-	/* other internal vars.*/
 	str hfb, callid;
 	str hfb, callid;
 	struct sip_uri p_uri, pnexthop;
 	struct sip_uri p_uri, pnexthop;
 	struct sip_msg faked_msg;
 	struct sip_msg faked_msg;
@@ -660,7 +652,7 @@ static void rpc_t_uac(
 	void *th = NULL;
 	void *th = NULL;
 
 
 	dctx = 0;
 	dctx = 0;
-	if(reply_wait == 1
+	if(tattrs->reply_wait == 1
 			&& (rpc->capabilities == 0
 			&& (rpc->capabilities == 0
 					|| !(rpc->capabilities(c) & RPC_DELAYED_REPLY))) {
 					|| !(rpc->capabilities(c) & RPC_DELAYED_REPLY))) {
 		rpc->fault(c, 600,
 		rpc->fault(c, 600,
@@ -668,41 +660,36 @@ static void rpc_t_uac(
 				" by this rpc transport");
 				" by this rpc transport");
 		return;
 		return;
 	}
 	}
-	ret = rpc->scan(c, "SSSSS*S", &method, &ruri, &nexthop, &send_socket,
-			&headers, &body);
-	if(ret < 5 && !(-ret == 5)) {
-		rpc->fault(c, 400, "too few parameters (%d/5)", ret ? ret : -ret);
-		return;
-	}
 	/* check and parse parameters */
 	/* check and parse parameters */
-	if(method.len == 0) {
+	if(tattrs->method.len == 0) {
 		rpc->fault(c, 400, "Empty method");
 		rpc->fault(c, 400, "Empty method");
 		return;
 		return;
 	}
 	}
-	if(parse_uri(ruri.s, ruri.len, &p_uri) < 0) {
-		rpc->fault(c, 400, "Invalid request uri \"%s\"", ruri.s);
+	if(parse_uri(tattrs->ruri.s, tattrs->ruri.len, &p_uri) < 0) {
+		rpc->fault(c, 400, "Invalid request uri \"%s\"", tattrs->ruri.s);
 		return;
 		return;
 	}
 	}
-	if(body.len > 0 && (rpflags & 1)) {
-		if(ksr_hex_decode_ws(&body, &sraw) < 0) {
+	if(tattrs->body.len > 0 && (tattrs->rpflags & 1)) {
+		if(ksr_hex_decode_ws(&tattrs->body, &sraw) < 0) {
 			rpc->fault(c, 400, "Invalid hexa body");
 			rpc->fault(c, 400, "Invalid hexa body");
 			return;
 			return;
 		}
 		}
-		body = sraw;
+		tattrs->body = sraw;
 	}
 	}
 	/* old fifo & unixsock backwards compatibility for nexthop: '.' is still
 	/* old fifo & unixsock backwards compatibility for nexthop: '.' is still
 	   allowed */
 	   allowed */
-	if(nexthop.len == 1 && nexthop.s[0] == '.') {
+	if(tattrs->nexthop.len == 1 && tattrs->nexthop.s[0] == '.') {
 		/* empty nextop */
 		/* empty nextop */
-		nexthop.len = 0;
-		nexthop.s = 0;
-	} else if(nexthop.len == 0) {
-		nexthop.s = 0;
-	} else if(parse_uri(nexthop.s, nexthop.len, &pnexthop) < 0) {
+		tattrs->nexthop.len = 0;
+		tattrs->nexthop.s = 0;
+	} else if(tattrs->nexthop.len == 0) {
+		tattrs->nexthop.s = 0;
+	} else if(parse_uri(tattrs->nexthop.s, tattrs->nexthop.len, &pnexthop)
+			  < 0) {
 		if(sraw.s != NULL) {
 		if(sraw.s != NULL) {
 			pkg_free(sraw.s);
 			pkg_free(sraw.s);
 		}
 		}
-		rpc->fault(c, 400, "Invalid next-hop uri \"%s\"", nexthop.s);
+		rpc->fault(c, 400, "Invalid next-hop uri \"%s\"", tattrs->nexthop.s);
 		return;
 		return;
 	}
 	}
 	/* kamailio backwards compatibility for send_socket: '.' is still
 	/* kamailio backwards compatibility for send_socket: '.' is still
@@ -710,12 +697,12 @@ static void rpc_t_uac(
 	ssock = 0;
 	ssock = 0;
 	saddr.s = 0;
 	saddr.s = 0;
 	saddr.len = 0;
 	saddr.len = 0;
-	if(send_socket.len == 1 && send_socket.s[0] == '.') {
+	if(tattrs->send_socket.len == 1 && tattrs->send_socket.s[0] == '.') {
 		/* empty send socket */
 		/* empty send socket */
-		send_socket.len = 0;
-	} else if(send_socket.len
-			  && (parse_phostport(
-						  send_socket.s, &saddr.s, &saddr.len, &sport, &sproto)
+		tattrs->send_socket.len = 0;
+	} else if(tattrs->send_socket.len
+			  && (parse_phostport(tattrs->send_socket.s, &saddr.s, &saddr.len,
+						  &sport, &sproto)
 							  != 0
 							  != 0
 					  ||
 					  ||
 					  /* check also if it's not a MH addr. */
 					  /* check also if it's not a MH addr. */
@@ -723,20 +710,20 @@ static void rpc_t_uac(
 		if(sraw.s != NULL) {
 		if(sraw.s != NULL) {
 			pkg_free(sraw.s);
 			pkg_free(sraw.s);
 		}
 		}
-		rpc->fault(c, 400, "Invalid send socket \"%s\"", send_socket.s);
+		rpc->fault(c, 400, "Invalid send socket \"%s\"", tattrs->send_socket.s);
 		return;
 		return;
 	} else if(saddr.len
 	} else if(saddr.len
 			  && (ssock = grep_sock_info(&saddr, sport, sproto)) == 0) {
 			  && (ssock = grep_sock_info(&saddr, sport, sproto)) == 0) {
 		if(sraw.s != NULL) {
 		if(sraw.s != NULL) {
 			pkg_free(sraw.s);
 			pkg_free(sraw.s);
 		}
 		}
-		rpc->fault(c, 400, "No local socket for \"%s\"", send_socket.s);
+		rpc->fault(c, 400, "No local socket for \"%s\"", tattrs->send_socket.s);
 		return;
 		return;
 	}
 	}
 	/* check headers using the SIP parser to look in the header list */
 	/* check headers using the SIP parser to look in the header list */
 	memset(&faked_msg, 0, sizeof(struct sip_msg));
 	memset(&faked_msg, 0, sizeof(struct sip_msg));
-	faked_msg.len = headers.len;
-	faked_msg.buf = faked_msg.unparsed = headers.s;
+	faked_msg.len = tattrs->headers.len;
+	faked_msg.buf = faked_msg.unparsed = tattrs->headers.s;
 	if(parse_headers(&faked_msg, HDR_EOH_F, 0) == -1) {
 	if(parse_headers(&faked_msg, HDR_EOH_F, 0) == -1) {
 		if(sraw.s != NULL) {
 		if(sraw.s != NULL) {
 			pkg_free(sraw.s);
 			pkg_free(sraw.s);
@@ -745,12 +732,12 @@ static void rpc_t_uac(
 		return;
 		return;
 	}
 	}
 	/* at this moment all the parameters are parsed => more sanity checks */
 	/* at this moment all the parameters are parsed => more sanity checks */
-	if(rpc_uac_check_msg(rpc, c, &faked_msg, &method, &body, &fromtag, &cseq_is,
-			   &cseq, &callid)
+	if(rpc_uac_check_msg(rpc, c, &faked_msg, &tattrs->method, &tattrs->body,
+			   &fromtag, &cseq_is, &cseq, &callid)
 			< 0)
 			< 0)
 		goto error;
 		goto error;
-	if(get_hfblock(nexthop.len ? &nexthop : &ruri, faked_msg.headers,
-			   PROTO_NONE, ssock, &hfb)
+	if(get_hfblock(tattrs->nexthop.len ? &tattrs->nexthop : &tattrs->ruri,
+			   faked_msg.headers, PROTO_NONE, ssock, &hfb)
 			< 0) {
 			< 0) {
 		rpc->fault(c, 500, "Failed to build headers block");
 		rpc->fault(c, 500, "Failed to build headers block");
 		goto error;
 		goto error;
@@ -771,7 +758,7 @@ static void rpc_t_uac(
 	if(fromtag.s && fromtag.len) {
 	if(fromtag.s && fromtag.len) {
 		dlg.id.loc_tag = fromtag;
 		dlg.id.loc_tag = fromtag;
 	} else {
 	} else {
-		generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id, &ruri);
+		generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id, &tattrs->ruri);
 	}
 	}
 
 
 	/* Fill in CSeq */
 	/* Fill in CSeq */
@@ -786,17 +773,17 @@ static void rpc_t_uac(
 	if(get_to(&faked_msg)->tag_value.len > 0) {
 	if(get_to(&faked_msg)->tag_value.len > 0) {
 		dlg.id.rem_tag = get_to(&faked_msg)->tag_value;
 		dlg.id.rem_tag = get_to(&faked_msg)->tag_value;
 	}
 	}
-	dlg.rem_target = ruri;
-	dlg.dst_uri = nexthop;
+	dlg.rem_target = tattrs->ruri;
+	dlg.dst_uri = tattrs->nexthop;
 	dlg.send_sock = ssock;
 	dlg.send_sock = ssock;
 
 
 	memset(&uac_req, 0, sizeof(uac_req));
 	memset(&uac_req, 0, sizeof(uac_req));
-	uac_req.method = &method;
+	uac_req.method = &tattrs->method;
 	if(hfb.s != NULL && hfb.len > 0)
 	if(hfb.s != NULL && hfb.len > 0)
 		uac_req.headers = &hfb;
 		uac_req.headers = &hfb;
-	uac_req.body = body.len ? &body : 0;
+	uac_req.body = tattrs->body.len ? &tattrs->body : 0;
 	uac_req.dialog = &dlg;
 	uac_req.dialog = &dlg;
-	if(reply_wait == 1) {
+	if(tattrs->reply_wait == 1) {
 		dctx = rpc->delayed_ctx_new(c);
 		dctx = rpc->delayed_ctx_new(c);
 		if(dctx == 0) {
 		if(dctx == 0) {
 			rpc->fault(c, 500, "internal error: failed to create context");
 			rpc->fault(c, 500, "internal error: failed to create context");
@@ -809,14 +796,14 @@ static void rpc_t_uac(
 		   want to still send a reply */
 		   want to still send a reply */
 		rpc = &dctx->rpc;
 		rpc = &dctx->rpc;
 		c = dctx->reply_ctx;
 		c = dctx->reply_ctx;
-	} else if(reply_wait == 2) {
+	} else if(tattrs->reply_wait == 2) {
 		sruid_next(&_tm_rpc_sruid);
 		sruid_next(&_tm_rpc_sruid);
 		uac_req.cb = rpc_uac_block_callback;
 		uac_req.cb = rpc_uac_block_callback;
 		ruid = shm_str_dup_block(&_tm_rpc_sruid.uid);
 		ruid = shm_str_dup_block(&_tm_rpc_sruid.uid);
 		uac_req.cbp = ruid;
 		uac_req.cbp = ruid;
 		uac_req.cb_flags = TMCB_LOCAL_COMPLETED;
 		uac_req.cb_flags = TMCB_LOCAL_COMPLETED;
 	}
 	}
-	uac_req.cb_flags |= cbflags;
+	uac_req.cb_flags |= tattrs->cbflags;
 
 
 	ret = t_uac(&uac_req);
 	ret = t_uac(&uac_req);
 
 
@@ -837,7 +824,7 @@ static void rpc_t_uac(
 		goto error01;
 		goto error01;
 	}
 	}
 
 
-	if(reply_wait == 2) {
+	if(tattrs->reply_wait == 2) {
 		while(ritem == NULL && rcount < 800) {
 		while(ritem == NULL && rcount < 800) {
 			sleep_us(100000);
 			sleep_us(100000);
 			rcount++;
 			rcount++;
@@ -875,6 +862,51 @@ error:
 	}
 	}
 }
 }
 
 
+/** rpc t_uac version-
+ * It expects the following list of strings as parameters:
+ *  method
+ *  request_uri
+ *  dst_uri (next hop) -- can be empty (either "" or ".", which is still
+ *                        supported for backwards compatibility with fifo)
+ *  send_socket (socket from which the message will be sent)
+ *  headers (message headers separated by CRLF, at least From and To
+ *           must be present)
+ *  body (optional, might be null or completely missing)
+ *
+ * If all the parameters are ok it will call t_uac() using them.
+ * Note: this version will  wait for the transaction final reply
+ * only if reply_wait is set to 1. Otherwise the rpc reply will be sent
+ * immediately and it will be success if the parameters were ok and t_uac did
+ * not report any error.
+ * @param rpc - rpc handle
+ * @param  c - rpc current context
+ * @param reply_wait - if 1 do not generate a rpc reply until final response
+ *                     for the transaction arrives, if 0 immediately send
+ *                     an rpc reply (see above). If 2 blocking wait until
+ *                     final response for the transaction arrives.
+ * @param cbflags - uac req callback flags
+ * @param rpflags - rpc parameters flags
+ */
+static void rpc_t_uac(
+		rpc_t *rpc, void *c, int reply_wait, int cbflags, int rpflags)
+{
+	tm_rpc_uac_attrs_t tattrs;
+	int ret;
+
+	memset(&tattrs, 0, sizeof(tm_rpc_uac_attrs_t));
+
+	ret = rpc->scan(c, "SSSSS*S", &tattrs.method, &tattrs.ruri, &tattrs.nexthop,
+			&tattrs.send_socket, &tattrs.headers, &tattrs.body);
+	if(ret < 5 && !(-ret == 5)) {
+		rpc->fault(c, 400, "too few parameters (%d/5)", ret ? ret : -ret);
+		return;
+	}
+	tattrs.reply_wait = reply_wait;
+	tattrs.cbflags = cbflags;
+	tattrs.rpflags = rpflags;
+
+	rpc_t_uac_attrs_helper(rpc, c, &tattrs);
+}
 
 
 /** t_uac with no reply waiting.
 /** t_uac with no reply waiting.
  * @see rpc_t_uac.
  * @see rpc_t_uac.
@@ -972,7 +1004,6 @@ void rpc_t_uac_wait_block_noack_hex(rpc_t *rpc, void *c)
 	rpc_t_uac(rpc, c, 2, TMCB_DONT_ACK, 1);
 	rpc_t_uac(rpc, c, 2, TMCB_DONT_ACK, 1);
 }
 }
 
 
-
 static int t_uac_check_msg(struct sip_msg *msg, str *method, str *body,
 static int t_uac_check_msg(struct sip_msg *msg, str *method, str *body,
 		str *fromtag, int *cseq_is, int *cseq, str *callid)
 		str *fromtag, int *cseq_is, int *cseq, str *callid)
 {
 {