Browse code

core: new event_route[core:pre-routing]

- executed before running config script for SIP messages, if received
from the network, it is not executed if the message was dispatched
internally
- can be used to delegate processing to special workers via sworker
module
- if drop is used, then processing stops for that message, otherwise it
goes forther to request_route or reply_route

Daniel-Constantin Mierla authored on 26/11/2020 12:23:05
Showing 5 changed files
... ...
@@ -468,6 +468,7 @@ REPLY_ROUTE_CALLBACK	"reply_route_callback"
468 468
 EVENT_ROUTE_CALLBACK	"event_route_callback"
469 469
 RECEIVED_ROUTE_CALLBACK	"received_route_callback"
470 470
 RECEIVED_ROUTE_MODE		"received_route_mode"
471
+PRE_ROUTING_CALLBACK	"pre_routing_callback"
471 472
 
472 473
 MAX_RECURSIVE_LEVEL		"max_recursive_level"
473 474
 MAX_BRANCHES_PARAM		"max_branches"
... ...
@@ -986,6 +987,7 @@ IMPORTFILE      "import_file"
986 987
 <INITIAL>{EVENT_ROUTE_CALLBACK}  { count(); yylval.strval=yytext; return EVENT_ROUTE_CALLBACK;}
987 988
 <INITIAL>{RECEIVED_ROUTE_CALLBACK}  { count(); yylval.strval=yytext; return RECEIVED_ROUTE_CALLBACK;}
988 989
 <INITIAL>{RECEIVED_ROUTE_MODE}  { count(); yylval.strval=yytext; return RECEIVED_ROUTE_MODE;}
990
+<INITIAL>{PRE_ROUTING_CALLBACK}  { count(); yylval.strval=yytext; return PRE_ROUTING_CALLBACK;}
989 991
 <INITIAL>{MAX_RECURSIVE_LEVEL}  { count(); yylval.strval=yytext; return MAX_RECURSIVE_LEVEL;}
990 992
 <INITIAL>{MAX_BRANCHES_PARAM}  { count(); yylval.strval=yytext; return MAX_BRANCHES_PARAM;}
991 993
 <INITIAL>{LATENCY_LOG}  { count(); yylval.strval=yytext; return LATENCY_LOG;}
... ...
@@ -501,6 +501,7 @@ extern char *default_routename;
501 501
 %token EVENT_ROUTE_CALLBACK
502 502
 %token RECEIVED_ROUTE_CALLBACK
503 503
 %token RECEIVED_ROUTE_MODE
504
+%token PRE_ROUTING_CALLBACK
504 505
 %token MAX_RECURSIVE_LEVEL
505 506
 %token MAX_BRANCHES_PARAM
506 507
 %token LATENCY_CFG_LOG
... ...
@@ -1735,6 +1736,16 @@ assign_stm:
1735 1736
 			}
1736 1737
 		}
1737 1738
 	| KEMI DOT RECEIVED_ROUTE_CALLBACK EQUAL error { yyerror("string expected"); }
1739
+	| KEMI DOT PRE_ROUTING_CALLBACK EQUAL STRING {
1740
+			kemi_pre_routing_callback.s = $5;
1741
+			kemi_pre_routing_callback.len = strlen($5);
1742
+			if(kemi_pre_routing_callback.len==4
1743
+					&& strcasecmp(kemi_pre_routing_callback.s, "none")==0) {
1744
+				kemi_pre_routing_callback.s = "";
1745
+				kemi_pre_routing_callback.len = 0;
1746
+			}
1747
+		}
1748
+	| KEMI DOT PRE_ROUTING_CALLBACK EQUAL error { yyerror("string expected"); }
1738 1749
     | RECEIVED_ROUTE_MODE EQUAL intno { ksr_evrt_received_mode=$3; }
1739 1750
 	| RECEIVED_ROUTE_MODE EQUAL error  { yyerror("number  expected"); }
1740 1751
     | MAX_RECURSIVE_LEVEL EQUAL NUMBER { set_max_recursive_level($3); }
... ...
@@ -198,6 +198,7 @@ extern int onsend_route_reply;
198 198
 
199 199
 extern int ksr_evrt_received_mode;
200 200
 extern str kemi_received_route_callback;
201
+extern str kemi_pre_routing_callback;
201 202
 
202 203
 /* real time stuff */
203 204
 extern int real_time;
... ...
@@ -147,7 +147,8 @@ typedef struct snd_flags {
147 147
 
148 148
 /* recv flags */
149 149
 typedef enum recv_flags {
150
-	RECV_F_INTERNAL   = (1 << 0), /*  */
150
+	RECV_F_INTERNAL     = (1 << 0), /* message dispatched internally */
151
+	RECV_F_PREROUTING   = (1 << 1), /* message in pre-routing */
151 152
 } recv_flags_t;
152 153
 
153 154
 typedef struct receive_info {
... ...
@@ -217,6 +217,68 @@ int ksr_evrt_received(char *buf, unsigned int len, receive_info_t *rcv_info)
217 217
 	return ret;
218 218
 }
219 219
 
220
+
221
+static int ksr_evrt_pre_routing_idx = -1;
222
+str kemi_pre_routing_callback = STR_NULL;
223
+
224
+
225
+/**
226
+ *
227
+ */
228
+int ksr_evrt_pre_routing(sip_msg_t *msg)
229
+{
230
+	int ret = 0;
231
+	int rt = -1;
232
+	run_act_ctx_t ra_ctx;
233
+	run_act_ctx_t *bctx = NULL;
234
+	sr_kemi_eng_t *keng = NULL;
235
+	str evname = str_init("core:pre-routing");
236
+	recv_flags_t brflags;
237
+
238
+	if(kemi_pre_routing_callback.len>0) {
239
+		keng = sr_kemi_eng_get();
240
+		if(keng == NULL) {
241
+			LM_DBG("kemi enabled with no core:pre-routing event route callback\n");
242
+			return 0;
243
+		}
244
+	} else {
245
+		if(ksr_evrt_pre_routing_idx == -1) {
246
+			rt = route_lookup(&event_rt, evname.s);
247
+			if (rt < 0 || event_rt.rlist[rt] == NULL) {
248
+				ksr_evrt_pre_routing_idx = -2;
249
+			}
250
+		} else {
251
+			rt = ksr_evrt_pre_routing_idx;
252
+		}
253
+		if (rt < 0 || event_rt.rlist[rt] == NULL) {
254
+			LM_DBG("event route core:pre-routing not defined\n");
255
+			return 0;
256
+		}
257
+	}
258
+
259
+	set_route_type(REQUEST_ROUTE);
260
+	init_run_actions_ctx(&ra_ctx);
261
+	brflags = msg->rcv.rflags;
262
+	msg->rcv.rflags |= RECV_F_PREROUTING;
263
+	if(keng) {
264
+		bctx = sr_kemi_act_ctx_get();
265
+		sr_kemi_act_ctx_set(&ra_ctx);
266
+		ret=sr_kemi_route(keng, msg, REQUEST_ROUTE,
267
+				&kemi_pre_routing_callback, &evname);
268
+		sr_kemi_act_ctx_set(bctx);
269
+	} else {
270
+		ret=run_actions(&ra_ctx, event_rt.rlist[rt], msg);
271
+	}
272
+	msg->rcv.rflags = brflags;
273
+	if(ra_ctx.run_flags&DROP_R_F) {
274
+		LM_DBG("drop was used\n");
275
+		return 1;
276
+	}
277
+	LM_DBG("execution returned %d\n", ret);
278
+
279
+	return 0;
280
+}
281
+
220 282
 /** Receive message
221 283
  *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
222 284
  * break (e.g.: modules/textops)
... ...
@@ -330,6 +392,15 @@ int receive_msg(char *buf, unsigned int len, receive_info_t *rcv_info)
330 392
 	/* ... clear branches from previous message */
331 393
 	clear_branches();
332 394
 
395
+	ret = ksr_evrt_pre_routing(msg);
396
+	if(ret<0) {
397
+		goto error02;
398
+	}
399
+	if(ret == 1) {
400
+		/* finished */
401
+		goto end;
402
+	}
403
+
333 404
 	if(unlikely(ksr_route_locks_set!=NULL && msg->callid && msg->callid->body.s
334 405
 			&& msg->callid->body.len >0)) {
335 406
 		cidlockidx = get_hash1_raw(msg->callid->body.s, msg->callid->body.len);