[sr-dev] git:master:3de068a8: tm: t_check_status exported to kemi framework

Daniel-Constantin Mierla miconda at gmail.com
Wed Dec 6 17:01:38 CET 2017


Module: kamailio
Branch: master
Commit: 3de068a8897917d088993923f3028ca98aadc765
URL: https://github.com/kamailio/kamailio/commit/3de068a8897917d088993923f3028ca98aadc765

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2017-12-06T16:50:39+01:00

tm: t_check_status exported to kemi framework

---

Modified: src/modules/tm/tm.c

---

Diff:  https://github.com/kamailio/kamailio/commit/3de068a8897917d088993923f3028ca98aadc765.diff
Patch: https://github.com/kamailio/kamailio/commit/3de068a8897917d088993923f3028ca98aadc765.patch

---

diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c
index 9bc1695a0f..7d7145393b 100644
--- a/src/modules/tm/tm.c
+++ b/src/modules/tm/tm.c
@@ -852,7 +852,6 @@ static int child_init(int rank)
 }
 
 
-
 /**************************** wrapper functions ***************************/
 static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
 {
@@ -984,6 +983,98 @@ static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
 	return -1;
 }
 
+static int ki_t_check_status(sip_msg_t* msg, str *sexp)
+{
+	regmatch_t pmatch;
+	struct cell *t;
+	char *status, *s = NULL;
+	char backup;
+	int lowest_status, n, ret;
+	regex_t re;
+
+	/* first get the transaction */
+	if (t_check(msg, 0 ) == -1) return -1;
+
+	if ((t = get_t()) == 0) {
+		LM_ERR("cannot check status for a reply"
+				" which has no T-state established\n");
+		goto error0;
+	}
+
+	memset(&re, 0, sizeof(regex_t));
+	if (regcomp(&re, sexp->s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)) {
+		LM_ERR("Bad regular expression '%s'\n", s);
+		goto error0;
+	}
+
+	switch(get_route_type()) {
+		case REQUEST_ROUTE:
+			/* use the status of the last sent reply */
+			status = int2str( t->uas.status, 0);
+			break;
+
+		case TM_ONREPLY_ROUTE:
+		case CORE_ONREPLY_ROUTE:
+			/* use the status of the current reply */
+			status = msg->first_line.u.reply.status.s;
+			backup = status[msg->first_line.u.reply.status.len];
+			status[msg->first_line.u.reply.status.len] = 0;
+			break;
+
+		case FAILURE_ROUTE:
+			/* use the status of the winning reply */
+			ret = t_pick_branch( -1, 0, t, &lowest_status);
+			if (ret == -1) {
+				/* t_pick_branch() retuns error also when there are only
+				 * blind UACs. Let us give it another chance including the
+				 * blind branches. */
+				LM_DBG("t_pick_branch returned error,"
+						" trying t_pick_branch_blind\n");
+				ret = t_pick_branch_blind(t, &lowest_status);
+			}
+			if (ret < 0) {
+				LM_CRIT("BUG: t_pick_branch failed to get"
+						" a final response in FAILURE_ROUTE\n");
+				goto error;
+			}
+			status = int2str( lowest_status , 0);
+			break;
+		case BRANCH_FAILURE_ROUTE:
+			status = int2str(t->uac[get_t_branch()].last_received, 0);
+			break;
+		default:
+			LM_ERR("unsupported route type %d\n",
+					get_route_type());
+			goto error;
+	}
+
+	LM_DBG("checked status is <%s>\n",status);
+	/* do the checking */
+	n = regexec(&re, status, 1, &pmatch, 0);
+
+	regfree(&re);
+
+	if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){
+		/* t_check() above has the side effect of setting T and
+		 * REFerencing T => we must unref and unset it.  */
+		UNREF( t );
+		set_t(T_UNDEFINED, T_BR_UNDEFINED);
+	}
+	if (n!=0) return -1;
+	return 1;
+
+error:
+	regfree(&re);
+error0:
+	if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){
+		/* t_check() above has the side effect of setting T and
+		 * REFerencing T => we must unref and unset it.  */
+		UNREF( t );
+		set_t(T_UNDEFINED, T_BR_UNDEFINED);
+	}
+
+	return -1;
+}
 
 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
 {
@@ -2818,6 +2909,11 @@ static sr_kemi_t tm_kemi_exports[] = {
 		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},
+	{ str_init("tm"), str_init("t_check_status"),
+		SR_KEMIP_INT, ki_t_check_status,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
 	{ str_init("tm"), str_init("t_grep_status"),
 		SR_KEMIP_INT, t_grep_status,
 		{ SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
@@ -2883,4 +2979,4 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2)
 {
 	sr_kemi_modules_add(tm_kemi_exports);
 	return 0;
-}
+}
\ No newline at end of file




More information about the sr-dev mailing list