00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <stdlib.h>
00052 #include <sys/types.h>
00053 #include <regex.h>
00054 #include <netdb.h>
00055 #include <string.h>
00056 #include <sys/socket.h>
00057 #include <netinet/in.h>
00058 #include <arpa/inet.h>
00059 #include <netdb.h>
00060
00061 #include "route.h"
00062 #include "forward.h"
00063 #include "dprint.h"
00064 #include "proxy.h"
00065 #include "action.h"
00066 #include "sr_module.h"
00067 #include "ip_addr.h"
00068 #include "resolve.h"
00069 #include "socket_info.h"
00070 #include "blacklists.h"
00071 #include "parser/parse_uri.h"
00072 #include "parser/parse_from.h"
00073 #include "parser/parse_to.h"
00074 #include "mem/mem.h"
00075
00076
00077
00078 struct action* rlist[RT_NO];
00079
00080 struct action* onreply_rlist[ONREPLY_RT_NO];
00081 struct action* failure_rlist[FAILURE_RT_NO];
00082 struct action* branch_rlist[BRANCH_RT_NO];
00083 #ifdef USE_LOCAL_ROUTE
00084 struct action* local_rlist;
00085 #endif
00086 struct action* error_rlist;
00087
00088 int route_type = REQUEST_ROUTE;
00089
00090
00091 static int fix_actions(struct action* a);
00092
00093 extern int return_code;
00094
00095
00096
00097
00098 void init_route_lists(void)
00099 {
00100 memset(rlist, 0, sizeof(rlist));
00101 memset(onreply_rlist, 0, sizeof(onreply_rlist));
00102 memset(failure_rlist, 0, sizeof(failure_rlist));
00103 memset(branch_rlist, 0, sizeof(branch_rlist));
00104 error_rlist = 0;
00105 #ifdef USE_LOCAL_ROUTE
00106 local_rlist = 0;
00107 #endif
00108 }
00109
00110
00111
00112
00113
00114
00115 static int fix_expr(struct expr* exp)
00116 {
00117 regex_t* re;
00118 int ret;
00119
00120 ret=E_BUG;
00121 if (exp==0){
00122 LM_CRIT("null pointer\n");
00123 return E_BUG;
00124 }
00125 if (exp->type==EXP_T){
00126 switch(exp->op){
00127 case AND_OP:
00128 case OR_OP:
00129 if ((ret=fix_expr(exp->left.v.expr))!=0)
00130 return ret;
00131 ret=fix_expr(exp->right.v.expr);
00132 break;
00133 case NOT_OP:
00134 case EVAL_OP:
00135 ret=fix_expr(exp->left.v.expr);
00136 break;
00137 default:
00138 LM_CRIT("unknown op %d\n", exp->op);
00139 }
00140 }else if (exp->type==ELEM_T){
00141 if (exp->op==MATCH_OP || exp->op==NOTMATCH_OP){
00142 if (exp->right.type==STRING_ST){
00143 re=(regex_t*)pkg_malloc(sizeof(regex_t));
00144 if (re==0){
00145 LM_CRIT("out of pkg memory\n");
00146 return E_OUT_OF_MEM;
00147 }
00148 if (regcomp(re, (char*) exp->right.v.data,
00149 REG_EXTENDED|REG_NOSUB|REG_ICASE) ){
00150 LM_CRIT("bad re \"%s\"\n", (char*) exp->right.v.data);
00151 pkg_free(re);
00152 return E_BAD_RE;
00153 }
00154
00155 pkg_free(exp->right.v.data);
00156 exp->right.v.data=re;
00157 exp->right.type=RE_ST;
00158 }else if (exp->right.type!=RE_ST
00159 && exp->right.type!=SCRIPTVAR_ST){
00160 LM_CRIT("invalid type for match\n");
00161 return E_BUG;
00162 }
00163 }
00164 if (exp->left.type==ACTION_O){
00165 ret=fix_actions((struct action*)exp->right.v.data);
00166 if (ret!=0){
00167 LM_CRIT("fix_actions error\n");
00168 return ret;
00169 }
00170 }
00171 if (exp->left.type==EXPR_O){
00172 ret=fix_expr(exp->left.v.expr);
00173 if (ret!=0){
00174 LM_CRIT("fix left exp error\n");
00175 return ret;
00176 }
00177 }
00178 if (exp->right.type==EXPR_ST){
00179 ret=fix_expr(exp->right.v.expr);
00180 if (ret!=0){
00181 LM_CRIT("fix rigth exp error\n");
00182 return ret;
00183 }
00184 }
00185 ret=0;
00186 }
00187 return ret;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 static int fix_actions(struct action* a)
00197 {
00198 struct action *t;
00199 int ret, i, port, proto = PROTO_NONE;
00200 cmd_export_t* cmd;
00201 struct hostent* he;
00202 struct ip_addr ip;
00203 struct socket_info* si;
00204 str host;
00205 struct proxy_l *p;
00206 struct bl_head *blh;
00207
00208 if (a==0){
00209 LM_CRIT("null pointer\n");
00210 return E_BUG;
00211 }
00212 for(t=a; t!=0; t=t->next){
00213 switch(t->type){
00214 case FORWARD_T:
00215 if (t->elem[0].type==NOSUBTYPE)
00216 break;
00217 case SEND_T:
00218 if (t->elem[0].type!=STRING_ST) {
00219 LM_CRIT("invalid type %d (should be string)\n", t->type);
00220 return E_BUG;
00221 }
00222 ret = parse_phostport( t->elem[0].u.string,
00223 strlen(t->elem[0].u.string),
00224 &host.s, &host.len, &port, &proto);
00225 if (ret!=0) {
00226 LM_ERR("forward/send bad argument\n");
00227 return E_CFG;
00228 }
00229 p = add_proxy( &host,(unsigned short)port, proto);
00230 if (p==0) {
00231 LM_ERR("forward/send failed to add proxy");
00232 return E_CFG;
00233 }
00234 t->elem[0].type = PROXY_ST;
00235 t->elem[0].u.data = (void*)p;
00236 break;
00237 case IF_T:
00238 if (t->elem[0].type!=EXPR_ST){
00239 LM_CRIT("invalid subtype %d for if (should be expr)\n",
00240 t->elem[0].type);
00241 return E_BUG;
00242 }else if( (t->elem[1].type!=ACTIONS_ST)
00243 &&(t->elem[1].type!=NOSUBTYPE) ){
00244 LM_CRIT("invalid subtype %d for if() {...} (should be"
00245 "action)\n", t->elem[1].type);
00246 return E_BUG;
00247 }else if( (t->elem[2].type!=ACTIONS_ST)
00248 &&(t->elem[2].type!=NOSUBTYPE) ){
00249 LM_CRIT("invalid subtype %d for if() {} else{...}(should"
00250 "be action)\n", t->elem[2].type);
00251 return E_BUG;
00252 }
00253 if (t->elem[0].u.data){
00254 if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
00255 return ret;
00256 }
00257 if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
00258 if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
00259 return ret;
00260 }
00261 if ( (t->elem[2].type==ACTIONS_ST)&&(t->elem[2].u.data) ){
00262 if((ret=fix_actions((struct action*)t->elem[2].u.data))<0)
00263 return ret;
00264 }
00265 break;
00266 case WHILE_T:
00267 if (t->elem[0].type!=EXPR_ST){
00268 LM_CRIT("invalid subtype %d for while (should be expr)\n",
00269 t->elem[0].type);
00270 return E_BUG;
00271 }else if( (t->elem[1].type!=ACTIONS_ST)
00272 &&(t->elem[1].type!=NOSUBTYPE) ){
00273 LM_CRIT("invalid subtype %d for while() {...} (should be"
00274 "action)\n", t->elem[1].type);
00275 return E_BUG;
00276 }
00277 if (t->elem[0].u.data){
00278 if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
00279 return ret;
00280 }
00281 if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
00282 if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
00283 return ret;
00284 }
00285 break;
00286 case SWITCH_T:
00287 if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
00288 if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
00289 return ret;
00290 }
00291 break;
00292 case CASE_T:
00293 if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
00294 if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
00295 return ret;
00296 }
00297 break;
00298 case DEFAULT_T:
00299 if ( (t->elem[0].type==ACTIONS_ST)&&(t->elem[0].u.data) ){
00300 if ((ret=fix_actions((struct action*)t->elem[0].u.data))<0)
00301 return ret;
00302 }
00303 break;
00304 case MODULE_T:
00305 cmd = (cmd_export_t*)t->elem[0].u.data;
00306 LM_DBG("fixing %s, line %d\n", cmd->name, t->line);
00307 if (cmd->fixup){
00308 if (cmd->param_no==0){
00309 ret=cmd->fixup( 0, 0);
00310 if (ret<0) goto error;
00311 }
00312 else {
00313 for (i=1; i<=cmd->param_no; i++) {
00314 ret=cmd->fixup(&t->elem[i].u.data, i);
00315 t->elem[i].type=MODFIXUP_ST;
00316 if (ret<0) goto error;
00317 }
00318 }
00319 }
00320 break;
00321 case FORCE_SEND_SOCKET_T:
00322 if (t->elem[0].type!=SOCKID_ST){
00323 LM_CRIT("invalid subtype %d for force_send_socket\n",
00324 t->elem[0].type);
00325 return E_BUG;
00326 }
00327 he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0);
00328 if (he==0){
00329 LM_ERR(" could not resolve %s\n",
00330 ((struct socket_id*)t->elem[0].u.data)->name);
00331 ret = E_BAD_ADDRESS;
00332 goto error;
00333 }
00334 hostent2ip_addr(&ip, he, 0);
00335 si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port,
00336 ((struct socket_id*)t->elem[0].u.data)->proto);
00337 if (si==0){
00338 LM_ERR("bad force_send_socket"
00339 " argument: %s:%d (ser doesn't listen on it)\n",
00340 ((struct socket_id*)t->elem[0].u.data)->name,
00341 ((struct socket_id*)t->elem[0].u.data)->port);
00342 ret = E_BAD_ADDRESS;
00343 goto error;
00344 }
00345 t->elem[0].u.data=si;
00346 t->elem[0].type=SOCKETINFO_ST;
00347 break;
00348 case SET_DEBUG_T:
00349 if (t->elem[0].type==NOSUBTYPE)
00350 break;
00351 if (t->elem[0].type!=NUMBER_ST) {
00352 LM_CRIT("fix_actions: BUG in setdebug() type %d\n",
00353 t->elem[0].type );
00354 ret=E_BUG;
00355 goto error;
00356 }
00357
00358 if (t->elem[0].u.number>L_DBG)
00359 t->elem[0].u.number = L_DBG;
00360 else if (t->elem[0].u.number<L_ALERT)
00361 t->elem[0].u.number = L_ALERT;
00362 break;
00363 case SETFLAG_T:
00364 case RESETFLAG_T:
00365 case ISFLAGSET_T:
00366 if (t->elem[0].type!=NUMBER_ST) {
00367 LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type );
00368 ret=E_BUG;
00369 goto error;
00370 }
00371 if (!flag_in_range( t->elem[0].u.number )) {
00372 ret=E_CFG;
00373 goto error;
00374 }
00375 break;
00376 case SETSFLAG_T:
00377 case RESETSFLAG_T:
00378 case ISSFLAGSET_T:
00379 if (t->elem[0].type!=NUMBER_ST) {
00380 LM_CRIT("bad xxxsflag() type %d\n", t->elem[0].type );
00381 ret=E_BUG;
00382 goto error;
00383 }
00384 t->elem[0].u.number = fixup_flag( t->elem[0].u.number );
00385 if (t->elem[0].u.data==0) {
00386 ret=E_CFG;
00387 goto error;
00388 }
00389 break;
00390 case SETBFLAG_T:
00391 case RESETBFLAG_T:
00392 case ISBFLAGSET_T:
00393 if (t->elem[0].type!=NUMBER_ST || t->elem[1].type!=NUMBER_ST) {
00394 LM_CRIT("bad xxxbflag() type "
00395 "%d,%d\n", t->elem[0].type, t->elem[0].type);
00396 ret=E_BUG;
00397 goto error;
00398 }
00399 t->elem[1].u.number = fixup_flag( t->elem[1].u.number );
00400 if (t->elem[1].u.data==0) {
00401 ret=E_CFG;
00402 goto error;
00403 }
00404 break;
00405 case EQ_T:
00406 case COLONEQ_T:
00407 case PLUSEQ_T:
00408 case MINUSEQ_T:
00409 case DIVEQ_T:
00410 case MULTEQ_T:
00411 case MODULOEQ_T:
00412 case BANDEQ_T:
00413 case BOREQ_T:
00414 case BXOREQ_T:
00415 if (t->elem[1].u.data){
00416 if ((ret=fix_expr((struct expr*)t->elem[1].u.data))<0)
00417 return ret;
00418 }
00419 break;
00420 case USE_BLACKLIST_T:
00421 case UNUSE_BLACKLIST_T:
00422 if (t->elem[0].type!=STRING_ST) {
00423 LM_CRIT("bad [UN]USE_BLACKLIST type %d\n",t->elem[0].type);
00424 ret=E_BUG;
00425 goto error;
00426 }
00427 host.s = t->elem[0].u.string;
00428 host.len = strlen(host.s);
00429 if ( strcasecmp(host.s,"all")==0 ) {
00430 blh = NULL;
00431 } else {
00432 blh = get_bl_head_by_name(&host);
00433 if (blh==NULL) {
00434 LM_ERR("[UN]USE_BLACKLIST - list "
00435 "%s not configured\n", t->elem[0].u.string);
00436 ret=E_CFG;
00437 goto error;
00438 }
00439 }
00440 t->elem[0].type = BLACKLIST_ST;
00441 t->elem[0].u.data = blh;
00442 break;
00443 case ROUTE_T:
00444 if(rlist[t->elem[0].u.number]==0)
00445 {
00446 LM_WARN("call of empty route block no %ld (line %d)\n",
00447 t->elem[0].u.number, t->line);
00448 }
00449 break;
00450 }
00451 }
00452 return 0;
00453 error:
00454 LM_ERR("fixing failed (code=%d) at cfg line %d\n", ret, t->line);
00455 return ret;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 inline static int comp_no( int port, void *param, int op, int subtype )
00468 {
00469
00470 if (subtype!=NUMBER_ST) {
00471 LM_CRIT("number expected: %d\n", subtype );
00472 return E_BUG;
00473 }
00474 switch (op){
00475 case EQUAL_OP:
00476 return port==(long)param;
00477 case DIFF_OP:
00478 return port!=(long)param;
00479 case GT_OP:
00480 return port>(long)param;
00481 case LT_OP:
00482 return port<(long)param;
00483 case GTE_OP:
00484 return port>=(long)param;
00485 case LTE_OP:
00486 return port<=(long)param;
00487 default:
00488 LM_CRIT("unknown operator: %d\n", op );
00489 return E_BUG;
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 inline static int comp_strval(struct sip_msg *msg, int op, str* ival,
00503 operand_t *opd)
00504 {
00505 int ret;
00506 regex_t* re;
00507 char backup, backup2;
00508 str res;
00509 pv_value_t value;
00510
00511 if(ival==NULL || ival->s==NULL || ival->len == 0)
00512 goto error;
00513
00514 res.s = 0; res.len = 0;
00515 if(opd->type == SCRIPTVAR_ST)
00516 {
00517 if(pv_get_spec_value(msg, opd->v.spec, &value)!=0)
00518 {
00519 LM_CRIT("cannot get var value\n");
00520 goto error;
00521 }
00522 if(value.flags&PV_VAL_STR)
00523 {
00524 res = value.rs;
00525 } else {
00526 res.s = sint2str(value.ri, &res.len);
00527 }
00528 } else if(opd->type == NUMBER_ST) {
00529 res.s = sint2str(opd->v.n, &res.len);
00530 }else if(opd->type == STRING_ST) {
00531 res = opd->v.s;
00532 } else {
00533 if((op!=MATCH_OP && op!=NOTMATCH_OP) || opd->type != RE_ST)
00534 {
00535 LM_CRIT("invalid operation %d/%d\n", op, opd->type);
00536 goto error;
00537 }
00538 }
00539
00540
00541 ret=-1;
00542 switch(op){
00543 case EQUAL_OP:
00544 if(ival->len != res.len) return 0;
00545 ret=(strncasecmp(ival->s, res.s, ival->len)==0);
00546 break;
00547 case DIFF_OP:
00548 if(ival->len != res.len) return 1;
00549 ret=(strncasecmp(ival->s, res.s, ival->len)!=0);
00550 break;
00551 case MATCH_OP:
00552 case NOTMATCH_OP:
00553 backup=ival->s[ival->len];ival->s[ival->len]='\0';
00554
00555 if(opd->type == SCRIPTVAR_ST) {
00556 re=(regex_t*)pkg_malloc(sizeof(regex_t));
00557 if (re==0){
00558 LM_CRIT("pkg memory allocation failure\n");
00559 ival->s[ival->len]=backup;
00560 goto error;
00561 }
00562 backup2 = res.s[res.len];res.s[res.len] = '\0';
00563 if (regcomp(re, res.s, REG_EXTENDED|REG_NOSUB|REG_ICASE)) {
00564 pkg_free(re);
00565 res.s[res.len] = backup2;
00566 ival->s[ival->len]=backup;
00567 goto error;
00568 }
00569 ret=(regexec(re, ival->s, 0, 0, 0)==0);
00570 regfree(re);
00571 pkg_free(re);
00572 res.s[res.len] = backup2;
00573 } else {
00574 ret=(regexec((regex_t*)opd->v.data, ival->s, 0, 0, 0)==0);
00575 }
00576
00577 ival->s[ival->len]=backup;
00578 if(op==NOTMATCH_OP)
00579 ret = !ret;
00580 break;
00581 default:
00582 LM_CRIT("unknown op %d\n", op);
00583 goto error;
00584 }
00585 return ret;
00586
00587 error:
00588 return -1;
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 inline static int comp_str(char* str, void* param, int op, int subtype)
00601 {
00602 int ret = -1;
00603
00604 switch(op){
00605 case EQUAL_OP:
00606 if (subtype!=STRING_ST){
00607 LM_CRIT("bad type %d, string expected\n", subtype);
00608 goto error;
00609 }
00610 ret=(strcasecmp(str, (char*)param)==0);
00611 break;
00612 case DIFF_OP:
00613 if (subtype!=STRING_ST){
00614 LM_CRIT("bad type %d, string expected\n", subtype);
00615 goto error;
00616 }
00617 ret=(strcasecmp(str, (char*)param)!=0);
00618 break;
00619 case MATCH_OP:
00620 if (subtype!=RE_ST){
00621 LM_CRIT("bad type %d, RE expected\n", subtype);
00622 goto error;
00623 }
00624 ret=(regexec((regex_t*)param, str, 0, 0, 0)==0);
00625 break;
00626 case NOTMATCH_OP:
00627 if (subtype!=RE_ST){
00628 LM_CRIT("bad type %d, RE expected!\n", subtype);
00629 goto error;
00630 }
00631 ret=(regexec((regex_t*)param, str, 0, 0, 0)!=0);
00632 break;
00633 default:
00634 LM_CRIT("unknown op %d\n", op);
00635 goto error;
00636 }
00637 return ret;
00638
00639 error:
00640 return -1;
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 inline static int check_self_op(int op, str* s, unsigned short p)
00652 {
00653 int ret = check_self(s, p, 0);
00654
00655 switch(op){
00656 case EQUAL_OP:
00657 break;
00658 case DIFF_OP:
00659 if (ret>=0) ret=!ret;
00660 break;
00661 default:
00662 LM_CRIT("invalid operator %d\n", op);
00663 ret=-1;
00664 }
00665 return ret;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 inline static int comp_ip(struct sip_msg *msg, int op, struct ip_addr* ip,
00678 operand_t *opd)
00679 {
00680 struct hostent* he;
00681 char ** h;
00682 int ret = -1;
00683 str tmp;
00684
00685 switch(opd->type){
00686 case NET_ST:
00687 switch(op){
00688 case EQUAL_OP:
00689 ret=(matchnet(ip, (struct net*)opd->v.data)==1);
00690 break;
00691 case DIFF_OP:
00692 ret=(matchnet(ip, (struct net*)opd->v.data)!=1);
00693 break;
00694 default:
00695 goto error_op;
00696 }
00697 break;
00698 case STRING_ST:
00699 case RE_ST:
00700 switch(op){
00701 case EQUAL_OP:
00702 case MATCH_OP:
00703
00704 ret=comp_str(ip_addr2a(ip), opd->v.data, op, opd->type);
00705 if (ret==1) break;
00706
00707 if (opd->type==STRING_ST){
00708 he=resolvehost((char*)opd->v.data,0);
00709 if (he==0){
00710 LM_DBG("could not resolve %s\n",(char*)opd->v.data);
00711 }else if (he->h_addrtype==(int)ip->af){
00712 for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
00713 ret=(memcmp(ip->u.addr, *h, ip->len)==0);
00714 }
00715 if (ret==1) break;
00716 }
00717 }
00718
00719
00720
00721 if(received_dns & DO_REV_DNS)
00722 {
00723 he=rev_resolvehost(ip);
00724 if (he==0){
00725 print_ip("comp_ip: could not rev_resolve ip"
00726 " address: ", ip, "\n");
00727 ret=0;
00728 }else{
00729
00730 ret=comp_str(he->h_name, opd->v.data, op,
00731 opd->type);
00732
00733 for(h=he->h_aliases; (ret!=1) && (*h); h++){
00734 ret=comp_str(*h, opd->v.data, op, opd->type);
00735 }
00736 }
00737 } else {
00738 return 0;
00739 }
00740 break;
00741 case DIFF_OP:
00742 ret=comp_ip(msg, op, ip, opd);
00743 if (ret>=0) ret=!ret;
00744 break;
00745 default:
00746 goto error_op;
00747 }
00748 break;
00749 case MYSELF_ST:
00750 tmp.s=ip_addr2a(ip);
00751 tmp.len=strlen(tmp.s);
00752 ret=check_self_op(op, &tmp, 0);
00753 break;
00754 default:
00755 LM_CRIT("invalid type for src_ip or dst_ip (%d)\n", opd->type);
00756 ret=-1;
00757 }
00758 return ret;
00759 error_op:
00760 LM_CRIT("invalid operator %d\n", op);
00761 return -1;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 inline static int comp_s2r(int op, str *s1, regex_t *re)
00773 {
00774 char backup;
00775 int ret = -1;
00776
00777
00778 if(s1->len == 0 || s1->s==NULL || re==NULL)
00779 return 0;
00780 switch(op) {
00781 case MATCH_OP:
00782 backup = s1->s[s1->len]; s1->s[s1->len] = '\0';
00783 ret=(regexec(re, s1->s, 0, 0, 0)==0);
00784 s1->s[s1->len] = backup;
00785 break;
00786 case NOTMATCH_OP:
00787 backup = s1->s[s1->len]; s1->s[s1->len] = '\0';
00788 ret=(regexec(re, s1->s, 0, 0, 0)!=0);
00789 s1->s[s1->len] = backup;
00790 break;
00791 default:
00792 LM_CRIT("unknown op %d\n", op);
00793 }
00794 return ret;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 inline static int comp_s2s(int op, str *s1, str *s2)
00806 {
00807 char backup, backup2;
00808 int n, rt, ret = -1;
00809 regex_t* re;
00810
00811
00812 if(s1->s==NULL || s2->s==NULL)
00813 return 0;
00814 switch(op) {
00815 case EQUAL_OP:
00816 if(s1->len != s2->len) return 0;
00817 ret=(strncasecmp(s1->s, s2->s, s2->len)==0);
00818 break;
00819 case DIFF_OP:
00820 if(s1->len != s2->len) return 1;
00821 ret=(strncasecmp(s1->s, s2->s, s2->len)!=0);
00822 break;
00823 case GT_OP:
00824 n = (s1->len>=s2->len)?s1->len:s2->len;
00825 rt = strncasecmp(s1->s,s2->s, n);
00826 if (rt>0)
00827 ret = 1;
00828 else if(rt==0 && s1->len>s1->len)
00829 ret = 1;
00830 else ret = 0;
00831 break;
00832 case GTE_OP:
00833 n = (s1->len>=s2->len)?s1->len:s2->len;
00834 rt = strncasecmp(s1->s,s2->s, n);
00835 if (rt>0)
00836 ret = 1;
00837 else if(rt==0 && s1->len>=s1->len)
00838 ret = 1;
00839 else ret = 0;
00840 break;
00841 case LT_OP:
00842 n = (s1->len>=s2->len)?s1->len:s2->len;
00843 rt = strncasecmp(s1->s,s2->s, n);
00844 if (rt<0)
00845 ret = 1;
00846 else if(rt==0 && s1->len<s1->len)
00847 ret = 1;
00848 else ret = 0;
00849 break;
00850 case LTE_OP:
00851 n = (s1->len>=s2->len)?s1->len:s2->len;
00852 rt = strncasecmp(s1->s,s2->s, n);
00853 if (rt<0)
00854 ret = 1;
00855 else if(rt==0 && s1->len<=s1->len)
00856 ret = 1;
00857 else ret = 0;
00858 break;
00859 case MATCHD_OP:
00860 case NOTMATCHD_OP:
00861 if(s1->len == 0 || s2->len == 0) return 0;
00862 re=(regex_t*)pkg_malloc(sizeof(regex_t));
00863 if (re==0) {
00864 LM_CRIT("pkg memory allocation failure\n");
00865 return -1;
00866 }
00867
00868 backup = s1->s[s1->len]; s1->s[s1->len] = '\0';
00869 backup2 = s2->s[s2->len]; s2->s[s2->len] = '\0';
00870
00871 if (regcomp(re, s2->s, REG_EXTENDED|REG_NOSUB|REG_ICASE)) {
00872 pkg_free(re);
00873 s2->s[s2->len] = backup2;
00874 s1->s[s1->len] = backup;
00875 return -1;
00876 }
00877 if(op==MATCHD_OP)
00878 ret=(regexec(re, s1->s, 0, 0, 0)==0);
00879 else
00880 ret=(regexec(re, s1->s, 0, 0, 0)!=0);
00881 regfree(re);
00882 pkg_free(re);
00883 s2->s[s2->len] = backup2;
00884 s1->s[s1->len] = backup;
00885 break;
00886 default:
00887 LM_CRIT("unknown op %d\n", op);
00888 }
00889 return ret;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900 inline static int comp_n2n(int op, int n1, int n2)
00901 {
00902 switch(op) {
00903 case EQUAL_OP:
00904 case MATCH_OP:
00905 case MATCHD_OP:
00906 if(n1 == n2)
00907 return 1;
00908 return 0;
00909 case NOTMATCH_OP:
00910 case NOTMATCHD_OP:
00911 case DIFF_OP:
00912 if(n1 != n2)
00913 return 1;
00914 return 0;
00915 case GT_OP:
00916 if(n1 > n2)
00917 return 1;
00918 return 0;
00919 case GTE_OP:
00920 if(n1 >= n2)
00921 return 1;
00922 return 0;
00923 case LT_OP:
00924 if(n1 < n2)
00925 return 1;
00926 return 0;
00927 case LTE_OP:
00928 if(n1 <= n2)
00929 return 1;
00930 return 0;
00931 default:
00932 LM_CRIT("unknown op %d\n", op);
00933 }
00934 return -1;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 inline static int comp_scriptvar(struct sip_msg *msg, int op, operand_t *left,
00947 operand_t *right)
00948 {
00949 str lstr, rstr;
00950 int ln, rn, type;
00951 pv_value_t lvalue, rvalue;
00952
00953 lstr.s = 0; lstr.len = 0;
00954 rstr.s = 0; rstr.len = 0;
00955 ln = 0; rn =0;
00956 if(pv_get_spec_value(msg, left->v.spec, &lvalue)!=0)
00957 {
00958 LM_CRIT("cannot get left var value\n");
00959 goto error;
00960 }
00961 if(right->type==NULLV_ST)
00962 {
00963 if(op==EQUAL_OP)
00964 {
00965 if(lvalue.flags&PV_VAL_NULL)
00966 return 1;
00967 return 0;
00968 } else {
00969 if(lvalue.flags&PV_VAL_NULL)
00970 return 0;
00971 return 1;
00972 }
00973 }
00974
00975 lstr = lvalue.rs;
00976 ln = lvalue.ri;
00977 type = 0;
00978
00979 if(right->type == SCRIPTVAR_ST)
00980 {
00981 if(pv_get_spec_value(msg, right->v.spec, &rvalue)!=0)
00982 {
00983 LM_CRIT("cannot get right var value\n");
00984 goto error;
00985 }
00986 if(rvalue.flags&PV_VAL_NULL || lvalue.flags&PV_VAL_NULL ) {
00987 if (rvalue.flags&PV_VAL_NULL && lvalue.flags&PV_VAL_NULL )
00988 return (op==EQUAL_OP)?1:0;
00989 return (op==DIFF_OP)?1:0;
00990 }
00991
00992 if(op==MATCH_OP||op==NOTMATCH_OP)
00993 {
00994 if(!((rvalue.flags&PV_VAL_STR) && (lvalue.flags&PV_VAL_STR)))
00995 {
00996 LM_CRIT("invalid operation %d/%d\n", op, right->type);
00997 goto error;
00998 }
00999 if(op==MATCH_OP)
01000 return comp_s2s(MATCHD_OP, &lstr, &rvalue.rs);
01001 else
01002 return comp_s2s(NOTMATCHD_OP, &lstr, &rvalue.rs);
01003 }
01004
01005 if((rvalue.flags&PV_VAL_INT) && (lvalue.flags&PV_VAL_INT)) {
01006
01007 rn = rvalue.ri;
01008 type =2;
01009 } else if((rvalue.flags&PV_VAL_STR) && (lvalue.flags&PV_VAL_STR)) {
01010
01011 rstr = rvalue.rs;
01012 type =1;
01013 } else {
01014 LM_CRIT("invalid operation %d/%d!\n", op,
01015 right->type);
01016 goto error;
01017 }
01018 } else {
01019
01020 if(lvalue.flags&PV_VAL_NULL)
01021 return (op==DIFF_OP || op==NOTMATCH_OP || op==NOTMATCHD_OP)?1:0;
01022
01023 if(right->type == NUMBER_ST) {
01024 if(!(lvalue.flags&PV_VAL_INT))
01025 {
01026 LM_CRIT("invalid operation %d/%d/%d!!\n", op,
01027 right->type, lvalue.flags);
01028 goto error;
01029 }
01030
01031 type =2;
01032 rn = right->v.n;
01033 } else if(right->type == STRING_ST) {
01034 if(!(lvalue.flags&PV_VAL_STR))
01035 {
01036 LM_CRIT("invalid operation %d/%d!!!\n", op, right->type);
01037 goto error;
01038 }
01039
01040 type =1;
01041 rstr = right->v.s;
01042 } else {
01043
01044 type = 0;
01045 }
01046 if(op==MATCH_OP || op==NOTMATCH_OP)
01047 {
01048 if(!(lvalue.flags&PV_VAL_STR) || right->type != RE_ST)
01049 {
01050 LM_CRIT("invalid operation %d/%d\n", op, right->type);
01051 goto error;
01052 }
01053 return comp_s2r(op, &lstr, (regex_t*)right->v.expr);
01054 }
01055 }
01056
01057 if(type==1) {
01058 LM_DBG("str %d : %.*s\n", op, lstr.len, ZSW(lstr.s));
01059 return comp_s2s(op, &lstr, &rstr);
01060 } else if(type==2) {
01061 LM_DBG("int %d : %d / %d\n", op, ln, rn);
01062 return comp_n2n(op, ln, rn);
01063 } else {
01064 LM_CRIT("invalid operation %d/%d\n", op, right->type);
01065 }
01066
01067 error:
01068 return -1;
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 static int eval_elem(struct expr* e, struct sip_msg* msg, pv_value_t *val)
01080 {
01081
01082 struct sip_uri uri;
01083 int ret, retl, retr, ival;
01084 pv_value_t lval, rval;
01085 char *p;
01086
01087 ret=E_BUG;
01088 if (e->type!=ELEM_T){
01089 LM_CRIT("invalid type\n");
01090 goto error;
01091 }
01092
01093 if(val) memset(val, 0, sizeof(pv_value_t));
01094
01095 switch(e->left.type){
01096 case METHOD_O:
01097 ret=comp_strval(msg, e->op, &msg->first_line.u.request.method,
01098 &e->right);
01099 break;
01100 case URI_O:
01101 if(msg->new_uri.s){
01102 if (e->right.type==MYSELF_ST){
01103 if (parse_sip_msg_uri(msg)<0) ret=-1;
01104 else ret=check_self_op(e->op, &msg->parsed_uri.host,
01105 msg->parsed_uri.port_no?
01106 msg->parsed_uri.port_no:SIP_PORT);
01107 }else{
01108 ret=comp_strval(msg, e->op, &msg->new_uri, &e->right);
01109 }
01110 }else{
01111 if (e->right.type==MYSELF_ST){
01112 if (parse_sip_msg_uri(msg)<0) ret=-1;
01113 else ret=check_self_op(e->op, &msg->parsed_uri.host,
01114 msg->parsed_uri.port_no?
01115 msg->parsed_uri.port_no:SIP_PORT);
01116 }else{
01117 ret=comp_strval(msg, e->op,
01118 &msg->first_line.u.request.uri,
01119 &e->right);
01120 }
01121 }
01122 break;
01123 case FROM_URI_O:
01124 if (parse_from_header(msg)<0){
01125 LM_ERR("bad or missing From: header\n");
01126 goto error;
01127 }
01128 if (e->right.type==MYSELF_ST){
01129 if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len,
01130 &uri) < 0){
01131 LM_ERR("bad uri in From:\n");
01132 goto error;
01133 }
01134 ret=check_self_op(e->op, &uri.host,
01135 uri.port_no?uri.port_no:SIP_PORT);
01136 }else{
01137 ret=comp_strval(msg, e->op, &get_from(msg)->uri,
01138 &e->right);
01139 }
01140 break;
01141 case TO_URI_O:
01142 if ((msg->to==0) && ((parse_headers(msg, HDR_TO_F, 0)==-1) ||
01143 (msg->to==0))){
01144 LM_ERR("bad or missing To: header\n");
01145 goto error;
01146 }
01147
01148 if (e->right.type==MYSELF_ST){
01149 if (parse_uri(get_to(msg)->uri.s, get_to(msg)->uri.len,
01150 &uri) < 0){
01151 LM_ERR("bad uri in To:\n");
01152 goto error;
01153 }
01154 ret=check_self_op(e->op, &uri.host,
01155 uri.port_no?uri.port_no:SIP_PORT);
01156 }else{
01157 ret=comp_strval(msg, e->op, &get_to(msg)->uri,
01158 &e->right);
01159 }
01160 break;
01161 case SRCIP_O:
01162 ret=comp_ip(msg, e->op, &msg->rcv.src_ip, &e->right);
01163 break;
01164 case DSTIP_O:
01165 ret=comp_ip(msg, e->op, &msg->rcv.dst_ip, &e->right);
01166 break;
01167 case NUMBER_O:
01168 ret=!(!e->right.v.n);
01169 break;
01170 case ACTION_O:
01171 ret=run_action_list( (struct action*)e->right.v.data, msg);
01172 if(val)
01173 {
01174 val->flags = PV_TYPE_INT|PV_VAL_INT;
01175 val->ri = ret;
01176 }
01177 if (ret<=0) ret=(ret==0)?EXPR_DROP:0;
01178 else ret=1;
01179 return ret;
01180 case EXPR_O:
01181 retl = retr = 0;
01182 memset(&lval, 0, sizeof(pv_value_t));
01183 memset(&rval, 0, sizeof(pv_value_t));
01184 if(e->left.v.data)
01185 retl=eval_expr((struct expr*)e->left.v.data,msg,&lval);
01186 if(lval.flags == PV_VAL_NONE)
01187 {
01188 pv_value_destroy(&lval);
01189 pv_value_destroy(&rval);
01190 return 0;
01191 }
01192 if(e->op == BNOT_OP)
01193 {
01194 if(lval.flags&PV_VAL_INT)
01195 {
01196 if(val!=NULL)
01197 {
01198 val->flags = PV_TYPE_INT|PV_VAL_INT;
01199 val->ri = ~lval.ri;
01200 }
01201 pv_value_destroy(&lval);
01202 pv_value_destroy(&rval);
01203 return (val->ri)?1:0;
01204 }
01205 LM_ERR("binary NOT on non-numeric value\n");
01206 pv_value_destroy(&lval);
01207 pv_value_destroy(&rval);
01208 return 0;
01209 }
01210 if(e->right.v.data)
01211 retr=eval_expr((struct expr*)e->right.v.data,msg,&rval);
01212
01213 if(lval.flags&PV_TYPE_INT)
01214 {
01215 if(!(rval.flags&PV_VAL_INT))
01216 {
01217 LM_ERR("invalid numeric operands\n");
01218 pv_value_destroy(&lval);
01219 pv_value_destroy(&rval);
01220 return 0;
01221 }
01222 if(val!=NULL)
01223 val->flags = PV_TYPE_INT|PV_VAL_INT;
01224
01225 ival = 0;
01226 switch(e->op) {
01227 case PLUS_OP:
01228 ival = lval.ri + rval.ri;
01229 break;
01230 case MINUS_OP:
01231 ival = lval.ri - rval.ri;
01232 break;
01233 case DIV_OP:
01234 if(rval.ri==0)
01235 {
01236 LM_ERR("divide by 0\n");
01237 pv_value_destroy(&lval);
01238 pv_value_destroy(&rval);
01239 return 0;
01240 } else
01241 ival = lval.ri / rval.ri;
01242 break;
01243 case MULT_OP:
01244 ival = lval.ri * rval.ri;
01245 break;
01246 case MODULO_OP:
01247 if(rval.ri==0)
01248 {
01249 LM_ERR("divide by 0\n");
01250 pv_value_destroy(&lval);
01251 pv_value_destroy(&rval);
01252 return 0;
01253 } else
01254 ival = lval.ri % rval.ri;
01255 break;
01256 case BAND_OP:
01257 ival = lval.ri & rval.ri;
01258 break;
01259 case BOR_OP:
01260 ival = lval.ri | rval.ri;
01261 break;
01262 case BXOR_OP:
01263 ival = lval.ri ^ rval.ri;
01264 break;
01265 case BLSHIFT_OP:
01266 ival = lval.ri << rval.ri;
01267 break;
01268 case BRSHIFT_OP:
01269 ival = lval.ri >> rval.ri;
01270 break;
01271 default:
01272 LM_ERR("invalid int op %d\n", e->op);
01273 val->ri = 0;
01274 pv_value_destroy(&lval);
01275 pv_value_destroy(&rval);
01276 return 0;
01277 }
01278 pv_value_destroy(&lval);
01279 pv_value_destroy(&rval);
01280 if(val!=NULL) val->ri = ival;
01281 return (ival)?1:0;
01282 } else {
01283 if(!(rval.flags&PV_VAL_STR))
01284 {
01285 LM_ERR("invalid string operands\n");
01286 pv_value_destroy(&lval);
01287 pv_value_destroy(&rval);
01288 return 0;
01289 }
01290 if(e->op != PLUS_OP)
01291 {
01292 LM_ERR("invalid string operator %d\n", e->op);
01293 pv_value_destroy(&lval);
01294 pv_value_destroy(&rval);
01295 return 0;
01296 }
01297 if(val==NULL)
01298 {
01299 ret = (lval.rs.len>0 || rval.rs.len>0);
01300 pv_value_destroy(&lval);
01301 pv_value_destroy(&rval);
01302 return ret;
01303 }
01304 val->rs.s=(char*)pkg_malloc((lval.rs.len+rval.rs.len+1)
01305 *sizeof(char));
01306 if(val->rs.s==0)
01307 {
01308 LM_ERR("no more memory\n");
01309 pv_value_destroy(&lval);
01310 pv_value_destroy(&rval);
01311 return 0;
01312 }
01313 val->flags = PV_VAL_PKG|PV_VAL_STR;
01314 memcpy(val->rs.s, lval.rs.s, lval.rs.len);
01315 memcpy(val->rs.s+lval.rs.len, rval.rs.s, rval.rs.len);
01316 val->rs.len = lval.rs.len + rval.rs.len;
01317 val->rs.s[val->rs.len] = '\0';
01318 pv_value_destroy(&lval);
01319 pv_value_destroy(&rval);
01320 return 1;
01321 }
01322 break;
01323 case SRCPORT_O:
01324 ret=comp_no(msg->rcv.src_port,
01325 e->right.v.data,
01326 e->op,
01327 e->right.type );
01328 break;
01329 case DSTPORT_O:
01330 ret=comp_no(msg->rcv.dst_port, e->right.v.data, e->op,
01331 e->right.type);
01332 break;
01333 case PROTO_O:
01334 ret=comp_no(msg->rcv.proto, e->right.v.data, e->op,
01335 e->right.type);
01336 break;
01337 case AF_O:
01338 ret=comp_no(msg->rcv.src_ip.af, e->right.v.data, e->op,
01339 e->right.type);
01340 break;
01341 case RETCODE_O:
01342 ret=comp_no(return_code, e->right.v.data, e->op,
01343 e->right.type);
01344 break;
01345 case MSGLEN_O:
01346 ret=comp_no(msg->len, e->right.v.data, e->op,
01347 e->right.type);
01348 break;
01349 case STRINGV_O:
01350 if(val) {
01351 val->flags = PV_VAL_STR;
01352 val->rs = e->left.v.s;
01353 }
01354
01355 return (e->left.v.s.len>0)?1:0;
01356 case NUMBERV_O:
01357 if(val) {
01358 val->flags = PV_TYPE_INT|PV_VAL_INT;
01359 val->ri = e->left.v.n;
01360 }
01361 ret=!(!e->left.v.n);
01362 return ret;
01363 case SCRIPTVAR_O:
01364 if(e->op==NO_OP)
01365 {
01366 memset(&rval, 0, sizeof(pv_value_t));
01367 if(pv_get_spec_value(msg, e->right.v.spec, &rval)==0)
01368 {
01369 if(rval.flags==PV_VAL_NONE || (rval.flags&PV_VAL_NULL)
01370 || (rval.flags&PV_VAL_EMPTY)
01371 || ((rval.flags&PV_TYPE_INT)&&rval.ri==0))
01372 {
01373 pv_value_destroy(&rval);
01374 return 0;
01375 }
01376 if(rval.flags&PV_TYPE_INT)
01377 {
01378 pv_value_destroy(&rval);
01379 return 1;
01380 }
01381 if(rval.rs.len!=0)
01382 {
01383 pv_value_destroy(&rval);
01384 return 1;
01385 }
01386 pv_value_destroy(&rval);
01387 }
01388 return 0;
01389 }
01390 if(e->op==VALUE_OP)
01391 {
01392 if(pv_get_spec_value(msg, e->left.v.spec, &lval)==0)
01393 {
01394 if(val!=NULL)
01395 memcpy(val, &lval, sizeof(pv_value_t));
01396 if(lval.flags&PV_VAL_STR)
01397 {
01398 if(!((lval.flags&PV_VAL_PKG)
01399 || (lval.flags&PV_VAL_SHM)))
01400 {
01401 if(val!=NULL)
01402 {
01403
01404 p = (char*)pkg_malloc((val->rs.len+1)
01405 *sizeof(char));
01406 if(p==0)
01407 {
01408 LM_ERR("no more pkg memory\n");
01409 memset(val, 0, sizeof(pv_value_t));
01410 return 0;
01411 }
01412 memcpy(p, val->rs.s, val->rs.len);
01413 p[val->rs.len] = 0;
01414 val->rs.s = p;
01415 val->flags|= PV_VAL_PKG;
01416 }
01417 }
01418 return 1;
01419 }
01420 if(lval.flags==PV_VAL_NONE
01421 || (lval.flags & PV_VAL_NULL)
01422 || (lval.flags & PV_VAL_EMPTY))
01423 return 0;
01424 if(lval.flags&PV_TYPE_INT)
01425 return (lval.ri!=0);
01426 else
01427 return (lval.rs.len>0);
01428 }
01429 return 0;
01430 }
01431
01432 ret=comp_scriptvar(msg, e->op, &e->left, &e->right);
01433 break;
01434 default:
01435 LM_CRIT("invalid operand %d\n", e->left.type);
01436 }
01437 if(val)
01438 {
01439 val->flags = PV_TYPE_INT|PV_VAL_INT;
01440 val->ri = ret;
01441 }
01442 return ret;
01443 error:
01444 if(val)
01445 {
01446 val->flags = PV_TYPE_INT|PV_VAL_INT;
01447 val->ri = -1;
01448 }
01449 return -1;
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459 int eval_expr(struct expr* e, struct sip_msg* msg, pv_value_t *val)
01460 {
01461 static int rec_lev=0;
01462 int ret;
01463
01464 rec_lev++;
01465 if (rec_lev>MAX_REC_LEV){
01466 LM_CRIT("too many expressions (%d)\n", rec_lev);
01467 ret=-1;
01468 goto skip;
01469 }
01470
01471 if (e->type==ELEM_T){
01472 ret=eval_elem(e, msg, val);
01473 }else if (e->type==EXP_T){
01474 switch(e->op){
01475 case AND_OP:
01476 ret=eval_expr(e->left.v.expr, msg, val);
01477
01478 if (ret!=1) break;
01479 ret=eval_expr(e->right.v.expr, msg, val);
01480 break;
01481 case OR_OP:
01482 ret=eval_expr(e->left.v.expr, msg, val);
01483
01484 if (ret!=0) break;
01485 ret=eval_expr(e->right.v.expr, msg, val);
01486 break;
01487 case NOT_OP:
01488 ret=eval_expr(e->left.v.expr, msg, val);
01489 if (ret<0) break;
01490 ret= ! ret;
01491 break;
01492 case EVAL_OP:
01493 ret=eval_expr(e->left.v.expr, msg, val);
01494 break;
01495 default:
01496 LM_CRIT("unknown op %d\n", e->op);
01497 ret=-1;
01498 }
01499 }else{
01500 LM_CRIT("unknown type %d\n", e->type);
01501 ret=-1;
01502 }
01503
01504 skip:
01505 rec_lev--;
01506 return ret;
01507 }
01508
01509
01510
01511
01512
01513
01514
01515 void push(struct action* a, struct action** head)
01516 {
01517 struct action *t;
01518 if (*head==0){
01519 *head=a;
01520 return;
01521 }
01522 for (t=*head; t->next;t=t->next);
01523 t->next=a;
01524 }
01525
01526
01527
01528
01529
01530
01531
01532
01533 int add_actions(struct action* a, struct action** head)
01534 {
01535 int ret;
01536
01537 LM_DBG("fixing actions...\n");
01538 if ((ret=fix_actions(a))!=0) goto error;
01539 push(a,head);
01540 return 0;
01541
01542 error:
01543 return ret;
01544 }
01545
01546
01547
01548
01549
01550
01551
01552 int fix_rls(void)
01553 {
01554 int i,ret;
01555 for(i=0;i<RT_NO;i++){
01556 if(rlist[i]){
01557 if ((ret=fix_actions(rlist[i]))!=0){
01558 return ret;
01559 }
01560 }
01561 }
01562 for(i=0;i<ONREPLY_RT_NO;i++){
01563 if(onreply_rlist[i]){
01564 if ((ret=fix_actions(onreply_rlist[i]))!=0){
01565 return ret;
01566 }
01567 }
01568 }
01569 for(i=0;i<FAILURE_RT_NO;i++){
01570 if(failure_rlist[i]){
01571 if ((ret=fix_actions(failure_rlist[i]))!=0){
01572 return ret;
01573 }
01574 }
01575 }
01576 for(i=0;i<BRANCH_RT_NO;i++){
01577 if(branch_rlist[i]){
01578 if ((ret=fix_actions(branch_rlist[i]))!=0){
01579 return ret;
01580 }
01581 }
01582 }
01583 if(error_rlist){
01584 if ((ret=fix_actions(error_rlist))!=0){
01585 return ret;
01586 }
01587 }
01588 #ifdef USE_LOCAL_ROUTE
01589 if(local_rlist){
01590 if ((ret=fix_actions(local_rlist))!=0){
01591 return ret;
01592 }
01593 }
01594 #endif
01595 return 0;
01596 }
01597
01598
01599 static int rcheck_stack[RT_NO];
01600 static int rcheck_stack_p = 0;
01601 static int rcheck_status = 0;
01602
01603
01604
01605
01606
01607
01608
01609
01610 static int check_actions(struct action *a, int r_type)
01611 {
01612 struct action *aitem;
01613 cmd_export_t *fct;
01614 int n;
01615
01616 for( ; a ; a=a->next ) {
01617 switch (a->type) {
01618 case ROUTE_T:
01619
01620 for( n=0 ; n<rcheck_stack_p ; n++ ) {
01621 if (rcheck_stack[n]==(int)a->elem[0].u.number)
01622 break;
01623 }
01624 if (n!=rcheck_stack_p)
01625 break;
01626 if (++rcheck_stack_p==RT_NO) {
01627 LM_CRIT("stack overflow (%d)\n", rcheck_stack_p);
01628 goto error;
01629 }
01630 rcheck_stack[rcheck_stack_p] = a->elem[0].u.number;
01631 if (check_actions( rlist[a->elem[0].u.number], r_type)!=0)
01632 goto error;
01633 rcheck_stack_p--;
01634 break;
01635 case IF_T:
01636 if (check_actions((struct action*)a->elem[1].u.data, r_type)!=0)
01637 goto error;
01638 if (check_actions((struct action*)a->elem[2].u.data, r_type)!=0)
01639 goto error;
01640 break;
01641 case WHILE_T:
01642 if (check_actions((struct action*)a->elem[1].u.data, r_type)!=0)
01643 goto error;
01644 break;
01645 case SWITCH_T:
01646 aitem = (struct action*)a->elem[1].u.data;
01647 for( ; aitem ; aitem=aitem->next ) {
01648 n = check_actions((struct action*)aitem->elem[1].u.data,
01649 r_type);
01650 if (n!=0) goto error;
01651 }
01652 break;
01653 case MODULE_T:
01654
01655 fct = (cmd_export_t*)(a->elem[0].u.data);
01656 if ( (fct->flags&r_type)!=r_type ) {
01657 rcheck_status = -1;
01658 LM_ERR("script function "
01659 "\"%s\" (types=%d) does not support route type "
01660 "(%d)\n",fct->name, fct->flags, r_type);
01661 for( n=rcheck_stack_p-1; n>=0 ; n-- ) {
01662 LM_ERR("route stack[%d]=%d\n",n,rcheck_stack[n]);
01663 }
01664 }
01665 break;
01666 default:
01667 break;
01668 }
01669 }
01670
01671 return 0;
01672 error:
01673 return -1;
01674 }
01675
01676
01677
01678
01679
01680
01681 int check_rls(void)
01682 {
01683 int i, ret;
01684
01685 rcheck_status = 0;
01686
01687 if(rlist[0]){
01688 if ((ret=check_actions(rlist[0],REQUEST_ROUTE))!=0){
01689 LM_ERR("check failed for main request route\n");
01690 return ret;
01691 }
01692 }
01693 for(i=0;i<ONREPLY_RT_NO;i++){
01694 if(onreply_rlist[i]){
01695 if ((ret=check_actions(onreply_rlist[i],ONREPLY_ROUTE))!=0){
01696 LM_ERR("check failed for onreply_route[%d]\n",i);
01697 return ret;
01698 }
01699 }
01700 }
01701 for(i=0;i<FAILURE_RT_NO;i++){
01702 if(failure_rlist[i]){
01703 if ((ret=check_actions(failure_rlist[i],FAILURE_ROUTE))!=0){
01704 LM_ERR("check failed for failure_route[%d]\n",i);
01705 return ret;
01706 }
01707 }
01708 }
01709 for(i=0;i<BRANCH_RT_NO;i++){
01710 if(branch_rlist[i]){
01711 if ((ret=check_actions(branch_rlist[i],BRANCH_ROUTE))!=0){
01712 LM_ERR("check failed for branch_route[%d]\n",i);
01713 return ret;
01714 }
01715 }
01716 }
01717 if(error_rlist){
01718 if ((ret=check_actions(error_rlist,ERROR_ROUTE))!=0){
01719 LM_ERR("check failed for error_route\n");
01720 return ret;
01721 }
01722 }
01723 #ifdef USE_LOCAL_ROUTE
01724 if(local_rlist){
01725 if ((ret=check_actions(local_rlist,LOCAL_ROUTE))!=0){
01726 LM_ERR("check failed for local_route\n");
01727 return ret;
01728 }
01729 }
01730 #endif
01731 return rcheck_status;
01732 }
01733
01734
01735
01736
01737
01738 void print_rl(void)
01739 {
01740 int j;
01741
01742 for(j=0; j<RT_NO; j++){
01743 if (rlist[j]==0){
01744 if (j==0) LM_DBG("WARNING: the main routing table is empty\n");
01745 continue;
01746 }
01747 LM_DBG("routing table %d:\n",j);
01748 print_actions(rlist[j]);
01749 LM_DBG("\n");
01750 }
01751 for(j=0; j<ONREPLY_RT_NO; j++){
01752 if (onreply_rlist[j]==0){
01753 continue;
01754 }
01755 LM_DBG("onreply routing table %d:\n",j);
01756 print_actions(onreply_rlist[j]);
01757 LM_DBG("\n");
01758 }
01759 for(j=0; j<FAILURE_RT_NO; j++){
01760 if (failure_rlist[j]==0){
01761 continue;
01762 }
01763 LM_DBG("failure routing table %d:\n",j);
01764 print_actions(failure_rlist[j]);
01765 LM_DBG("\n");
01766 }
01767 for(j=0; j<BRANCH_RT_NO; j++){
01768 if (branch_rlist[j]==0){
01769 continue;
01770 }
01771 LM_DBG("T-branch routing table %d:\n",j);
01772 print_actions(branch_rlist[j]);
01773 LM_DBG("\n");
01774 }
01775 }