- 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
... | ... |
@@ -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); } |
... | ... |
@@ -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); |