1 /**
2 * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
3 *
4 * This file is part of Kamailio, a free SIP server.
5 *
6 * Kamailio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
10 *
11 * Kamailio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25
26 #include "dprint.h"
27 #include "forward.h"
28 #include "locking.h"
29 #include "dset.h"
30 #include "action.h"
31 #include "data_lump.h"
32 #include "data_lump_rpl.h"
33 #include "strutils.h"
34 #include "select_buf.h"
35 #include "pvar.h"
36 #include "mem/shm.h"
37 #include "parser/parse_uri.h"
38 #include "parser/parse_from.h"
39 #include "parser/parse_hname2.h"
40 #include "parser/parse_methods.h"
41
42 #include "kemi.h"
43
44
45 #define SR_KEMI_HNAME_SIZE 128
46
47 /* names for kemi callback functions */
48 str kemi_onsend_route_callback = str_init("ksr_onsend_route");
49 str kemi_reply_route_callback = str_init("ksr_reply_route");
50 str kemi_event_route_callback = str_init("");
51
52 /**
53 *
54 */
55 static sr_kemi_xval_t _sr_kemi_xval = {0};
56
57 /**
58 *
59 */
60 static run_act_ctx_t *_sr_kemi_act_ctx = NULL;
61
62 /**
63 *
64 */
sr_kemi_act_ctx_set(run_act_ctx_t * ctx)65 void sr_kemi_act_ctx_set(run_act_ctx_t *ctx)
66 {
67 _sr_kemi_act_ctx = ctx;
68 }
69
70 /**
71 *
72 */
sr_kemi_act_ctx_get(void)73 run_act_ctx_t* sr_kemi_act_ctx_get(void)
74 {
75 return _sr_kemi_act_ctx;
76 }
77
78 /**
79 *
80 */
sr_kemi_core_dbg(sip_msg_t * msg,str * txt)81 static int sr_kemi_core_dbg(sip_msg_t *msg, str *txt)
82 {
83 if(txt!=NULL && txt->s!=NULL)
84 LM_DBG("%.*s", txt->len, txt->s);
85 return 0;
86 }
87
88 /**
89 *
90 */
sr_kemi_core_err(sip_msg_t * msg,str * txt)91 static int sr_kemi_core_err(sip_msg_t *msg, str *txt)
92 {
93 if(txt!=NULL && txt->s!=NULL)
94 LM_ERR("%.*s", txt->len, txt->s);
95 return 0;
96 }
97
98 /**
99 *
100 */
sr_kemi_core_info(sip_msg_t * msg,str * txt)101 static int sr_kemi_core_info(sip_msg_t *msg, str *txt)
102 {
103 if(txt!=NULL && txt->s!=NULL)
104 LM_INFO("%.*s", txt->len, txt->s);
105 return 0;
106 }
107
108 /**
109 *
110 */
sr_kemi_core_warn(sip_msg_t * msg,str * txt)111 static int sr_kemi_core_warn(sip_msg_t *msg, str *txt)
112 {
113 if(txt!=NULL && txt->s!=NULL)
114 LM_WARN("%.*s", txt->len, txt->s);
115 return 0;
116 }
117
118 /**
119 *
120 */
sr_kemi_core_notice(sip_msg_t * msg,str * txt)121 static int sr_kemi_core_notice(sip_msg_t *msg, str *txt)
122 {
123 if(txt!=NULL && txt->s!=NULL)
124 LM_NOTICE("%.*s", txt->len, txt->s);
125 return 0;
126 }
127
128 /**
129 *
130 */
sr_kemi_core_crit(sip_msg_t * msg,str * txt)131 static int sr_kemi_core_crit(sip_msg_t *msg, str *txt)
132 {
133 if(txt!=NULL && txt->s!=NULL)
134 LM_CRIT("%.*s", txt->len, txt->s);
135 return 0;
136 }
137
138 /**
139 *
140 */
sr_kemi_core_log(sip_msg_t * msg,str * level,str * txt)141 static int sr_kemi_core_log(sip_msg_t *msg, str *level, str *txt)
142 {
143 if(txt!=NULL && txt->s!=NULL) {
144 if(level==NULL || level->s==NULL) {
145 LM_ERR("%s", txt->s);
146 } else {
147 if(strcasecmp(level->s, "dbg")==0) {
148 LM_DBG("%s", txt->s);
149 } else if(strcasecmp(level->s, "info")==0) {
150 LM_INFO("%s", txt->s);
151 } else if(strcasecmp(level->s, "notice")==0) {
152 LM_NOTICE("%s", txt->s);
153 } else if(strcasecmp(level->s, "warn")==0) {
154 LM_WARN("%s", txt->s);
155 } else if(strcasecmp(level->s, "err")==0) {
156 LM_ERR("%s", txt->s);
157 } else if(strcasecmp(level->s, "crit")==0) {
158 LM_CRIT("%s", txt->s);
159 } else {
160 LM_ERR("%s", txt->s);
161 }
162 }
163 }
164 return 0;
165 }
166
167 /**
168 *
169 */
sr_kemi_core_set_drop(sip_msg_t * msg)170 int sr_kemi_core_set_drop(sip_msg_t *msg)
171 {
172 if(_sr_kemi_act_ctx==NULL)
173 return 0;
174 LM_DBG("set drop action executed inside embedded interpreter\n");
175 _sr_kemi_act_ctx->run_flags |= EXIT_R_F|DROP_R_F;
176 return 0;
177 }
178
179 /**
180 *
181 */
sr_kemi_core_is_myself(sip_msg_t * msg,str * uri)182 static int sr_kemi_core_is_myself(sip_msg_t *msg, str *uri)
183 {
184 struct sip_uri puri;
185 int ret;
186
187 if(uri==NULL || uri->s==NULL) {
188 return SR_KEMI_FALSE;
189 }
190 if(uri->len>4 && (strncmp(uri->s, "sip:", 4)==0
191 || strncmp(uri->s, "sips:", 5)==0)) {
192 if(parse_uri(uri->s, uri->len, &puri)!=0) {
193 LM_ERR("failed to parse uri [%.*s]\n", uri->len, uri->s);
194 return SR_KEMI_FALSE;
195 }
196 ret = check_self(&puri.host, (puri.port.s)?puri.port_no:0,
197 (puri.transport_val.s)?puri.proto:0);
198 } else {
199 ret = check_self(uri, 0, 0);
200 }
201 if(ret==1) {
202 return SR_KEMI_TRUE;
203 }
204 return SR_KEMI_FALSE;
205 }
206
207 /**
208 *
209 */
sr_kemi_core_is_myself_ruri(sip_msg_t * msg)210 static int sr_kemi_core_is_myself_ruri(sip_msg_t *msg)
211 {
212 if(msg==NULL) {
213 LM_WARN("invalid msg parameter\n");
214 return SR_KEMI_FALSE;
215 }
216
217 if(msg->first_line.type == SIP_REPLY) /* REPLY doesn't have a ruri */
218 return SR_KEMI_FALSE;
219
220 if (msg->new_uri.s!=NULL)
221 return sr_kemi_core_is_myself(msg, &msg->new_uri);
222 return sr_kemi_core_is_myself(msg, &msg->first_line.u.request.uri);
223 }
224
225 /**
226 *
227 */
sr_kemi_core_is_myself_duri(sip_msg_t * msg)228 static int sr_kemi_core_is_myself_duri(sip_msg_t *msg)
229 {
230 if(msg==NULL) {
231 LM_WARN("invalid msg parameter\n");
232 return SR_KEMI_FALSE;
233 }
234
235 if (msg->dst_uri.s!=NULL)
236 return sr_kemi_core_is_myself(msg, &msg->dst_uri);
237
238 return SR_KEMI_FALSE;
239 }
240
241 /**
242 *
243 */
sr_kemi_core_is_myself_nhuri(sip_msg_t * msg)244 static int sr_kemi_core_is_myself_nhuri(sip_msg_t *msg)
245 {
246 if(msg==NULL) {
247 LM_WARN("invalid msg parameter\n");
248 return SR_KEMI_FALSE;
249 }
250
251 if (msg->dst_uri.s!=NULL)
252 return sr_kemi_core_is_myself(msg, &msg->dst_uri);
253
254 return sr_kemi_core_is_myself_ruri(msg);
255 }
256
257 /**
258 *
259 */
sr_kemi_core_is_myself_furi(sip_msg_t * msg)260 static int sr_kemi_core_is_myself_furi(sip_msg_t *msg)
261 {
262 to_body_t *xfrom;
263
264 if(msg==NULL) {
265 LM_WARN("invalid msg parameter\n");
266 return SR_KEMI_FALSE;
267 }
268
269 if(parse_from_header(msg)<0) {
270 LM_ERR("cannot parse From header\n");
271 return SR_KEMI_FALSE;
272 }
273
274 if(msg->from==NULL || get_from(msg)==NULL) {
275 LM_DBG("no From header\n");
276 return SR_KEMI_FALSE;
277 }
278
279 xfrom = get_from(msg);
280
281 return sr_kemi_core_is_myself(msg, &xfrom->uri);
282 }
283
284 /**
285 *
286 */
sr_kemi_core_is_myself_turi(sip_msg_t * msg)287 static int sr_kemi_core_is_myself_turi(sip_msg_t *msg)
288 {
289 to_body_t *xto;
290
291 if(msg==NULL) {
292 LM_WARN("invalid msg parameter\n");
293 return SR_KEMI_FALSE;
294 }
295
296 if(parse_to_header(msg)<0) {
297 LM_ERR("cannot parse To header\n");
298 return SR_KEMI_FALSE;
299 }
300
301 if(msg->to==NULL || get_to(msg)==NULL) {
302 LM_DBG("no To header\n");
303 return SR_KEMI_FALSE;
304 }
305
306 xto = get_to(msg);
307
308 return sr_kemi_core_is_myself(msg, &xto->uri);
309 }
310
311 /**
312 *
313 */
sr_kemi_core_is_myself_suri(sip_msg_t * msg)314 static int sr_kemi_core_is_myself_suri(sip_msg_t *msg)
315 {
316 str suri;
317
318 if(get_src_uri(msg, 0, &suri)<0) {
319 LM_ERR("cannot src address uri\n");
320 return SR_KEMI_FALSE;
321 }
322
323 return sr_kemi_core_is_myself(msg, &suri);
324 }
325
326 /**
327 *
328 */
sr_kemi_core_is_myself_srcip(sip_msg_t * msg)329 static int sr_kemi_core_is_myself_srcip(sip_msg_t *msg)
330 {
331 str srcip;
332 int ret;
333
334 srcip.s = ip_addr2a(&msg->rcv.src_ip);
335 srcip.len = strlen(srcip.s);
336
337 ret = check_self(&srcip, 0, 0);
338 if(ret==1) {
339 return SR_KEMI_TRUE;
340 }
341 return SR_KEMI_FALSE;
342 }
343
344 /**
345 *
346 */
sr_kemi_core_setflag(sip_msg_t * msg,int flag)347 static int sr_kemi_core_setflag(sip_msg_t *msg, int flag)
348 {
349 if(msg==NULL) {
350 LM_WARN("invalid msg parameter\n");
351 return SR_KEMI_FALSE;
352 }
353
354 if (!flag_in_range(flag)) {
355 LM_ERR("invalid flag parameter %d\n", flag);
356 return SR_KEMI_FALSE;
357 }
358
359 setflag(msg, flag);
360 return SR_KEMI_TRUE;
361 }
362
363 /**
364 *
365 */
sr_kemi_core_resetflag(sip_msg_t * msg,int flag)366 static int sr_kemi_core_resetflag(sip_msg_t *msg, int flag)
367 {
368 if(msg==NULL) {
369 LM_WARN("invalid msg parameter\n");
370 return SR_KEMI_FALSE;
371 }
372
373 if (!flag_in_range(flag)) {
374 LM_ERR("invalid flag parameter %d\n", flag);
375 return SR_KEMI_FALSE;
376 }
377
378 resetflag(msg, flag);
379 return SR_KEMI_TRUE;
380 }
381
382 /**
383 *
384 */
sr_kemi_core_isflagset(sip_msg_t * msg,int flag)385 static int sr_kemi_core_isflagset(sip_msg_t *msg, int flag)
386 {
387 int ret;
388
389 if(msg==NULL) {
390 LM_WARN("invalid msg parameter\n");
391 return SR_KEMI_FALSE;
392 }
393
394 if (!flag_in_range(flag)) {
395 LM_ERR("invalid flag parameter %d\n", flag);
396 return SR_KEMI_FALSE;
397 }
398
399 ret = isflagset(msg, flag);
400 if(ret>0)
401 return SR_KEMI_TRUE;
402 return SR_KEMI_FALSE;
403 }
404
405 /**
406 *
407 */
sr_kemi_core_setbiflag(sip_msg_t * msg,int flag,int branch)408 static int sr_kemi_core_setbiflag(sip_msg_t *msg, int flag, int branch)
409 {
410 if(msg==NULL) {
411 LM_WARN("invalid msg parameter\n");
412 return SR_KEMI_FALSE;
413 }
414
415 if (!flag_in_range(flag)) {
416 LM_ERR("invalid flag parameter %d\n", flag);
417 return SR_KEMI_FALSE;
418 }
419
420 setbflag(branch, flag);
421 return SR_KEMI_TRUE;
422 }
423
424 /**
425 *
426 */
sr_kemi_core_resetbiflag(sip_msg_t * msg,int flag,int branch)427 static int sr_kemi_core_resetbiflag(sip_msg_t *msg, int flag, int branch)
428 {
429 if(msg==NULL) {
430 LM_WARN("invalid msg parameter\n");
431 return SR_KEMI_FALSE;
432 }
433
434 if (!flag_in_range(flag)) {
435 LM_ERR("invalid flag parameter %d\n", flag);
436 return SR_KEMI_FALSE;
437 }
438
439 resetbflag(branch, flag);
440 return SR_KEMI_TRUE;
441 }
442
443 /**
444 *
445 */
sr_kemi_core_isbiflagset(sip_msg_t * msg,int flag,int branch)446 static int sr_kemi_core_isbiflagset(sip_msg_t *msg, int flag, int branch)
447 {
448 int ret;
449
450 if(msg==NULL) {
451 LM_WARN("invalid msg parameter\n");
452 return SR_KEMI_FALSE;
453 }
454
455 if (!flag_in_range(flag)) {
456 LM_ERR("invalid flag parameter %d\n", flag);
457 return SR_KEMI_FALSE;
458 }
459
460 ret = isbflagset(branch, flag);
461 if(ret>0)
462 return SR_KEMI_TRUE;
463 return SR_KEMI_FALSE;
464 }
465
466 /**
467 *
468 */
sr_kemi_core_setbflag(sip_msg_t * msg,int flag)469 static int sr_kemi_core_setbflag(sip_msg_t *msg, int flag)
470 {
471 return sr_kemi_core_setbiflag(msg, flag, 0);
472 }
473
474 /**
475 *
476 */
sr_kemi_core_resetbflag(sip_msg_t * msg,int flag)477 static int sr_kemi_core_resetbflag(sip_msg_t *msg, int flag)
478 {
479 return sr_kemi_core_resetbiflag(msg, flag, 0);
480 }
481
482 /**
483 *
484 */
sr_kemi_core_isbflagset(sip_msg_t * msg,int flag)485 static int sr_kemi_core_isbflagset(sip_msg_t *msg, int flag)
486 {
487 return sr_kemi_core_isbiflagset(msg, flag, 0);
488 }
489
490 /**
491 *
492 */
sr_kemi_core_setsflag(sip_msg_t * msg,int flag)493 static int sr_kemi_core_setsflag(sip_msg_t *msg, int flag)
494 {
495 if (!flag_in_range(flag)) {
496 LM_ERR("invalid flag parameter %d\n", flag);
497 return SR_KEMI_FALSE;
498 }
499
500 setsflag(flag);
501 return SR_KEMI_TRUE;
502 }
503
504 /**
505 *
506 */
sr_kemi_core_resetsflag(sip_msg_t * msg,int flag)507 static int sr_kemi_core_resetsflag(sip_msg_t *msg, int flag)
508 {
509 if (!flag_in_range(flag)) {
510 LM_ERR("invalid flag parameter %d\n", flag);
511 return SR_KEMI_FALSE;
512 }
513
514 resetsflag(flag);
515 return SR_KEMI_TRUE;
516 }
517
518 /**
519 *
520 */
sr_kemi_core_issflagset(sip_msg_t * msg,int flag)521 static int sr_kemi_core_issflagset(sip_msg_t *msg, int flag)
522 {
523 int ret;
524
525 if (!flag_in_range(flag)) {
526 LM_ERR("invalid flag parameter %d\n", flag);
527 return SR_KEMI_FALSE;
528 }
529
530 ret = issflagset(flag);
531 if(ret>0)
532 return SR_KEMI_TRUE;
533 return SR_KEMI_FALSE;
534 }
535
536 /**
537 *
538 */
sr_kemi_core_seturi(sip_msg_t * msg,str * uri)539 static int sr_kemi_core_seturi(sip_msg_t *msg, str *uri)
540 {
541 if(uri==NULL || uri->s==NULL) {
542 LM_ERR("invalid uri parameter\n");
543 return SR_KEMI_FALSE;
544 }
545
546 if(msg==NULL) {
547 LM_WARN("invalid msg parameter\n");
548 return SR_KEMI_FALSE;
549 }
550
551 if(rewrite_uri(msg, uri)<0) {
552 LM_ERR("updating r-uri failed\n");
553 return SR_KEMI_FALSE;
554 }
555 return SR_KEMI_TRUE;
556 }
557
558 /**
559 *
560 */
sr_kemi_core_setuser(sip_msg_t * msg,str * user)561 static int sr_kemi_core_setuser(sip_msg_t *msg, str *user)
562 {
563 struct action act;
564 struct run_act_ctx h;
565
566 if(user==NULL || user->s==NULL) {
567 LM_ERR("invalid user parameter\n");
568 return SR_KEMI_FALSE;
569 }
570
571 if(msg==NULL) {
572 LM_WARN("invalid user parameter\n");
573 return SR_KEMI_FALSE;
574 }
575
576 memset(&act, 0, sizeof(act));
577 act.val[0].type = STRING_ST;
578 act.val[0].u.string = user->s;
579 act.type = SET_USER_T;
580 init_run_actions_ctx(&h);
581 if (do_action(&h, &act, msg)<0) {
582 LM_ERR("do action failed\n");
583 return SR_KEMI_FALSE;
584 }
585 return SR_KEMI_TRUE;
586 }
587
588 /**
589 *
590 */
sr_kemi_core_sethost(sip_msg_t * msg,str * host)591 static int sr_kemi_core_sethost(sip_msg_t *msg, str *host)
592 {
593 struct action act;
594 struct run_act_ctx h;
595
596 if(host==NULL || host->s==NULL) {
597 LM_ERR("invalid host parameter\n");
598 return SR_KEMI_FALSE;
599 }
600
601 if(msg==NULL) {
602 LM_WARN("invalid msg parameter\n");
603 return SR_KEMI_FALSE;
604 }
605
606 memset(&act, 0, sizeof(act));
607 act.val[0].type = STRING_ST;
608 act.val[0].u.string = host->s;
609 act.type = SET_HOST_T;
610 init_run_actions_ctx(&h);
611 if (do_action(&h, &act, msg)<0)
612 {
613 LM_ERR("do action failed\n");
614 return SR_KEMI_FALSE;
615 }
616 return SR_KEMI_TRUE;
617 }
618
619 /**
620 *
621 */
sr_kemi_core_setdsturi(sip_msg_t * msg,str * uri)622 static int sr_kemi_core_setdsturi(sip_msg_t *msg, str *uri)
623 {
624 if(uri==NULL || uri->s==NULL) {
625 LM_ERR("invalid uri parameter\n");
626 return SR_KEMI_FALSE;
627 }
628
629 if(msg==NULL) {
630 LM_WARN("invalid msg parameter\n");
631 return SR_KEMI_FALSE;
632 }
633
634 if(set_dst_uri(msg, uri)<0) {
635 LM_ERR("setting dst uri failed\n");
636 return SR_KEMI_TRUE;
637 }
638 return SR_KEMI_TRUE;
639 }
640
641 /**
642 *
643 */
sr_kemi_core_resetdsturi(sip_msg_t * msg)644 static int sr_kemi_core_resetdsturi(sip_msg_t *msg)
645 {
646 if(msg==NULL) {
647 LM_WARN("invalid msg parameter\n");
648 return SR_KEMI_FALSE;
649 }
650
651 reset_dst_uri(msg);
652 return SR_KEMI_TRUE;
653 }
654
655 /**
656 *
657 */
sr_kemi_core_isdsturiset(sip_msg_t * msg)658 static int sr_kemi_core_isdsturiset(sip_msg_t *msg)
659 {
660 if(msg==NULL) {
661 LM_WARN("invalid msg parameter\n");
662 return SR_KEMI_FALSE;
663 }
664
665 if(msg->dst_uri.s!=NULL && msg->dst_uri.len>0) {
666 return SR_KEMI_TRUE;
667 }
668 return SR_KEMI_FALSE;
669 }
670
671 /**
672 *
673 */
sr_kemi_core_force_rport(sip_msg_t * msg)674 static int sr_kemi_core_force_rport(sip_msg_t *msg)
675 {
676 if(msg==NULL) {
677 LM_WARN("invalid msg parameter\n");
678 return SR_KEMI_FALSE;
679 }
680
681 msg->msg_flags|=FL_FORCE_RPORT;
682 return SR_KEMI_TRUE;
683 }
684
685 /**
686 *
687 */
sr_kemi_core_add_local_rport(sip_msg_t * msg)688 static int sr_kemi_core_add_local_rport(sip_msg_t *msg)
689 {
690 if(msg==NULL) {
691 LM_WARN("invalid msg parameter\n");
692 return SR_KEMI_FALSE;
693 }
694
695 msg->msg_flags|=FL_ADD_LOCAL_RPORT;
696 return SR_KEMI_TRUE;
697 }
698
699 /**
700 *
701 */
sr_kemi_core_match_method_id(str * rmethod,str * vmethod,int mid)702 static int sr_kemi_core_match_method_id(str *rmethod, str *vmethod, int mid)
703 {
704 char mbuf[SR_KEMI_HNAME_SIZE];
705 int i;
706 unsigned int method;
707 str s;
708
709 if(memchr(vmethod->s, '|', vmethod->len)==NULL) {
710 if(rmethod->len!=vmethod->len) {
711 return SR_KEMI_FALSE;
712 }
713 if(strncasecmp(rmethod->s, vmethod->s, vmethod->len)!=0) {
714 return SR_KEMI_FALSE;
715 }
716 return SR_KEMI_TRUE;
717 }
718 if(vmethod->len>=SR_KEMI_HNAME_SIZE-1) {
719 LM_ERR("methods parameter is too long\n");
720 return SR_KEMI_FALSE;
721 }
722 memcpy(mbuf, vmethod->s, vmethod->len);
723 mbuf[vmethod->len] = '\0';
724 for(i=0; i<vmethod->len; i++) {
725 if(mbuf[i]=='|') {
726 mbuf[i] = ',';
727 }
728 }
729 s.s = mbuf;
730 s.len = vmethod->len;
731 if(parse_methods(&s, &method)!=0) {
732 LM_ERR("failed to parse methods string [%.*s]\n", s.len, s.s);
733 return SR_KEMI_FALSE;
734 }
735 if((method==METHOD_UNDEF) || (method&METHOD_OTHER)) {
736 LM_ERR("unknown method in list [%.*s] - use only standard SIP methods\n",
737 s.len, s.s);
738 return SR_KEMI_FALSE;
739 }
740 if((int)method & mid) {
741 return SR_KEMI_TRUE;
742 }
743 return SR_KEMI_FALSE;
744 }
745
746 /**
747 *
748 */
sr_kemi_core_is_method(sip_msg_t * msg,str * vmethod)749 static int sr_kemi_core_is_method(sip_msg_t *msg, str *vmethod)
750 {
751 if(msg==NULL || vmethod==NULL || vmethod->s==NULL || vmethod->len<=0) {
752 LM_WARN("invalid parameters\n");
753 return SR_KEMI_FALSE;
754 }
755
756 if(msg->first_line.type==SIP_REQUEST) {
757 if(msg->first_line.u.request.method_value==METHOD_OTHER) {
758 if(msg->first_line.u.request.method.len!=vmethod->len) {
759 return SR_KEMI_FALSE;
760 }
761 if(strncasecmp(msg->first_line.u.request.method.s, vmethod->s,
762 vmethod->len)!=0) {
763 return SR_KEMI_FALSE;
764 }
765 return SR_KEMI_TRUE;
766 }
767 return sr_kemi_core_match_method_id(&msg->first_line.u.request.method,
768 vmethod, msg->first_line.u.request.method_value);
769 }
770
771 if(parse_headers(msg, HDR_CSEQ_F, 0)!=0 || msg->cseq==NULL) {
772 LM_ERR("cannot parse cseq header\n");
773 return SR_KEMI_FALSE;
774 }
775 if(get_cseq(msg)->method_id==METHOD_OTHER) {
776 if(get_cseq(msg)->method.len!=vmethod->len) {
777 return SR_KEMI_FALSE;
778 }
779 if(strncasecmp(get_cseq(msg)->method.s, vmethod->s,
780 vmethod->len)!=0) {
781 return SR_KEMI_FALSE;
782 }
783 return SR_KEMI_TRUE;
784 }
785 return sr_kemi_core_match_method_id(&get_cseq(msg)->method, vmethod,
786 get_cseq(msg)->method_id);
787 }
788
789 /**
790 *
791 */
sr_kemi_core_is_method_in(sip_msg_t * msg,str * vmethod)792 static int sr_kemi_core_is_method_in(sip_msg_t *msg, str *vmethod)
793 {
794 int imethod;
795 int i;
796
797 if(msg==NULL || vmethod==NULL || vmethod->s==NULL || vmethod->len<=0) {
798 LM_WARN("invalid parameters\n");
799 return SR_KEMI_FALSE;
800 }
801
802 if(msg->first_line.type==SIP_REQUEST) {
803 imethod = msg->first_line.u.request.method_value;
804 } else {
805 if(parse_headers(msg, HDR_CSEQ_F, 0)!=0 || msg->cseq==NULL) {
806 LM_ERR("cannot parse cseq header\n");
807 return SR_KEMI_FALSE;
808 }
809 imethod = get_cseq(msg)->method_id;
810 }
811
812 if(imethod==METHOD_OTHER) {
813 return SR_KEMI_FALSE;
814 }
815
816 for(i=0; i<vmethod->len; i++) {
817 switch(vmethod->s[i]) {
818 case 'I':
819 case 'i':
820 if(imethod==METHOD_INVITE) {
821 return SR_KEMI_TRUE;
822 }
823 break;
824 case 'A':
825 case 'a':
826 if(imethod==METHOD_ACK) {
827 return SR_KEMI_TRUE;
828 }
829 break;
830 case 'B':
831 case 'b':
832 if(imethod==METHOD_BYE) {
833 return SR_KEMI_TRUE;
834 }
835 break;
836 case 'C':
837 case 'c':
838 if(imethod==METHOD_CANCEL) {
839 return SR_KEMI_TRUE;
840 }
841 break;
842 case 'M':
843 case 'm':
844 if(imethod==METHOD_MESSAGE) {
845 return SR_KEMI_TRUE;
846 }
847 break;
848 case 'R':
849 case 'r':
850 if(imethod==METHOD_REGISTER) {
851 return SR_KEMI_TRUE;
852 }
853 break;
854 case 'E':
855 case 'e':
856 if(imethod==METHOD_PRACK) {
857 return SR_KEMI_TRUE;
858 }
859 break;
860 case 'P':
861 case 'p':
862 if(imethod==METHOD_PUBLISH) {
863 return SR_KEMI_TRUE;
864 }
865 break;
866 case 'S':
867 case 's':
868 if(imethod==METHOD_SUBSCRIBE) {
869 return SR_KEMI_TRUE;
870 }
871 break;
872 case 'N':
873 case 'n':
874 if(imethod==METHOD_NOTIFY) {
875 return SR_KEMI_TRUE;
876 }
877 break;
878 case 'O':
879 case 'o':
880 if(imethod==METHOD_OPTIONS) {
881 return SR_KEMI_TRUE;
882 }
883 break;
884 case 'F':
885 case 'f':
886 if(imethod==METHOD_REFER) {
887 return SR_KEMI_TRUE;
888 }
889 break;
890 case 'G':
891 case 'g':
892 if(imethod==METHOD_GET) {
893 return SR_KEMI_TRUE;
894 }
895 break;
896 case 'U':
897 case 'u':
898 if(imethod==METHOD_UPDATE) {
899 return SR_KEMI_TRUE;
900 }
901 break;
902 case 'K':
903 case 'k':
904 if(imethod==METHOD_KDMQ) {
905 return SR_KEMI_TRUE;
906 }
907 break;
908 case 'D':
909 case 'd':
910 if(imethod==METHOD_DELETE) {
911 return SR_KEMI_TRUE;
912 }
913 break;
914 case 'T':
915 case 't':
916 if(imethod==METHOD_POST) {
917 return SR_KEMI_TRUE;
918 }
919 break;
920 case 'V':
921 case 'v':
922 if(imethod==METHOD_PUT) {
923 return SR_KEMI_TRUE;
924 }
925 break;
926 default:
927 LM_WARN("unsupported method flag: %c\n", vmethod->s[i]);
928 }
929 }
930 return SR_KEMI_FALSE;
931 }
932
933 /**
934 *
935 */
sr_kemi_core_is_method_type(sip_msg_t * msg,int mtype)936 static int sr_kemi_core_is_method_type(sip_msg_t *msg, int mtype)
937 {
938 int imethod;
939
940 if(msg==NULL) {
941 LM_WARN("invalid parameters\n");
942 return SR_KEMI_FALSE;
943 }
944
945 if(msg->first_line.type==SIP_REQUEST) {
946 imethod = msg->first_line.u.request.method_value;
947 } else {
948 if(parse_headers(msg, HDR_CSEQ_F, 0)!=0 || msg->cseq==NULL) {
949 LM_ERR("cannot parse cseq header\n");
950 return SR_KEMI_FALSE;
951 }
952 imethod = get_cseq(msg)->method_id;
953 }
954
955 if(imethod==mtype) {
956 return SR_KEMI_TRUE;
957 }
958
959 return SR_KEMI_FALSE;
960 }
961
962 /**
963 *
964 */
sr_kemi_core_is_method_invite(sip_msg_t * msg)965 static int sr_kemi_core_is_method_invite(sip_msg_t *msg)
966 {
967 return sr_kemi_core_is_method_type(msg, METHOD_INVITE);
968 }
969
970 /**
971 *
972 */
sr_kemi_core_is_method_ack(sip_msg_t * msg)973 static int sr_kemi_core_is_method_ack(sip_msg_t *msg)
974 {
975 return sr_kemi_core_is_method_type(msg, METHOD_ACK);
976 }
977
978 /**
979 *
980 */
sr_kemi_core_is_method_bye(sip_msg_t * msg)981 static int sr_kemi_core_is_method_bye(sip_msg_t *msg)
982 {
983 return sr_kemi_core_is_method_type(msg, METHOD_BYE);
984 }
985
986 /**
987 *
988 */
sr_kemi_core_is_method_cancel(sip_msg_t * msg)989 static int sr_kemi_core_is_method_cancel(sip_msg_t *msg)
990 {
991 return sr_kemi_core_is_method_type(msg, METHOD_CANCEL);
992 }
993
994 /**
995 *
996 */
sr_kemi_core_is_method_register(sip_msg_t * msg)997 static int sr_kemi_core_is_method_register(sip_msg_t *msg)
998 {
999 return sr_kemi_core_is_method_type(msg, METHOD_REGISTER);
1000 }
1001
1002 /**
1003 *
1004 */
sr_kemi_core_is_method_options(sip_msg_t * msg)1005 static int sr_kemi_core_is_method_options(sip_msg_t *msg)
1006 {
1007 return sr_kemi_core_is_method_type(msg, METHOD_OPTIONS);
1008 }
1009
1010 /**
1011 *
1012 */
sr_kemi_core_is_method_update(sip_msg_t * msg)1013 static int sr_kemi_core_is_method_update(sip_msg_t *msg)
1014 {
1015 return sr_kemi_core_is_method_type(msg, METHOD_UPDATE);
1016 }
1017
1018 /**
1019 *
1020 */
sr_kemi_core_is_method_subscribe(sip_msg_t * msg)1021 static int sr_kemi_core_is_method_subscribe(sip_msg_t *msg)
1022 {
1023 return sr_kemi_core_is_method_type(msg, METHOD_SUBSCRIBE);
1024 }
1025
1026 /**
1027 *
1028 */
sr_kemi_core_is_method_publish(sip_msg_t * msg)1029 static int sr_kemi_core_is_method_publish(sip_msg_t *msg)
1030 {
1031 return sr_kemi_core_is_method_type(msg, METHOD_PUBLISH);
1032 }
1033
1034 /**
1035 *
1036 */
sr_kemi_core_is_method_notify(sip_msg_t * msg)1037 static int sr_kemi_core_is_method_notify(sip_msg_t *msg)
1038 {
1039 return sr_kemi_core_is_method_type(msg, METHOD_NOTIFY);
1040 }
1041
1042 /**
1043 *
1044 */
sr_kemi_core_is_method_refer(sip_msg_t * msg)1045 static int sr_kemi_core_is_method_refer(sip_msg_t *msg)
1046 {
1047 return sr_kemi_core_is_method_type(msg, METHOD_REFER);
1048 }
1049
1050 /**
1051 *
1052 */
sr_kemi_core_is_method_info(sip_msg_t * msg)1053 static int sr_kemi_core_is_method_info(sip_msg_t *msg)
1054 {
1055 return sr_kemi_core_is_method_type(msg, METHOD_INFO);
1056 }
1057
1058 /**
1059 *
1060 */
sr_kemi_core_is_method_prack(sip_msg_t * msg)1061 static int sr_kemi_core_is_method_prack(sip_msg_t *msg)
1062 {
1063 return sr_kemi_core_is_method_type(msg, METHOD_PRACK);
1064 }
1065
1066
1067 /**
1068 *
1069 */
sr_kemi_core_is_method_message(sip_msg_t * msg)1070 static int sr_kemi_core_is_method_message(sip_msg_t *msg)
1071 {
1072 return sr_kemi_core_is_method_type(msg, METHOD_MESSAGE);
1073 }
1074
1075
1076 /**
1077 *
1078 */
sr_kemi_core_is_method_kdmq(sip_msg_t * msg)1079 static int sr_kemi_core_is_method_kdmq(sip_msg_t *msg)
1080 {
1081 return sr_kemi_core_is_method_type(msg, METHOD_KDMQ);
1082 }
1083
1084
1085 /**
1086 *
1087 */
sr_kemi_core_is_method_get(sip_msg_t * msg)1088 static int sr_kemi_core_is_method_get(sip_msg_t *msg)
1089 {
1090 return sr_kemi_core_is_method_type(msg, METHOD_GET);
1091 }
1092
1093 /**
1094 *
1095 */
sr_kemi_core_is_method_post(sip_msg_t * msg)1096 static int sr_kemi_core_is_method_post(sip_msg_t *msg)
1097 {
1098 return sr_kemi_core_is_method_type(msg, METHOD_POST);
1099 }
1100
1101 /**
1102 *
1103 */
sr_kemi_core_is_method_put(sip_msg_t * msg)1104 static int sr_kemi_core_is_method_put(sip_msg_t *msg)
1105 {
1106 return sr_kemi_core_is_method_type(msg, METHOD_PUT);
1107 }
1108
1109 /**
1110 *
1111 */
sr_kemi_core_is_method_delete(sip_msg_t * msg)1112 static int sr_kemi_core_is_method_delete(sip_msg_t *msg)
1113 {
1114 return sr_kemi_core_is_method_type(msg, METHOD_DELETE);
1115 }
1116
1117 /**
1118 *
1119 */
sr_kemi_core_is_proto_udp(sip_msg_t * msg)1120 static int sr_kemi_core_is_proto_udp(sip_msg_t *msg)
1121 {
1122 return (msg->rcv.proto == PROTO_UDP)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1123 }
1124
1125 /**
1126 *
1127 */
sr_kemi_core_is_proto_tcp(sip_msg_t * msg)1128 static int sr_kemi_core_is_proto_tcp(sip_msg_t *msg)
1129 {
1130 return (msg->rcv.proto == PROTO_TCP)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1131 }
1132
1133 /**
1134 *
1135 */
sr_kemi_core_is_proto_tls(sip_msg_t * msg)1136 static int sr_kemi_core_is_proto_tls(sip_msg_t *msg)
1137 {
1138 return (msg->rcv.proto == PROTO_TLS)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1139 }
1140
1141 /**
1142 *
1143 */
sr_kemi_core_is_proto_ws(sip_msg_t * msg)1144 static int sr_kemi_core_is_proto_ws(sip_msg_t *msg)
1145 {
1146 return (msg->rcv.proto == PROTO_WS)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1147 }
1148
1149 /**
1150 *
1151 */
sr_kemi_core_is_proto_wss(sip_msg_t * msg)1152 static int sr_kemi_core_is_proto_wss(sip_msg_t *msg)
1153 {
1154 return (msg->rcv.proto == PROTO_WSS)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1155 }
1156
1157 /**
1158 *
1159 */
sr_kemi_core_is_proto_sctp(sip_msg_t * msg)1160 static int sr_kemi_core_is_proto_sctp(sip_msg_t *msg)
1161 {
1162 return (msg->rcv.proto == PROTO_SCTP)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1163 }
1164
1165 /**
1166 *
1167 */
sr_kemi_core_is_proto(sip_msg_t * msg,str * sproto)1168 static int sr_kemi_core_is_proto(sip_msg_t *msg, str *sproto)
1169 {
1170 int i;
1171 if (msg==NULL || sproto==NULL || sproto->s==NULL || sproto->len<=0) {
1172 return SR_KEMI_FALSE;
1173 }
1174 for(i=0; i<sproto->len; i++) {
1175 switch(sproto->s[i]) {
1176 case 'e':
1177 case 'E':
1178 if (msg->rcv.proto == PROTO_TLS) {
1179 return SR_KEMI_TRUE;
1180 }
1181 break;
1182 case 's':
1183 case 'S':
1184 if (msg->rcv.proto == PROTO_SCTP) {
1185 return SR_KEMI_TRUE;
1186 }
1187 break;
1188 case 't':
1189 case 'T':
1190 if (msg->rcv.proto == PROTO_TCP) {
1191 return SR_KEMI_TRUE;
1192 }
1193 break;
1194 case 'u':
1195 case 'U':
1196 if (msg->rcv.proto == PROTO_UDP) {
1197 return SR_KEMI_TRUE;
1198 }
1199 break;
1200 case 'v':
1201 case 'V':
1202 if (msg->rcv.proto == PROTO_WS) {
1203 return SR_KEMI_TRUE;
1204 }
1205 break;
1206
1207 case 'w':
1208 case 'W':
1209 if (msg->rcv.proto == PROTO_WSS) {
1210 return SR_KEMI_TRUE;
1211 }
1212 break;
1213 }
1214 }
1215 return SR_KEMI_FALSE;
1216 }
1217
1218 /**
1219 *
1220 */
sr_kemi_core_is_af_ipv4(sip_msg_t * msg)1221 static int sr_kemi_core_is_af_ipv4(sip_msg_t *msg)
1222 {
1223 if(msg==NULL || msg->rcv.bind_address==NULL) {
1224 return SR_KEMI_FALSE;
1225 }
1226 return (msg->rcv.bind_address->address.af==AF_INET)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1227 }
1228
1229 /**
1230 *
1231 */
sr_kemi_core_is_af_ipv6(sip_msg_t * msg)1232 static int sr_kemi_core_is_af_ipv6(sip_msg_t *msg)
1233 {
1234 if(msg==NULL || msg->rcv.bind_address==NULL) {
1235 return SR_KEMI_FALSE;
1236 }
1237 return (msg->rcv.bind_address->address.af==AF_INET6)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1238 }
1239
1240 /**
1241 *
1242 */
sr_kemi_core_is_src_port(sip_msg_t * msg,int vport)1243 static int sr_kemi_core_is_src_port(sip_msg_t *msg, int vport)
1244 {
1245 return (vport == (int)msg->rcv.src_port)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1246 }
1247
1248 /**
1249 *
1250 */
sr_kemi_core_is_dst_port(sip_msg_t * msg,int vport)1251 static int sr_kemi_core_is_dst_port(sip_msg_t *msg, int vport)
1252 {
1253 if(msg==NULL || msg->rcv.bind_address==NULL) {
1254 return SR_KEMI_FALSE;
1255 }
1256 return (vport == (int)msg->rcv.bind_address->port_no)?SR_KEMI_TRUE:SR_KEMI_FALSE;
1257 }
1258
1259 /**
1260 *
1261 */
sr_kemi_core_forward_uri(sip_msg_t * msg,str * vuri)1262 static int sr_kemi_core_forward_uri(sip_msg_t *msg, str *vuri)
1263 {
1264 int ret;
1265 dest_info_t dst;
1266 sip_uri_t *u;
1267 sip_uri_t next_hop;
1268
1269 if(msg==NULL) {
1270 LM_WARN("invalid msg parameter\n");
1271 return -1;
1272 }
1273
1274 init_dest_info(&dst);
1275
1276 if(vuri==NULL || vuri->s==NULL || vuri->len<=0) {
1277 if (msg->dst_uri.len) {
1278 ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop);
1279 u = &next_hop;
1280 } else {
1281 ret = parse_sip_msg_uri(msg);
1282 u = &msg->parsed_uri;
1283 }
1284 } else {
1285 ret = parse_uri(vuri->s, vuri->len, &next_hop);
1286 u = &next_hop;
1287 }
1288
1289 if (ret<0) {
1290 LM_ERR("forward - bad_uri dropping packet\n");
1291 return -1;
1292 }
1293
1294 dst.proto=u->proto;
1295 ret=forward_request(msg, &u->host, u->port_no, &dst);
1296 if (ret>=0) {
1297 return 1;
1298 }
1299
1300 return -1;
1301 }
1302
1303 /**
1304 *
1305 */
sr_kemi_core_forward(sip_msg_t * msg)1306 static int sr_kemi_core_forward(sip_msg_t *msg)
1307 {
1308 return sr_kemi_core_forward_uri(msg, NULL);
1309 }
1310
1311 /**
1312 *
1313 */
sr_kemi_core_set_forward_close(sip_msg_t * msg)1314 static int sr_kemi_core_set_forward_close(sip_msg_t *msg)
1315 {
1316 if(msg==NULL) {
1317 LM_WARN("invalid msg parameter\n");
1318 return SR_KEMI_FALSE;
1319 }
1320
1321 msg->fwd_send_flags.f |= SND_F_CON_CLOSE;
1322 return SR_KEMI_TRUE;
1323 }
1324
1325 /**
1326 *
1327 */
sr_kemi_core_set_forward_no_connect(sip_msg_t * msg)1328 static int sr_kemi_core_set_forward_no_connect(sip_msg_t *msg)
1329 {
1330 if(msg==NULL) {
1331 LM_WARN("invalid msg parameter\n");
1332 return SR_KEMI_FALSE;
1333 }
1334
1335 msg->fwd_send_flags.f |= SND_F_FORCE_CON_REUSE;
1336 return SR_KEMI_TRUE;
1337 }
1338
1339 /**
1340 *
1341 */
sr_kemi_core_set_reply_close(sip_msg_t * msg)1342 static int sr_kemi_core_set_reply_close(sip_msg_t *msg)
1343 {
1344 if(msg==NULL) {
1345 LM_WARN("invalid msg parameter\n");
1346 return SR_KEMI_FALSE;
1347 }
1348
1349 msg->rpl_send_flags.f |= SND_F_CON_CLOSE;
1350 return SR_KEMI_TRUE;
1351 }
1352
1353 /**
1354 *
1355 */
sr_kemi_core_set_reply_no_connect(sip_msg_t * msg)1356 static int sr_kemi_core_set_reply_no_connect(sip_msg_t *msg)
1357 {
1358 if(msg==NULL) {
1359 LM_WARN("invalid msg parameter\n");
1360 return SR_KEMI_FALSE;
1361 }
1362
1363 msg->rpl_send_flags.f |= SND_F_FORCE_CON_REUSE;
1364 return SR_KEMI_TRUE;
1365 }
1366
1367 /**
1368 *
1369 */
sr_kemi_core_set_advertised_address(sip_msg_t * msg,str * addr)1370 static int sr_kemi_core_set_advertised_address(sip_msg_t *msg, str *addr)
1371 {
1372 #define SR_ADV_ADDR_SIZE 128
1373 static char _sr_adv_addr_buf[SR_ADV_ADDR_SIZE];
1374
1375 if(addr==NULL || addr->s==NULL) {
1376 LM_ERR("invalid addr parameter\n");
1377 return SR_KEMI_FALSE;
1378 }
1379
1380 if(addr->len>=SR_ADV_ADDR_SIZE) {
1381 LM_ERR("addr parameter is too large\n");
1382 return SR_KEMI_FALSE;
1383 }
1384
1385 if(msg==NULL) {
1386 LM_WARN("invalid msg parameter\n");
1387 return SR_KEMI_FALSE;
1388 }
1389
1390 memcpy(_sr_adv_addr_buf, addr->s, addr->len);
1391 _sr_adv_addr_buf[addr->len] = '\0';
1392 msg->set_global_address.s = _sr_adv_addr_buf;
1393 msg->set_global_address.len = addr->len;
1394
1395 return SR_KEMI_TRUE;
1396 }
1397
1398 /**
1399 *
1400 */
sr_kemi_core_set_advertised_port(sip_msg_t * msg,str * port)1401 static int sr_kemi_core_set_advertised_port(sip_msg_t *msg, str *port)
1402 {
1403 #define SR_ADV_PORT_SIZE 8
1404 static char _sr_adv_port_buf[SR_ADV_PORT_SIZE];
1405
1406 if(port==NULL || port->s==NULL) {
1407 LM_ERR("invalid port parameter\n");
1408 return SR_KEMI_FALSE;
1409 }
1410
1411 if(port->len>=SR_ADV_PORT_SIZE) {
1412 LM_ERR("port parameter is too large\n");
1413 return SR_KEMI_FALSE;
1414 }
1415
1416 if(msg==NULL) {
1417 LM_WARN("invalid msg parameter\n");
1418 return SR_KEMI_FALSE;
1419 }
1420
1421 memcpy(_sr_adv_port_buf, port->s, port->len);
1422 _sr_adv_port_buf[port->len] = '\0';
1423 msg->set_global_port.s = _sr_adv_port_buf;
1424 msg->set_global_port.len = port->len;
1425
1426 return SR_KEMI_TRUE;
1427 }
1428
1429 /**
1430 *
1431 */
sr_kemi_core_add_tcp_alias(sip_msg_t * msg,int port)1432 static int sr_kemi_core_add_tcp_alias(sip_msg_t *msg, int port)
1433 {
1434 if(msg==NULL) {
1435 LM_WARN("invalid msg parameter\n");
1436 return SR_KEMI_FALSE;
1437 }
1438
1439 #ifdef USE_TCP
1440 if ( msg->rcv.proto==PROTO_TCP
1441 #ifdef USE_TLS
1442 || msg->rcv.proto==PROTO_TLS
1443 #endif
1444 ) {
1445 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
1446 msg->rcv.proto)!=0){
1447 LM_ERR("adding tcp alias failed\n");
1448 return SR_KEMI_FALSE;
1449 }
1450 }
1451 #endif
1452
1453 return SR_KEMI_TRUE;
1454 }
1455
1456 /**
1457 *
1458 */
sr_kemi_core_add_tcp_alias_via(sip_msg_t * msg)1459 static int sr_kemi_core_add_tcp_alias_via(sip_msg_t *msg)
1460 {
1461 if(msg==NULL) {
1462 LM_WARN("invalid msg parameter\n");
1463 return SR_KEMI_FALSE;
1464 }
1465
1466 #ifdef USE_TCP
1467 if ( msg->rcv.proto==PROTO_TCP
1468 #ifdef USE_TLS
1469 || msg->rcv.proto==PROTO_TLS
1470 #endif
1471 ) {
1472 if (tcpconn_add_alias(msg->rcv.proto_reserved1, msg->via1->port,
1473 msg->rcv.proto)!=0){
1474 LM_ERR("adding tcp alias failed\n");
1475 return SR_KEMI_FALSE;
1476 }
1477 }
1478 #endif
1479 return SR_KEMI_TRUE;
1480 }
1481
1482
1483 /**
1484 *
1485 */
sr_kemi_core_get_debug(sip_msg_t * msg)1486 static int sr_kemi_core_get_debug(sip_msg_t *msg)
1487 {
1488 return get_cfg_debug_level();
1489 }
1490
1491 /**
1492 *
1493 */
sr_kemi_core_route(sip_msg_t * msg,str * route)1494 static int sr_kemi_core_route(sip_msg_t *msg, str *route)
1495 {
1496 run_act_ctx_t tctx;
1497 run_act_ctx_t *pctx = NULL;
1498 int rtid = -1;
1499 int ret = 0;
1500
1501 if(route == NULL || route->s == NULL) {
1502 return -1;
1503 }
1504
1505 rtid = route_lookup(&main_rt, route->s);
1506 if (rtid < 0) {
1507 return -1;
1508 }
1509
1510 if(_sr_kemi_act_ctx != NULL) {
1511 pctx = _sr_kemi_act_ctx;
1512 } else {
1513 init_run_actions_ctx(&tctx);
1514 pctx = &tctx;
1515 }
1516
1517 ret=run_actions(pctx, main_rt.rlist[rtid], msg);
1518
1519 if (pctx->run_flags & EXIT_R_F) {
1520 return 0;
1521 }
1522
1523 return ret;
1524 }
1525
1526 /**
1527 *
1528 */
1529 static sr_kemi_t _sr_kemi_core[] = {
1530 { str_init(""), str_init("dbg"),
1531 SR_KEMIP_NONE, sr_kemi_core_dbg,
1532 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1533 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1534 },
1535 { str_init(""), str_init("err"),
1536 SR_KEMIP_NONE, sr_kemi_core_err,
1537 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1538 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1539 },
1540 { str_init(""), str_init("info"),
1541 SR_KEMIP_NONE, sr_kemi_core_info,
1542 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1543 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1544 },
1545 { str_init(""), str_init("warn"),
1546 SR_KEMIP_NONE, sr_kemi_core_warn,
1547 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1548 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1549 },
1550 { str_init(""), str_init("notice"),
1551 SR_KEMIP_NONE, sr_kemi_core_notice,
1552 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1553 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1554 },
1555 { str_init(""), str_init("crit"),
1556 SR_KEMIP_NONE, sr_kemi_core_crit,
1557 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1558 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1559 },
1560 { str_init(""), str_init("log"),
1561 SR_KEMIP_NONE, sr_kemi_core_log,
1562 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1563 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1564 },
1565 { str_init(""), str_init("set_drop"),
1566 SR_KEMIP_NONE, sr_kemi_core_set_drop,
1567 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1568 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1569 },
1570 { str_init(""), str_init("is_myself"),
1571 SR_KEMIP_BOOL, sr_kemi_core_is_myself,
1572 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1573 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1574 },
1575 { str_init(""), str_init("is_myself_ruri"),
1576 SR_KEMIP_BOOL, sr_kemi_core_is_myself_ruri,
1577 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1578 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1579 },
1580 { str_init(""), str_init("is_myself_duri"),
1581 SR_KEMIP_BOOL, sr_kemi_core_is_myself_duri,
1582 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1583 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1584 },
1585 { str_init(""), str_init("is_myself_nhuri"),
1586 SR_KEMIP_BOOL, sr_kemi_core_is_myself_nhuri,
1587 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1588 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1589 },
1590 { str_init(""), str_init("is_myself_furi"),
1591 SR_KEMIP_BOOL, sr_kemi_core_is_myself_furi,
1592 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1593 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1594 },
1595 { str_init(""), str_init("is_myself_turi"),
1596 SR_KEMIP_BOOL, sr_kemi_core_is_myself_turi,
1597 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1598 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1599 },
1600 { str_init(""), str_init("is_myself_suri"),
1601 SR_KEMIP_BOOL, sr_kemi_core_is_myself_suri,
1602 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1603 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1604 },
1605 { str_init(""), str_init("is_myself_srcip"),
1606 SR_KEMIP_BOOL, sr_kemi_core_is_myself_srcip,
1607 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1608 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1609 },
1610 { str_init(""), str_init("setflag"),
1611 SR_KEMIP_BOOL, sr_kemi_core_setflag,
1612 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1613 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1614 },
1615 { str_init(""), str_init("resetflag"),
1616 SR_KEMIP_BOOL, sr_kemi_core_resetflag,
1617 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1618 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1619 },
1620 { str_init(""), str_init("isflagset"),
1621 SR_KEMIP_BOOL, sr_kemi_core_isflagset,
1622 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1623 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1624 },
1625 { str_init(""), str_init("setbflag"),
1626 SR_KEMIP_BOOL, sr_kemi_core_setbflag,
1627 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1628 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1629 },
1630 { str_init(""), str_init("resetbflag"),
1631 SR_KEMIP_BOOL, sr_kemi_core_resetbflag,
1632 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1633 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1634 },
1635 { str_init(""), str_init("isbflagset"),
1636 SR_KEMIP_BOOL, sr_kemi_core_isbflagset,
1637 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1638 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1639 },
1640 { str_init(""), str_init("setbiflag"),
1641 SR_KEMIP_BOOL, sr_kemi_core_setbiflag,
1642 { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE,
1643 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1644 },
1645 { str_init(""), str_init("resetbiflag"),
1646 SR_KEMIP_BOOL, sr_kemi_core_resetbiflag,
1647 { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE,
1648 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1649 },
1650 { str_init(""), str_init("isbiflagset"),
1651 SR_KEMIP_BOOL, sr_kemi_core_isbiflagset,
1652 { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE,
1653 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1654 },
1655 { str_init(""), str_init("setsflag"),
1656 SR_KEMIP_BOOL, sr_kemi_core_setsflag,
1657 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1658 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1659 },
1660 { str_init(""), str_init("resetsflag"),
1661 SR_KEMIP_BOOL, sr_kemi_core_resetsflag,
1662 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1663 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1664 },
1665 { str_init(""), str_init("issflagset"),
1666 SR_KEMIP_BOOL, sr_kemi_core_issflagset,
1667 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1668 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1669 },
1670 { str_init(""), str_init("seturi"),
1671 SR_KEMIP_BOOL, sr_kemi_core_seturi,
1672 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1673 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1674 },
1675 { str_init(""), str_init("setuser"),
1676 SR_KEMIP_BOOL, sr_kemi_core_setuser,
1677 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1678 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1679 },
1680 { str_init(""), str_init("sethost"),
1681 SR_KEMIP_BOOL, sr_kemi_core_sethost,
1682 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1683 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1684 },
1685 { str_init(""), str_init("setdsturi"),
1686 SR_KEMIP_BOOL, sr_kemi_core_setdsturi,
1687 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1688 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1689 },
1690 { str_init(""), str_init("resetdsturi"),
1691 SR_KEMIP_BOOL, sr_kemi_core_resetdsturi,
1692 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1693 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1694 },
1695 { str_init(""), str_init("isdsturiset"),
1696 SR_KEMIP_BOOL, sr_kemi_core_isdsturiset,
1697 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1698 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1699 },
1700 { str_init(""), str_init("force_rport"),
1701 SR_KEMIP_BOOL, sr_kemi_core_force_rport,
1702 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1703 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1704 },
1705 { str_init(""), str_init("add_local_rport"),
1706 SR_KEMIP_BOOL, sr_kemi_core_add_local_rport,
1707 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1708 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1709 },
1710 { str_init(""), str_init("is_method"),
1711 SR_KEMIP_BOOL, sr_kemi_core_is_method,
1712 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1713 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1714 },
1715 { str_init(""), str_init("is_method_in"),
1716 SR_KEMIP_BOOL, sr_kemi_core_is_method_in,
1717 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1718 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1719 },
1720 { str_init(""), str_init("forward"),
1721 SR_KEMIP_INT, sr_kemi_core_forward,
1722 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1723 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1724 },
1725 { str_init(""), str_init("forward_uri"),
1726 SR_KEMIP_INT, sr_kemi_core_forward_uri,
1727 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1728 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1729 },
1730 { str_init(""), str_init("set_forward_close"),
1731 SR_KEMIP_BOOL, sr_kemi_core_set_forward_close,
1732 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1733 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1734 },
1735 { str_init(""), str_init("set_forward_no_connect"),
1736 SR_KEMIP_BOOL, sr_kemi_core_set_forward_no_connect,
1737 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1738 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1739 },
1740 { str_init(""), str_init("set_reply_close"),
1741 SR_KEMIP_BOOL, sr_kemi_core_set_reply_close,
1742 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1743 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1744 },
1745 { str_init(""), str_init("set_reply_no_connect"),
1746 SR_KEMIP_BOOL, sr_kemi_core_set_reply_no_connect,
1747 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1748 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1749 },
1750 { str_init(""), str_init("set_advertised_address"),
1751 SR_KEMIP_INT, sr_kemi_core_set_advertised_address,
1752 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1753 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1754 },
1755 { str_init(""), str_init("set_advertised_port"),
1756 SR_KEMIP_INT, sr_kemi_core_set_advertised_port,
1757 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1758 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1759 },
1760 { str_init(""), str_init("add_tcp_alias"),
1761 SR_KEMIP_INT, sr_kemi_core_add_tcp_alias,
1762 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1763 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1764 },
1765 { str_init(""), str_init("add_tcp_alias_via"),
1766 SR_KEMIP_INT, sr_kemi_core_add_tcp_alias_via,
1767 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1768 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1769 },
1770 { str_init(""), str_init("is_INVITE"),
1771 SR_KEMIP_BOOL, sr_kemi_core_is_method_invite,
1772 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1773 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1774 },
1775 { str_init(""), str_init("is_ACK"),
1776 SR_KEMIP_BOOL, sr_kemi_core_is_method_ack,
1777 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1778 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1779 },
1780 { str_init(""), str_init("is_BYE"),
1781 SR_KEMIP_BOOL, sr_kemi_core_is_method_bye,
1782 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1783 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1784 },
1785 { str_init(""), str_init("is_CANCEL"),
1786 SR_KEMIP_BOOL, sr_kemi_core_is_method_cancel,
1787 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1788 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1789 },
1790 { str_init(""), str_init("is_REGISTER"),
1791 SR_KEMIP_BOOL, sr_kemi_core_is_method_register,
1792 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1793 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1794 },
1795 { str_init(""), str_init("is_OPTIONS"),
1796 SR_KEMIP_BOOL, sr_kemi_core_is_method_options,
1797 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1798 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1799 },
1800 { str_init(""), str_init("is_SUBSCRIBE"),
1801 SR_KEMIP_BOOL, sr_kemi_core_is_method_subscribe,
1802 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1803 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1804 },
1805 { str_init(""), str_init("is_PUBLISH"),
1806 SR_KEMIP_BOOL, sr_kemi_core_is_method_publish,
1807 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1808 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1809 },
1810 { str_init(""), str_init("is_NOTIFY"),
1811 SR_KEMIP_BOOL, sr_kemi_core_is_method_notify,
1812 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1813 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1814 },
1815 { str_init(""), str_init("is_REFER"),
1816 SR_KEMIP_BOOL, sr_kemi_core_is_method_refer,
1817 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1818 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1819 },
1820 { str_init(""), str_init("is_INFO"),
1821 SR_KEMIP_BOOL, sr_kemi_core_is_method_info,
1822 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1823 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1824 },
1825 { str_init(""), str_init("is_UPDATE"),
1826 SR_KEMIP_BOOL, sr_kemi_core_is_method_update,
1827 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1828 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1829 },
1830 { str_init(""), str_init("is_PRACK"),
1831 SR_KEMIP_BOOL, sr_kemi_core_is_method_prack,
1832 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1833 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1834 },
1835 { str_init(""), str_init("is_MESSAGE"),
1836 SR_KEMIP_BOOL, sr_kemi_core_is_method_message,
1837 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1838 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1839 },
1840 { str_init(""), str_init("is_KDMQ"),
1841 SR_KEMIP_BOOL, sr_kemi_core_is_method_kdmq,
1842 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1843 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1844 },
1845 { str_init(""), str_init("is_GET"),
1846 SR_KEMIP_BOOL, sr_kemi_core_is_method_get,
1847 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1848 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1849 },
1850 { str_init(""), str_init("is_POST"),
1851 SR_KEMIP_BOOL, sr_kemi_core_is_method_post,
1852 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1853 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1854 },
1855 { str_init(""), str_init("is_PUT"),
1856 SR_KEMIP_BOOL, sr_kemi_core_is_method_put,
1857 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1858 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1859 },
1860 { str_init(""), str_init("is_DELETE"),
1861 SR_KEMIP_BOOL, sr_kemi_core_is_method_delete,
1862 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1863 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1864 },
1865 { str_init(""), str_init("is_UDP"),
1866 SR_KEMIP_BOOL, sr_kemi_core_is_proto_udp,
1867 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1868 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1869 },
1870 { str_init(""), str_init("is_TCP"),
1871 SR_KEMIP_BOOL, sr_kemi_core_is_proto_tcp,
1872 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1873 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1874 },
1875 { str_init(""), str_init("is_TLS"),
1876 SR_KEMIP_BOOL, sr_kemi_core_is_proto_tls,
1877 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1878 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1879 },
1880 { str_init(""), str_init("is_WS"),
1881 SR_KEMIP_BOOL, sr_kemi_core_is_proto_ws,
1882 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1883 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1884 },
1885 { str_init(""), str_init("is_WSS"),
1886 SR_KEMIP_BOOL, sr_kemi_core_is_proto_wss,
1887 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1888 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1889 },
1890 { str_init(""), str_init("is_SCTP"),
1891 SR_KEMIP_BOOL, sr_kemi_core_is_proto_sctp,
1892 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1893 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1894 },
1895 { str_init(""), str_init("is_proto"),
1896 SR_KEMIP_BOOL, sr_kemi_core_is_proto,
1897 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1898 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1899 },
1900 { str_init(""), str_init("is_IPv4"),
1901 SR_KEMIP_BOOL, sr_kemi_core_is_af_ipv4,
1902 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1903 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1904 },
1905 { str_init(""), str_init("is_IPv6"),
1906 SR_KEMIP_BOOL, sr_kemi_core_is_af_ipv6,
1907 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1908 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1909 },
1910 { str_init(""), str_init("is_src_port"),
1911 SR_KEMIP_BOOL, sr_kemi_core_is_src_port,
1912 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1913 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1914 },
1915 { str_init(""), str_init("is_dst_port"),
1916 SR_KEMIP_BOOL, sr_kemi_core_is_dst_port,
1917 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
1918 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1919 },
1920 { str_init(""), str_init("get_debug"),
1921 SR_KEMIP_INT, sr_kemi_core_get_debug,
1922 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1923 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1924 },
1925 { str_init(""), str_init("route"),
1926 SR_KEMIP_INT, sr_kemi_core_route,
1927 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1928 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1929 },
1930
1931 { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1932 };
1933
1934 /**
1935 *
1936 */
sr_kemi_hdr_append(sip_msg_t * msg,str * txt)1937 static int sr_kemi_hdr_append(sip_msg_t *msg, str *txt)
1938 {
1939 struct lump* anchor;
1940 char *hdr;
1941
1942 if(txt==NULL || txt->s==NULL || msg==NULL)
1943 return -1;
1944
1945 LM_DBG("append hf: %.*s\n", txt->len, txt->s);
1946 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
1947 LM_ERR("error while parsing message\n");
1948 return -1;
1949 }
1950
1951 hdr = (char*)pkg_malloc(txt->len);
1952 if(hdr==NULL) {
1953 PKG_MEM_ERROR;
1954 return -1;
1955 }
1956 memcpy(hdr, txt->s, txt->len);
1957 /* anchor after last header */
1958 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
1959 if((anchor==NULL)
1960 || (insert_new_lump_before(anchor, hdr, txt->len, 0) == 0)) {
1961 LM_ERR("can't insert lump\n");
1962 pkg_free(hdr);
1963 return -1;
1964 }
1965 return 1;
1966 }
1967
1968 /**
1969 *
1970 */
sr_kemi_hdr_append_after(sip_msg_t * msg,str * txt,str * hname)1971 static int sr_kemi_hdr_append_after(sip_msg_t *msg, str *txt, str *hname)
1972 {
1973 struct lump* anchor;
1974 hdr_field_t *hf;
1975 hdr_field_t hfm;
1976 char *hdr;
1977 char hbuf[SR_KEMI_HNAME_SIZE];
1978
1979 if(txt==NULL || txt->s==NULL || hname==NULL || hname->s==NULL || msg==NULL)
1980 return -1;
1981
1982 if(hname->len>SR_KEMI_HNAME_SIZE-4) {
1983 LM_ERR("header name too long: %d\n", hname->len);
1984 return -1;
1985 }
1986 memcpy(hbuf, hname->s, hname->len);
1987 hbuf[hname->len] = ':';
1988 hbuf[hname->len+1] = '\0';
1989
1990 if (parse_hname2_short(hbuf, hbuf+hname->len+1, &hfm)==0) {
1991 LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
1992 return -1;
1993 }
1994
1995 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
1996 LM_ERR("error while parsing message\n");
1997 return -1;
1998 }
1999 for (hf=msg->headers; hf; hf=hf->next) {
2000 if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
2001 if (hfm.type!=hf->type)
2002 continue;
2003 } else {
2004 if (hf->name.len!=hfm.name.len)
2005 continue;
2006 if (cmp_hdrname_str(&hf->name, &hfm.name)!=0)
2007 continue;
2008 }
2009 break;
2010 }
2011
2012 hdr = (char*)pkg_malloc(txt->len);
2013 if(hdr==NULL) {
2014 PKG_MEM_ERROR;
2015 return -1;
2016 }
2017 memcpy(hdr, txt->s, txt->len);
2018
2019 if(hf==0) { /* after last header */
2020 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
2021 } else { /* after hf */
2022 anchor = anchor_lump(msg, hf->name.s + hf->len - msg->buf, 0, 0);
2023 }
2024
2025 if((anchor==NULL)
2026 || (insert_new_lump_before(anchor, hdr, txt->len, 0) == 0)) {
2027 LM_ERR("can't insert lump\n");
2028 pkg_free(hdr);
2029 return -1;
2030 }
2031 LM_DBG("appended after [%.*s] the hf: [%.*s]\n", hname->len, hname->s,
2032 txt->len, txt->s);
2033
2034 return 1;
2035 }
2036
2037 /**
2038 *
2039 */
sr_kemi_hdr_remove(sip_msg_t * msg,str * hname)2040 int sr_kemi_hdr_remove(sip_msg_t *msg, str *hname)
2041 {
2042 struct lump* anchor;
2043 hdr_field_t *hf;
2044 hdr_field_t hfm;
2045 char hbuf[SR_KEMI_HNAME_SIZE];
2046
2047 if(hname==NULL || hname->s==NULL || msg==NULL)
2048 return -1;
2049
2050 if(hname->len>SR_KEMI_HNAME_SIZE-4) {
2051 LM_ERR("header name too long: %d\n", hname->len);
2052 return -1;
2053 }
2054 memcpy(hbuf, hname->s, hname->len);
2055 hbuf[hname->len] = ':';
2056 hbuf[hname->len+1] = '\0';
2057
2058 if (parse_hname2_short(hbuf, hbuf+hname->len+1, &hfm)==0) {
2059 LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
2060 return -1;
2061 }
2062
2063 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
2064 LM_ERR("error while parsing message\n");
2065 return -1;
2066 }
2067
2068 LM_DBG("remove hf: %.*s\n", hname->len, hname->s);
2069 for (hf=msg->headers; hf; hf=hf->next) {
2070 if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
2071 if (hfm.type!=hf->type)
2072 continue;
2073 } else {
2074 if (hf->name.len!=hname->len)
2075 continue;
2076 if(strncasecmp(hf->name.s, hname->s, hname->len)!=0)
2077 continue;
2078 }
2079 anchor=del_lump(msg, hf->name.s - msg->buf, hf->len, 0);
2080 if (anchor==0) {
2081 LM_ERR("cannot remove hdr %.*s\n", hname->len, hname->s);
2082 return -1;
2083 }
2084 }
2085 return 1;
2086 }
2087
2088 /**
2089 *
2090 */
sr_kemi_hdr_is_present(sip_msg_t * msg,str * hname)2091 static int sr_kemi_hdr_is_present(sip_msg_t *msg, str *hname)
2092 {
2093 hdr_field_t *hf;
2094 hdr_field_t hfm;
2095 char hbuf[SR_KEMI_HNAME_SIZE];
2096
2097 if(hname==NULL || hname->s==NULL || msg==NULL)
2098 return -1;
2099
2100 if(hname->len>SR_KEMI_HNAME_SIZE-4) {
2101 LM_ERR("header name too long: %d\n", hname->len);
2102 return -1;
2103 }
2104 memcpy(hbuf, hname->s, hname->len);
2105 hbuf[hname->len] = ':';
2106 hbuf[hname->len+1] = '\0';
2107
2108 if (parse_hname2_short(hbuf, hbuf+hname->len+1, &hfm)==0) {
2109 LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
2110 return -1;
2111 }
2112
2113 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
2114 LM_ERR("error while parsing message\n");
2115 return -1;
2116 }
2117
2118 LM_DBG("searching hf: %.*s\n", hname->len, hname->s);
2119 for (hf=msg->headers; hf; hf=hf->next) {
2120 if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
2121 if (hfm.type!=hf->type)
2122 continue;
2123 } else {
2124 if (hf->name.len!=hname->len)
2125 continue;
2126 if(strncasecmp(hf->name.s, hname->s, hname->len)!=0)
2127 continue;
2128 }
2129 return 1;
2130 }
2131 return -1;
2132 }
2133
2134 /**
2135 *
2136 */
sr_kemi_hdr_insert(sip_msg_t * msg,str * txt)2137 static int sr_kemi_hdr_insert(sip_msg_t *msg, str *txt)
2138 {
2139 struct lump* anchor;
2140 char *hdr;
2141
2142 if(txt==NULL || txt->s==NULL || msg==NULL)
2143 return -1;
2144
2145 LM_DBG("insert hf: %.*s\n", txt->len, txt->s);
2146 hdr = (char*)pkg_malloc(txt->len);
2147 if(hdr==NULL) {
2148 PKG_MEM_ERROR;
2149 return -1;
2150 }
2151 memcpy(hdr, txt->s, txt->len);
2152 /* anchor before first header */
2153 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
2154 if((anchor==NULL)
2155 || (insert_new_lump_before(anchor, hdr, txt->len, 0) == 0)) {
2156 LM_ERR("can't insert lump\n");
2157 pkg_free(hdr);
2158 return -1;
2159 }
2160 return 1;
2161 }
2162
2163 /**
2164 *
2165 */
sr_kemi_hdr_insert_before(sip_msg_t * msg,str * txt,str * hname)2166 static int sr_kemi_hdr_insert_before(sip_msg_t *msg, str *txt, str *hname)
2167 {
2168 struct lump* anchor;
2169 hdr_field_t *hf;
2170 hdr_field_t hfm;
2171 char *hdr;
2172 char hbuf[SR_KEMI_HNAME_SIZE];
2173
2174 if(txt==NULL || txt->s==NULL || hname==NULL || hname->s==NULL || msg==NULL)
2175 return -1;
2176
2177 if(hname->len>SR_KEMI_HNAME_SIZE-4) {
2178 LM_ERR("header name too long: %d\n", hname->len);
2179 return -1;
2180 }
2181 memcpy(hbuf, hname->s, hname->len);
2182 hbuf[hname->len] = ':';
2183 hbuf[hname->len+1] = '\0';
2184
2185 if (parse_hname2_short(hbuf, hbuf+hname->len+1, &hfm)==0) {
2186 LM_ERR("error parsing header name [%.*s]\n", hname->len, hname->s);
2187 return -1;
2188 }
2189
2190 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
2191 LM_ERR("error while parsing message\n");
2192 return -1;
2193 }
2194 for (hf=msg->headers; hf; hf=hf->next) {
2195 if (hfm.type!=HDR_OTHER_T && hfm.type!=HDR_ERROR_T) {
2196 if (hfm.type!=hf->type)
2197 continue;
2198 } else {
2199 if (hf->name.len!=hfm.name.len)
2200 continue;
2201 if (cmp_hdrname_str(&hf->name, &hfm.name)!=0)
2202 continue;
2203 }
2204 break;
2205 }
2206
2207 hdr = (char*)pkg_malloc(txt->len);
2208 if(hdr==NULL) {
2209 PKG_MEM_ERROR;
2210 return -1;
2211 }
2212 memcpy(hdr, txt->s, txt->len);
2213 if(hf==0) { /* before first header */
2214 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
2215 } else { /* before hf */
2216 anchor = anchor_lump(msg, hf->name.s - msg->buf, 0, 0);
2217 }
2218 if((anchor==NULL)
2219 || (insert_new_lump_before(anchor, hdr, txt->len, 0) == 0)) {
2220 LM_ERR("can't insert lump\n");
2221 pkg_free(hdr);
2222 return -1;
2223 }
2224 LM_DBG("inserted before [%.*s] the hf: %.*s\n", hname->len, hname->s,
2225 txt->len, txt->s);
2226
2227 return 1;
2228 }
2229
2230 /**
2231 *
2232 */
sr_kemi_hdr_rmappend(sip_msg_t * msg,str * hrm,str * hadd)2233 static int sr_kemi_hdr_rmappend(sip_msg_t *msg, str *hrm, str *hadd)
2234 {
2235 int ret;
2236
2237 ret = sr_kemi_hdr_remove(msg, hrm);
2238 if(ret<0) {
2239 return ret;
2240 }
2241 return sr_kemi_hdr_append(msg, hadd);
2242 }
2243
2244 /**
2245 *
2246 */
sr_kemi_hdr_rminsert(sip_msg_t * msg,str * hrm,str * hadd)2247 static int sr_kemi_hdr_rminsert(sip_msg_t *msg, str *hrm, str *hadd)
2248 {
2249 int ret;
2250
2251 ret = sr_kemi_hdr_remove(msg, hrm);
2252 if(ret<0) {
2253 return ret;
2254 }
2255 return sr_kemi_hdr_insert(msg, hadd);
2256 }
2257
2258
2259 /**
2260 *
2261 */
sr_kemi_hdr_append_to_reply(sip_msg_t * msg,str * txt)2262 static int sr_kemi_hdr_append_to_reply(sip_msg_t *msg, str *txt)
2263 {
2264 if(txt==NULL || txt->s==NULL || msg==NULL)
2265 return -1;
2266
2267 LM_DBG("append to reply: %.*s\n", txt->len, txt->s);
2268
2269 if(add_lump_rpl(msg, txt->s, txt->len, LUMP_RPL_HDR)==0) {
2270 LM_ERR("unable to add reply lump\n");
2271 return -1;
2272 }
2273
2274 return 1;
2275 }
2276
2277 /**
2278 *
2279 */
sr_kemi_hdr_get_mode(sip_msg_t * msg,str * hname,int idx,int rmode)2280 static sr_kemi_xval_t* sr_kemi_hdr_get_mode(sip_msg_t *msg, str *hname, int idx,
2281 int rmode)
2282 {
2283 char hbuf[256];
2284 str s;
2285 hdr_field_t shdr;
2286 hdr_field_t *ihdr;
2287 #define SR_KEMI_VHDR_SIZE 256
2288 hdr_field_t *vhdr[SR_KEMI_VHDR_SIZE];
2289 int n;
2290 int hmatch;
2291
2292 memset(&_sr_kemi_xval, 0, sizeof(sr_kemi_xval_t));
2293
2294 if(msg==NULL) {
2295 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2296 return &_sr_kemi_xval;
2297 }
2298 /* we need to be sure we have parsed all headers */
2299 if(parse_headers(msg, HDR_EOH_F, 0)<0) {
2300 LM_ERR("error parsing headers\n");
2301 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2302 return &_sr_kemi_xval;
2303 }
2304 if(hname->len>=252) {
2305 LM_ERR("header name too long\n");
2306 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2307 return &_sr_kemi_xval;
2308 }
2309
2310 memcpy(hbuf, hname->s, hname->len);
2311 hbuf[hname->len] = ':';
2312 hbuf[hname->len+1] = '\0';
2313 s.s = hbuf;
2314 s.len = hname->len + 1;
2315
2316 if (parse_hname2_short(s.s, s.s + s.len, &shdr)==0) {
2317 LM_ERR("error parsing header name [%.*s]\n", s.len, s.s);
2318 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2319 return &_sr_kemi_xval;
2320 }
2321 n = 0;
2322 for (ihdr=msg->headers; ihdr; ihdr=ihdr->next) {
2323 hmatch = 0;
2324 if (shdr.type!=HDR_OTHER_T && shdr.type!=HDR_ERROR_T) {
2325 /* find by type */
2326 if (shdr.type==ihdr->type) {
2327 hmatch = 1;
2328 }
2329 } else {
2330 /* find by name */
2331 if (cmp_hdrname_str(&ihdr->name, hname)==0) {
2332 hmatch = 1;
2333 }
2334 }
2335 if (hmatch == 1) {
2336 if(idx==n) {
2337 break;
2338 } else {
2339 if(idx<0) {
2340 vhdr[n] = ihdr;
2341 }
2342 n++;
2343 if(n==SR_KEMI_VHDR_SIZE) {
2344 LM_DBG("too many headers with name: %.*s\n",
2345 hname->len, hname->s);
2346 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2347 return &_sr_kemi_xval;
2348 }
2349 }
2350 }
2351 }
2352 if(idx>=0) {
2353 if(ihdr==NULL) {
2354 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2355 return &_sr_kemi_xval;
2356 }
2357 } else {
2358 if(n + idx < 0) {
2359 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2360 return &_sr_kemi_xval;
2361 }
2362 ihdr = vhdr[n + idx];
2363 }
2364
2365 _sr_kemi_xval.vtype = SR_KEMIP_STR;
2366 _sr_kemi_xval.v.s = ihdr->body;
2367 return &_sr_kemi_xval;
2368 }
2369
2370 /**
2371 *
2372 */
sr_kemi_hdr_get(sip_msg_t * msg,str * hname)2373 static sr_kemi_xval_t* sr_kemi_hdr_get(sip_msg_t *msg, str *hname)
2374 {
2375 return sr_kemi_hdr_get_mode(msg, hname, 0, SR_KEMI_XVAL_NULL_NONE);
2376 }
2377
2378 /**
2379 *
2380 */
sr_kemi_hdr_gete(sip_msg_t * msg,str * hname)2381 static sr_kemi_xval_t* sr_kemi_hdr_gete(sip_msg_t *msg, str *hname)
2382 {
2383 return sr_kemi_hdr_get_mode(msg, hname, 0, SR_KEMI_XVAL_NULL_EMPTY);
2384 }
2385
2386 /**
2387 *
2388 */
sr_kemi_hdr_getw(sip_msg_t * msg,str * hname)2389 static sr_kemi_xval_t* sr_kemi_hdr_getw(sip_msg_t *msg, str *hname)
2390 {
2391 return sr_kemi_hdr_get_mode(msg, hname, 0, SR_KEMI_XVAL_NULL_PRINT);
2392 }
2393
2394 /**
2395 *
2396 */
sr_kemi_hdr_get_idx(sip_msg_t * msg,str * hname,int idx)2397 static sr_kemi_xval_t* sr_kemi_hdr_get_idx(sip_msg_t *msg, str *hname, int idx)
2398 {
2399 return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_NONE);
2400 }
2401
2402 /**
2403 *
2404 */
sr_kemi_hdr_gete_idx(sip_msg_t * msg,str * hname,int idx)2405 static sr_kemi_xval_t* sr_kemi_hdr_gete_idx(sip_msg_t *msg, str *hname, int idx)
2406 {
2407 return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_EMPTY);
2408 }
2409
2410 /**
2411 *
2412 */
sr_kemi_hdr_getw_idx(sip_msg_t * msg,str * hname,int idx)2413 static sr_kemi_xval_t* sr_kemi_hdr_getw_idx(sip_msg_t *msg, str *hname, int idx)
2414 {
2415 return sr_kemi_hdr_get_mode(msg, hname, idx, SR_KEMI_XVAL_NULL_PRINT);
2416 }
2417
2418 /**
2419 *
2420 */
2421 static sr_kemi_t _sr_kemi_hdr[] = {
2422 { str_init("hdr"), str_init("append"),
2423 SR_KEMIP_INT, sr_kemi_hdr_append,
2424 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2425 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2426 },
2427 { str_init("hdr"), str_init("append_after"),
2428 SR_KEMIP_INT, sr_kemi_hdr_append_after,
2429 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2430 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2431 },
2432 { str_init("hdr"), str_init("insert"),
2433 SR_KEMIP_INT, sr_kemi_hdr_insert,
2434 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2435 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2436 },
2437 { str_init("hdr"), str_init("insert_before"),
2438 SR_KEMIP_INT, sr_kemi_hdr_insert_before,
2439 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2440 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2441 },
2442 { str_init("hdr"), str_init("remove"),
2443 SR_KEMIP_INT, sr_kemi_hdr_remove,
2444 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2445 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2446 },
2447 { str_init("hdr"), str_init("rmappend"),
2448 SR_KEMIP_INT, sr_kemi_hdr_rmappend,
2449 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2450 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2451 },
2452 { str_init("hdr"), str_init("rminsert"),
2453 SR_KEMIP_INT, sr_kemi_hdr_rminsert,
2454 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2455 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2456 },
2457 { str_init("hdr"), str_init("is_present"),
2458 SR_KEMIP_INT, sr_kemi_hdr_is_present,
2459 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2460 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2461 },
2462 { str_init("hdr"), str_init("append_to_reply"),
2463 SR_KEMIP_INT, sr_kemi_hdr_append_to_reply,
2464 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2465 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2466 },
2467 { str_init("hdr"), str_init("get"),
2468 SR_KEMIP_XVAL, sr_kemi_hdr_get,
2469 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2470 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2471 },
2472 { str_init("hdr"), str_init("gete"),
2473 SR_KEMIP_XVAL, sr_kemi_hdr_gete,
2474 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2475 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2476 },
2477 { str_init("hdr"), str_init("getw"),
2478 SR_KEMIP_XVAL, sr_kemi_hdr_getw,
2479 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2480 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2481 },
2482 { str_init("hdr"), str_init("get_idx"),
2483 SR_KEMIP_XVAL, sr_kemi_hdr_get_idx,
2484 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2485 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2486 },
2487 { str_init("hdr"), str_init("gete_idx"),
2488 SR_KEMIP_XVAL, sr_kemi_hdr_gete_idx,
2489 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2490 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2491 },
2492 { str_init("hdr"), str_init("getw_idx"),
2493 SR_KEMIP_XVAL, sr_kemi_hdr_getw_idx,
2494 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2495 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2496 },
2497
2498 { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2499 };
2500
2501
2502 /**
2503 *
2504 */
sr_kemi_xval_null(sr_kemi_xval_t * xval,int rmode)2505 void sr_kemi_xval_null(sr_kemi_xval_t *xval, int rmode)
2506 {
2507 switch(rmode) {
2508 case SR_KEMI_XVAL_NULL_PRINT:
2509 xval->vtype = SR_KEMIP_STR;
2510 xval->v.s = *pv_get_null_str();
2511 return;
2512 case SR_KEMI_XVAL_NULL_EMPTY:
2513 xval->vtype = SR_KEMIP_STR;
2514 xval->v.s = *pv_get_empty_str();
2515 return;
2516 case SR_KEMI_XVAL_NULL_ZERO:
2517 xval->vtype = SR_KEMIP_INT;
2518 xval->v.n = 0;
2519 return;
2520 default:
2521 xval->vtype = SR_KEMIP_NULL;
2522 xval->v.s.s = NULL;
2523 xval->v.s.len = 0;
2524 return;
2525 }
2526 }
2527
2528 /**
2529 *
2530 */
sr_kemi_dict_item_free(sr_kemi_dict_item_t * item)2531 void sr_kemi_dict_item_free(sr_kemi_dict_item_t *item)
2532 {
2533 sr_kemi_dict_item_t *v;
2534
2535 while(item) {
2536 if (item->vtype == SR_KEMIP_ARRAY || item->vtype == SR_KEMIP_DICT) {
2537 sr_kemi_dict_item_free(item->v.dict);
2538 }
2539 v = item;
2540 item = item->next;
2541 pkg_free(v);
2542 }
2543 }
2544
2545 /**
2546 *
2547 */
sr_kemi_xval_free(sr_kemi_xval_t * xval)2548 void sr_kemi_xval_free(sr_kemi_xval_t *xval)
2549 {
2550 if(xval && (xval->vtype == SR_KEMIP_ARRAY || xval->vtype == SR_KEMIP_DICT))
2551 {
2552 sr_kemi_dict_item_free(xval->v.dict);
2553 }
2554 }
2555
2556 /**
2557 *
2558 */
sr_kemi_pv_get_mode(sip_msg_t * msg,str * pvn,int rmode)2559 static sr_kemi_xval_t* sr_kemi_pv_get_mode(sip_msg_t *msg, str *pvn, int rmode)
2560 {
2561 pv_spec_t *pvs;
2562 pv_value_t val;
2563 int pl;
2564
2565 memset(&_sr_kemi_xval, 0, sizeof(sr_kemi_xval_t));
2566
2567 LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
2568 pl = pv_locate_name(pvn);
2569 if(pl != pvn->len) {
2570 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2571 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2572 return &_sr_kemi_xval;
2573 }
2574 pvs = pv_cache_get(pvn);
2575 if(pvs==NULL) {
2576 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2577 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2578 return &_sr_kemi_xval;
2579 }
2580
2581 memset(&val, 0, sizeof(pv_value_t));
2582 if(pv_get_spec_value(msg, pvs, &val) != 0) {
2583 LM_ERR("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
2584 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2585 return &_sr_kemi_xval;
2586 }
2587 if(val.flags&PV_VAL_NULL) {
2588 sr_kemi_xval_null(&_sr_kemi_xval, rmode);
2589 return &_sr_kemi_xval;
2590 }
2591 if(val.flags&PV_TYPE_INT) {
2592 _sr_kemi_xval.vtype = SR_KEMIP_INT;
2593 _sr_kemi_xval.v.n = val.ri;
2594 return &_sr_kemi_xval;
2595 }
2596 _sr_kemi_xval.vtype = SR_KEMIP_STR;
2597 _sr_kemi_xval.v.s = val.rs;
2598 return &_sr_kemi_xval;
2599 }
2600
2601 /**
2602 *
2603 */
sr_kemi_pv_get(sip_msg_t * msg,str * pvn)2604 static sr_kemi_xval_t* sr_kemi_pv_get(sip_msg_t *msg, str *pvn)
2605 {
2606 return sr_kemi_pv_get_mode(msg, pvn, SR_KEMI_XVAL_NULL_NONE);
2607 }
2608
2609 /**
2610 *
2611 */
sr_kemi_pv_getw(sip_msg_t * msg,str * pvn)2612 static sr_kemi_xval_t* sr_kemi_pv_getw(sip_msg_t *msg, str *pvn)
2613 {
2614 return sr_kemi_pv_get_mode(msg, pvn, SR_KEMI_XVAL_NULL_PRINT);
2615 }
2616
2617 /**
2618 *
2619 */
sr_kemi_pv_gete(sip_msg_t * msg,str * pvn)2620 static sr_kemi_xval_t* sr_kemi_pv_gete(sip_msg_t *msg, str *pvn)
2621 {
2622 return sr_kemi_pv_get_mode(msg, pvn, SR_KEMI_XVAL_NULL_EMPTY);
2623 }
2624
2625 /**
2626 *
2627 */
sr_kemi_pv_push_valx(sr_kemi_xval_t * xval,int rmode,int vi,str * vs)2628 static void sr_kemi_pv_push_valx (sr_kemi_xval_t *xval, int rmode, int vi, str *vs)
2629 {
2630 if(rmode==1) {
2631 xval->vtype = SR_KEMIP_INT;
2632 xval->v.n = vi;
2633 } else {
2634 xval->vtype = SR_KEMIP_STR;
2635 xval->v.s = *vs;
2636 }
2637 }
2638
2639 /**
2640 *
2641 */
sr_kemi_pv_get_valx(sip_msg_t * msg,str * pvn,str * xsval,int xival,int rmode)2642 static sr_kemi_xval_t* sr_kemi_pv_get_valx (sip_msg_t *msg, str *pvn, str *xsval,
2643 int xival, int rmode)
2644 {
2645 pv_spec_t *pvs;
2646 pv_value_t val;
2647 int pl;
2648
2649 memset(&_sr_kemi_xval, 0, sizeof(sr_kemi_xval_t));
2650
2651 LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
2652 pl = pv_locate_name(pvn);
2653 if(pl != pvn->len) {
2654 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2655 sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
2656 return &_sr_kemi_xval;
2657 }
2658 pvs = pv_cache_get(pvn);
2659 if(pvs==NULL) {
2660 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2661 sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
2662 return &_sr_kemi_xval;
2663 }
2664
2665 memset(&val, 0, sizeof(pv_value_t));
2666 if(pv_get_spec_value(msg, pvs, &val) != 0) {
2667 LM_ERR("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
2668 sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
2669 return &_sr_kemi_xval;
2670 }
2671 if(val.flags&PV_VAL_NULL) {
2672 sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
2673 return &_sr_kemi_xval;
2674 }
2675 if(val.flags&PV_TYPE_INT) {
2676 _sr_kemi_xval.vtype = SR_KEMIP_INT;
2677 _sr_kemi_xval.v.n = val.ri;
2678 return &_sr_kemi_xval;
2679 }
2680 _sr_kemi_xval.vtype = SR_KEMIP_STR;
2681 _sr_kemi_xval.v.s = val.rs;
2682 return &_sr_kemi_xval;
2683 }
2684
2685 /**
2686 *
2687 */
sr_kemi_pv_getvs(sip_msg_t * msg,str * pvn,str * xsval)2688 static sr_kemi_xval_t* sr_kemi_pv_getvs (sip_msg_t *msg, str *pvn, str *xsval)
2689 {
2690 return sr_kemi_pv_get_valx (msg, pvn, xsval, 0, 0);
2691 }
2692
2693 /**
2694 *
2695 */
sr_kemi_pv_getvn(sip_msg_t * msg,str * pvn,int xival)2696 static sr_kemi_xval_t* sr_kemi_pv_getvn (sip_msg_t *msg, str *pvn, int xival)
2697 {
2698 return sr_kemi_pv_get_valx (msg, pvn, NULL, xival, 1);
2699 }
2700
2701 /**
2702 *
2703 */
sr_kemi_pv_seti(sip_msg_t * msg,str * pvn,int ival)2704 static int sr_kemi_pv_seti (sip_msg_t *msg, str *pvn, int ival)
2705 {
2706 pv_spec_t *pvs;
2707 pv_value_t val;
2708 int pl;
2709
2710 LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
2711 pl = pv_locate_name(pvn);
2712 if(pl != pvn->len) {
2713 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2714 return SR_KEMI_FALSE;
2715 }
2716 pvs = pv_cache_get(pvn);
2717 if(pvs==NULL) {
2718 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2719 return SR_KEMI_FALSE;
2720 }
2721
2722 memset(&val, 0, sizeof(pv_value_t));
2723 val.ri = ival;
2724 val.flags |= PV_TYPE_INT|PV_VAL_INT;
2725
2726 if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
2727 LM_ERR("unable to set pv [%.*s]\n", pvn->len, pvn->s);
2728 return SR_KEMI_FALSE;
2729 }
2730
2731 return SR_KEMI_TRUE;
2732 }
2733
2734 /**
2735 *
2736 */
sr_kemi_pv_sets(sip_msg_t * msg,str * pvn,str * sval)2737 static int sr_kemi_pv_sets (sip_msg_t *msg, str *pvn, str *sval)
2738 {
2739 pv_spec_t *pvs;
2740 pv_value_t val;
2741 int pl;
2742
2743 LM_DBG("pv set: %.*s\n", pvn->len, pvn->s);
2744 pl = pv_locate_name(pvn);
2745 if(pl != pvn->len) {
2746 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2747 return SR_KEMI_FALSE;
2748 }
2749 pvs = pv_cache_get(pvn);
2750 if(pvs==NULL) {
2751 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2752 return SR_KEMI_FALSE;
2753 }
2754
2755 memset(&val, 0, sizeof(pv_value_t));
2756 val.rs = *sval;
2757 val.flags |= PV_VAL_STR;
2758
2759 if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
2760 LM_ERR("unable to set pv [%.*s]\n", pvn->len, pvn->s);
2761 return SR_KEMI_FALSE;
2762 }
2763
2764 return SR_KEMI_TRUE;
2765 }
2766
2767 /**
2768 *
2769 */
sr_kemi_pv_unset(sip_msg_t * msg,str * pvn)2770 static int sr_kemi_pv_unset (sip_msg_t *msg, str *pvn)
2771 {
2772 pv_spec_t *pvs;
2773 pv_value_t val;
2774 int pl;
2775
2776 LM_DBG("pv unset: %.*s\n", pvn->len, pvn->s);
2777 pl = pv_locate_name(pvn);
2778 if(pl != pvn->len) {
2779 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2780 return SR_KEMI_FALSE;
2781 }
2782 pvs = pv_cache_get(pvn);
2783 if(pvs==NULL) {
2784 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2785 return SR_KEMI_FALSE;
2786 }
2787 memset(&val, 0, sizeof(pv_value_t));
2788 val.flags |= PV_VAL_NULL;
2789 if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
2790 LM_ERR("unable to unset pv [%.*s]\n", pvn->len, pvn->s);
2791 return SR_KEMI_FALSE;
2792 }
2793
2794 return SR_KEMI_TRUE;
2795 }
2796
2797 /**
2798 *
2799 */
sr_kemi_pv_is_null(sip_msg_t * msg,str * pvn)2800 static int sr_kemi_pv_is_null (sip_msg_t *msg, str *pvn)
2801 {
2802 pv_spec_t *pvs;
2803 pv_value_t val;
2804 int pl;
2805
2806 LM_DBG("pv is null test: %.*s\n", pvn->len, pvn->s);
2807 pl = pv_locate_name(pvn);
2808 if(pl != pvn->len) {
2809 LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
2810 return SR_KEMI_TRUE;
2811 }
2812 pvs = pv_cache_get(pvn);
2813 if(pvs==NULL) {
2814 LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
2815 return SR_KEMI_TRUE;
2816 }
2817
2818 memset(&val, 0, sizeof(pv_value_t));
2819 if(pv_get_spec_value(msg, pvs, &val) != 0) {
2820 LM_NOTICE("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
2821 return SR_KEMI_TRUE;
2822 }
2823 if(val.flags&PV_VAL_NULL) {
2824 return SR_KEMI_TRUE;
2825 } else {
2826 return SR_KEMI_FALSE;
2827 }
2828 }
2829
2830 /**
2831 *
2832 */
2833 static sr_kemi_t _sr_kemi_pv[] = {
2834 { str_init("pv"), str_init("get"),
2835 SR_KEMIP_XVAL, sr_kemi_pv_get,
2836 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2837 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2838 },
2839 { str_init("pv"), str_init("getw"),
2840 SR_KEMIP_XVAL, sr_kemi_pv_getw,
2841 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2842 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2843 },
2844 { str_init("pv"), str_init("gete"),
2845 SR_KEMIP_XVAL, sr_kemi_pv_gete,
2846 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2847 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2848 },
2849 { str_init("pv"), str_init("getvn"),
2850 SR_KEMIP_XVAL, sr_kemi_pv_getvn,
2851 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2852 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2853 },
2854 { str_init("pv"), str_init("getvs"),
2855 SR_KEMIP_XVAL, sr_kemi_pv_getvs,
2856 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2857 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2858 },
2859 { str_init("pv"), str_init("seti"),
2860 SR_KEMIP_BOOL, sr_kemi_pv_seti,
2861 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2862 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2863 },
2864 { str_init("pv"), str_init("sets"),
2865 SR_KEMIP_BOOL, sr_kemi_pv_sets,
2866 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2867 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2868 },
2869 { str_init("pv"), str_init("unset"),
2870 SR_KEMIP_BOOL, sr_kemi_pv_unset,
2871 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2872 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2873 },
2874 { str_init("pv"), str_init("is_null"),
2875 SR_KEMIP_BOOL, sr_kemi_pv_is_null,
2876 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2877 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2878 },
2879
2880 { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2881 };
2882
2883 /**
2884 *
2885 */
sr_kemi_exports_get_pv(void)2886 sr_kemi_t* sr_kemi_exports_get_pv(void)
2887 {
2888 return _sr_kemi_pv;
2889 }
2890
2891 #define SR_KEMI_MODULES_MAX_SIZE 1024
2892 static int _sr_kemi_modules_size = 0;
2893 static sr_kemi_module_t _sr_kemi_modules[SR_KEMI_MODULES_MAX_SIZE];
2894
2895 /**
2896 *
2897 */
sr_kemi_modules_add(sr_kemi_t * klist)2898 int sr_kemi_modules_add(sr_kemi_t *klist)
2899 {
2900 if(_sr_kemi_modules_size>=SR_KEMI_MODULES_MAX_SIZE) {
2901 LM_ERR("exceeded max number of modules\n");
2902 return -1;
2903 }
2904 if(_sr_kemi_modules_size==0) {
2905 LM_DBG("adding core module\n");
2906 _sr_kemi_modules[_sr_kemi_modules_size].mname = _sr_kemi_core[0].mname;
2907 _sr_kemi_modules[_sr_kemi_modules_size].kexp = _sr_kemi_core;
2908 _sr_kemi_modules_size++;
2909 LM_DBG("adding pv module\n");
2910 _sr_kemi_modules[_sr_kemi_modules_size].mname = _sr_kemi_pv[0].mname;
2911 _sr_kemi_modules[_sr_kemi_modules_size].kexp = _sr_kemi_pv;
2912 _sr_kemi_modules_size++;
2913 LM_DBG("adding hdr module\n");
2914 _sr_kemi_modules[_sr_kemi_modules_size].mname = _sr_kemi_hdr[0].mname;
2915 _sr_kemi_modules[_sr_kemi_modules_size].kexp = _sr_kemi_hdr;
2916 _sr_kemi_modules_size++;
2917 }
2918 if((_sr_kemi_modules_size>1)
2919 && (_sr_kemi_modules[_sr_kemi_modules_size-1].mname.len
2920 ==klist[0].mname.len)
2921 && (strncmp(_sr_kemi_modules[_sr_kemi_modules_size-1].mname.s,
2922 klist[0].mname.s, klist[0].mname.len)==0)) {
2923 /* handle re-open of the module */
2924 LM_DBG("updating module: %.*s\n", klist[0].mname.len, klist[0].mname.s);
2925 _sr_kemi_modules[_sr_kemi_modules_size-1].kexp = klist;
2926 } else {
2927 LM_DBG("adding module: %.*s\n", klist[0].mname.len, klist[0].mname.s);
2928 _sr_kemi_modules[_sr_kemi_modules_size].mname = klist[0].mname;
2929 _sr_kemi_modules[_sr_kemi_modules_size].kexp = klist;
2930 _sr_kemi_modules_size++;
2931 }
2932 return 0;
2933 }
2934
2935 /**
2936 *
2937 */
sr_kemi_modules_size_get(void)2938 int sr_kemi_modules_size_get(void)
2939 {
2940 return _sr_kemi_modules_size;
2941 }
2942
2943 /**
2944 *
2945 */
sr_kemi_modules_get(void)2946 sr_kemi_module_t* sr_kemi_modules_get(void)
2947 {
2948 return _sr_kemi_modules;
2949 }
2950
2951 /**
2952 *
2953 */
sr_kemi_lookup(str * mname,int midx,str * fname)2954 sr_kemi_t* sr_kemi_lookup(str *mname, int midx, str *fname)
2955 {
2956 int i;
2957 sr_kemi_t *ket;
2958
2959 if(mname==NULL || mname->len<=0) {
2960 for(i=0; _sr_kemi_core[i].fname.s!=NULL; i++) {
2961 ket = &_sr_kemi_core[i];
2962 if(ket->fname.len==fname->len
2963 && strncasecmp(ket->fname.s, fname->s, fname->len)==0) {
2964 return ket;
2965 }
2966 }
2967 } else {
2968 if(midx>0 && midx<SR_KEMI_MODULES_MAX_SIZE) {
2969 for(i=0; _sr_kemi_modules[midx].kexp[i].fname.s!=NULL; i++) {
2970 ket = &_sr_kemi_modules[midx].kexp[i];
2971 if(ket->fname.len==fname->len
2972 && strncasecmp(ket->fname.s, fname->s, fname->len)==0) {
2973 return ket;
2974 }
2975 }
2976 }
2977 }
2978 return NULL;
2979 }
2980
2981 /**
2982 *
2983 */
2984
2985 #define SR_KEMI_ENG_LIST_MAX_SIZE 8
2986 static sr_kemi_eng_t _sr_kemi_eng_list[SR_KEMI_ENG_LIST_MAX_SIZE];
2987 sr_kemi_eng_t *_sr_kemi_eng = NULL;
2988 static int _sr_kemi_eng_list_size=0;
2989
2990 /**
2991 *
2992 */
sr_kemi_eng_register(str * ename,sr_kemi_eng_route_f froute)2993 int sr_kemi_eng_register(str *ename, sr_kemi_eng_route_f froute)
2994 {
2995 int i;
2996
2997 for(i=0; i<_sr_kemi_eng_list_size; i++) {
2998 if(_sr_kemi_eng_list[i].ename.len==ename->len
2999 && strncasecmp(_sr_kemi_eng_list[i].ename.s, ename->s,
3000 ename->len)==0) {
3001 /* found */
3002 return 1;
3003 }
3004 }
3005 if(_sr_kemi_eng_list_size>=SR_KEMI_ENG_LIST_MAX_SIZE) {
3006 LM_ERR("too many config routing engines registered\n");
3007 return -1;
3008 }
3009 if(ename->len>=SR_KEMI_BNAME_SIZE) {
3010 LM_ERR("config routing engine name too long\n");
3011 return -1;
3012 }
3013 strncpy(_sr_kemi_eng_list[_sr_kemi_eng_list_size].bname,
3014 ename->s, ename->len);
3015 _sr_kemi_eng_list[_sr_kemi_eng_list_size].ename.s
3016 = _sr_kemi_eng_list[_sr_kemi_eng_list_size].bname;
3017 _sr_kemi_eng_list[_sr_kemi_eng_list_size].ename.len = ename->len;
3018 _sr_kemi_eng_list[_sr_kemi_eng_list_size].ename.s[ename->len] = 0;
3019 _sr_kemi_eng_list[_sr_kemi_eng_list_size].froute = froute;
3020 _sr_kemi_eng_list_size++;
3021
3022 LM_DBG("registered config routing enginge [%.*s]\n",
3023 ename->len, ename->s);
3024
3025 return 0;
3026 }
3027
3028 /**
3029 *
3030 */
sr_kemi_eng_set(str * ename,str * cpath)3031 int sr_kemi_eng_set(str *ename, str *cpath)
3032 {
3033 int i;
3034
3035 /* skip native and default */
3036 if(ename->len==6 && strncasecmp(ename->s, "native", 6)==0) {
3037 return 0;
3038 }
3039 if(ename->len==7 && strncasecmp(ename->s, "default", 7)==0) {
3040 return 0;
3041 }
3042
3043 if(sr_kemi_cbname_list_init()<0) {
3044 return -1;
3045 }
3046
3047 for(i=0; i<_sr_kemi_eng_list_size; i++) {
3048 if(_sr_kemi_eng_list[i].ename.len==ename->len
3049 && strncasecmp(_sr_kemi_eng_list[i].ename.s, ename->s,
3050 ename->len)==0) {
3051 /* found */
3052 _sr_kemi_eng = &_sr_kemi_eng_list[i];
3053 return 0;
3054 }
3055 }
3056 return -1;
3057 }
3058
3059 /**
3060 *
3061 */
sr_kemi_eng_setz(char * ename,char * cpath)3062 int sr_kemi_eng_setz(char *ename, char *cpath)
3063 {
3064 str sname;
3065 str spath;
3066
3067 sname.s = ename;
3068 sname.len = strlen(ename);
3069
3070 if(cpath!=0) {
3071 spath.s = cpath;
3072 spath.len = strlen(cpath);
3073 return sr_kemi_eng_set(&sname, &spath);
3074 } else {
3075 return sr_kemi_eng_set(&sname, NULL);
3076 }
3077 }
3078
3079 /**
3080 *
3081 */
sr_kemi_eng_get(void)3082 sr_kemi_eng_t* sr_kemi_eng_get(void)
3083 {
3084 return _sr_kemi_eng;
3085 }
3086
3087 /**
3088 *
3089 */
3090 #define KEMI_CBNAME_MAX_LEN 128
3091 #define KEMI_CBNAME_LIST_SIZE 256
3092
3093 typedef struct sr_kemi_cbname {
3094 str name;
3095 char bname[KEMI_CBNAME_MAX_LEN];
3096 } sr_kemi_cbname_t;
3097
3098 static gen_lock_t *_sr_kemi_cbname_lock = 0;
3099 static sr_kemi_cbname_t *_sr_kemi_cbname_list = NULL;
3100 static int *_sr_kemi_cbname_list_size = NULL;
3101
3102 /**
3103 *
3104 */
sr_kemi_cbname_list_init(void)3105 int sr_kemi_cbname_list_init(void)
3106 {
3107 if(_sr_kemi_cbname_list!=NULL) {
3108 return 0;
3109 }
3110 if ( (_sr_kemi_cbname_lock=lock_alloc())==0) {
3111 LM_CRIT("failed to alloc lock\n");
3112 return -1;
3113 }
3114 if (lock_init(_sr_kemi_cbname_lock)==0 ) {
3115 LM_CRIT("failed to init lock\n");
3116 lock_dealloc(_sr_kemi_cbname_lock);
3117 _sr_kemi_cbname_lock = NULL;
3118 return -1;
3119 }
3120 _sr_kemi_cbname_list_size = shm_malloc(sizeof(int));
3121 if(_sr_kemi_cbname_list_size==NULL) {
3122 lock_destroy(_sr_kemi_cbname_lock);
3123 lock_dealloc(_sr_kemi_cbname_lock);
3124 SHM_MEM_ERROR;
3125 return -1;
3126 }
3127 *_sr_kemi_cbname_list_size = 0;
3128 _sr_kemi_cbname_list
3129 = shm_malloc(KEMI_CBNAME_LIST_SIZE*sizeof(sr_kemi_cbname_t));
3130 if(_sr_kemi_cbname_list==NULL) {
3131 SHM_MEM_ERROR;
3132 shm_free(_sr_kemi_cbname_list_size);
3133 _sr_kemi_cbname_list_size = NULL;
3134 lock_destroy(_sr_kemi_cbname_lock);
3135 lock_dealloc(_sr_kemi_cbname_lock);
3136 _sr_kemi_cbname_lock = NULL;
3137 return -1;
3138 }
3139 memset(_sr_kemi_cbname_list, 0,
3140 KEMI_CBNAME_LIST_SIZE*sizeof(sr_kemi_cbname_t));
3141 return 0;
3142 }
3143
3144 /**
3145 *
3146 */
sr_kemi_cbname_lookup_name(str * name)3147 int sr_kemi_cbname_lookup_name(str *name)
3148 {
3149 int n;
3150 int i;
3151
3152 if(_sr_kemi_cbname_list==NULL) {
3153 return 0;
3154 }
3155 if(name->len >= KEMI_CBNAME_MAX_LEN) {
3156 LM_ERR("callback name is too long [%.*s] (max: %d)\n",
3157 name->len, name->s, KEMI_CBNAME_MAX_LEN);
3158 return 0;
3159 }
3160 n = *_sr_kemi_cbname_list_size;
3161
3162 for(i=0; i<n; i++) {
3163 if(_sr_kemi_cbname_list[i].name.len==name->len
3164 && strncmp(_sr_kemi_cbname_list[i].name.s,
3165 name->s, name->len)==0) {
3166 return i+1;
3167 }
3168 }
3169
3170 /* not found -- add it */
3171 lock_get(_sr_kemi_cbname_lock);
3172
3173 /* check if new callback were indexed meanwhile */
3174 for(; i<*_sr_kemi_cbname_list_size; i++) {
3175 if(_sr_kemi_cbname_list[i].name.len==name->len
3176 && strncmp(_sr_kemi_cbname_list[i].name.s,
3177 name->s, name->len)==0) {
3178 lock_release(_sr_kemi_cbname_lock);
3179 return i+1;
3180 }
3181 }
3182 if(*_sr_kemi_cbname_list_size>=KEMI_CBNAME_LIST_SIZE) {
3183 lock_release(_sr_kemi_cbname_lock);
3184 LM_ERR("no more space to index callbacks\n");
3185 return 0;
3186 }
3187 strncpy(_sr_kemi_cbname_list[i].bname, name->s, name->len);
3188 _sr_kemi_cbname_list[i].bname[name->len] = '\0';
3189 _sr_kemi_cbname_list[i].name.s = _sr_kemi_cbname_list[i].bname;
3190 _sr_kemi_cbname_list[i].name.len = name->len;
3191 i++;
3192 *_sr_kemi_cbname_list_size = i;
3193 lock_release(_sr_kemi_cbname_lock);
3194 return i;
3195 }
3196
3197 /**
3198 *
3199 */
sr_kemi_cbname_lookup_idx(int idx)3200 str* sr_kemi_cbname_lookup_idx(int idx)
3201 {
3202 int n;
3203
3204 if(_sr_kemi_cbname_list==NULL) {
3205 return NULL;
3206 }
3207 n = *_sr_kemi_cbname_list_size;
3208 if(idx<1 || idx>n) {
3209 LM_ERR("index %d is out of range\n", idx);
3210 return NULL;
3211 }
3212 return &_sr_kemi_cbname_list[idx-1].name;
3213 }
3214
3215 /**
3216 *
3217 */
3218 typedef struct sr_kemi_param_map {
3219 int ptype;
3220 str pname;
3221 } sr_kemi_param_map_t;
3222
3223 /**
3224 *
3225 */
3226 static sr_kemi_param_map_t _sr_kemi_param_map[] = {
3227 { SR_KEMIP_NONE, str_init("none") },
3228 { SR_KEMIP_INT, str_init("int") },
3229 { SR_KEMIP_STR, str_init("str") },
3230 { SR_KEMIP_BOOL, str_init("bool") },
3231 { SR_KEMIP_XVAL, str_init("xval") },
3232 { 0, STR_NULL }
3233 };
3234
3235 /**
3236 *
3237 */
sr_kemi_param_map_get_name(int ptype)3238 str *sr_kemi_param_map_get_name(int ptype)
3239 {
3240 int i;
3241
3242 for(i=0; _sr_kemi_param_map[i].pname.s!=NULL; i++) {
3243 if(_sr_kemi_param_map[i].ptype==ptype)
3244 return &_sr_kemi_param_map[i].pname;
3245 }
3246 return NULL;
3247 }
3248
3249 /**
3250 *
3251 */
sr_kemi_param_map_get_params(int * ptypes)3252 str *sr_kemi_param_map_get_params(int *ptypes)
3253 {
3254 int i;
3255 int l;
3256 #define KEMI_PARAM_MAP_SIZE 72
3257 static char pbuf[KEMI_PARAM_MAP_SIZE];
3258 static str sret = STR_NULL;
3259 str *pn;
3260
3261 pbuf[0] = '\0';
3262 l = 0;
3263 for(i = 0; i < SR_KEMI_PARAMS_MAX; i++) {
3264 if(ptypes[i] == SR_KEMIP_NONE)
3265 break;
3266 if(i > 0) {
3267 l += 2;
3268 if(l >= KEMI_PARAM_MAP_SIZE - 8) {
3269 strcat(pbuf, ", ...");
3270 goto done;
3271 }
3272 strcat(pbuf, ", ");
3273 }
3274 pn = sr_kemi_param_map_get_name(ptypes[i]);
3275 if(pn == NULL)
3276 return NULL;
3277 l += pn->len;
3278 if(l >= KEMI_PARAM_MAP_SIZE - 8) {
3279 strcat(pbuf, ", ...");
3280 goto done;
3281 }
3282 strcat(pbuf, pn->s);
3283 }
3284 if(pbuf[0]=='\0') {
3285 pn = sr_kemi_param_map_get_name(SR_KEMIP_NONE);
3286 if(pn == NULL)
3287 return NULL;
3288 if(pn->len<KEMI_PARAM_MAP_SIZE-1) strncat(pbuf, pn->s, pn->len);
3289 }
3290 done:
3291 sret.s = pbuf;
3292 sret.len = strlen(sret.s);
3293 return &sret;
3294 }
3295
3296 /**
3297 *
3298 */
sr_kemi_route(sr_kemi_eng_t * keng,sip_msg_t * msg,int rtype,str * ename,str * edata)3299 int sr_kemi_route(sr_kemi_eng_t *keng, sip_msg_t *msg, int rtype,
3300 str *ename, str *edata)
3301 {
3302 flag_t sfbk;
3303 int ret;
3304
3305 sfbk = getsflags();
3306 setsflagsval(0);
3307 reset_static_buffer();
3308 ret = keng->froute(msg, rtype, ename, edata);
3309 setsflagsval(sfbk);
3310 return ret;
3311 }
3312
3313 /**
3314 *
3315 */
sr_kemi_ctx_route(sr_kemi_eng_t * keng,run_act_ctx_t * ctx,sip_msg_t * msg,int rtype,str * ename,str * edata)3316 int sr_kemi_ctx_route(sr_kemi_eng_t *keng, run_act_ctx_t *ctx, sip_msg_t *msg,
3317 int rtype, str *ename, str *edata)
3318 {
3319 run_act_ctx_t *bctx;
3320 int ret;
3321
3322 bctx = sr_kemi_act_ctx_get();
3323 sr_kemi_act_ctx_set(ctx);
3324 ret = sr_kemi_route(keng, msg, rtype, ename, edata);
3325 sr_kemi_act_ctx_set(bctx);
3326 return ret;
3327 }
3328