/* run a list of actions */ int run_action_list(struct action* a, struct sip_msg* msg) { int ret=E_UNSPEC; struct action* t; for (t=a; t!=0; t=t->next){ ret=do_action(t, msg); /* if action returns 0, then stop processing the script */ if(ret==0) action_flags |= ACT_FL_EXIT; /* check for errors */ if (_oser_err_info.eclass!=0 && error_rlist.a!=NULL && (route_type&(ERROR_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE))==0 ) run_error_route(msg,0); /* continue or not ? */ if( action_flags&(ACT_FL_RETURN|ACT_FL_EXIT) ) break; } return ret; }
/*! \note WARNING: buf must be 0 terminated (buf[len]=0) or some things might * break (e.g.: modules/textops) */ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) { struct sip_msg* msg; struct timeval start; int rc; char *tmp; str in_buff; in_buff.len = len; in_buff.s = buf; /* the raw processing callbacks can change the buffer, further use in_buff.s and at the end try to free in_buff.s if changed by callbacks */ run_raw_processing_cb(PRE_RAW_PROCESSING,&in_buff); /* update the length for further processing */ len = in_buff.len; msg=pkg_malloc(sizeof(struct sip_msg)); if (msg==0) { LM_ERR("no pkg mem left for sip_msg\n"); goto error; } msg_no++; /* number of vias parsed -- good for diagnostic info in replies */ via_cnt=0; memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */ /* fill in msg */ msg->buf=in_buff.s; msg->len=len; msg->rcv=*rcv_info; msg->id=msg_no; msg->set_global_address=default_global_address; msg->set_global_port=default_global_port; if (parse_msg(in_buff.s,len, msg)!=0){ tmp=ip_addr2a(&(rcv_info->src_ip)); LM_ERR("Unable to parse msg received from [%s:%d]\n", tmp, rcv_info->src_port); /* if a REQUEST msg was detected (first line was succesfully parsed) we should trigger the error route */ if ( msg->first_line.type==SIP_REQUEST && error_rlist.a!=NULL ) run_error_route(msg, 1); goto parse_error; } LM_DBG("After parse_msg...\n"); start_expire_timer(start,execmsgthreshold); /* ... clear branches from previous message */ clear_branches(); if (msg->first_line.type==SIP_REQUEST) { update_stat( rcv_reqs, 1); /* sanity checks */ if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){ /* no via, send back error ? */ LM_ERR("no via found in request\n"); update_stat( err_reqs, 1); goto parse_error; } /* check if necessary to add receive?->moved to forward_req */ /* check for the alias stuff */ #ifdef USE_TCP if (msg->via1->alias && tcp_accept_aliases && (((rcv_info->proto==PROTO_TCP) && !tcp_disable) #ifdef USE_TLS || ((rcv_info->proto==PROTO_TLS) && !tls_disable) #endif ) ){ if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port, rcv_info->proto)!=0){ LM_ERR("tcp alias failed\n"); /* continue */ } } #endif LM_DBG("preparing to run routing scripts...\n"); /* set request route type --bogdan*/ set_route_type( REQUEST_ROUTE ); /* execute pre-script callbacks, if any; * if some of the callbacks said not to continue with * script processing, don't do so; * if we are here basic sanity checks are already done * (like presence of at least one via), so you can count * on via1 being parsed in a pre-script callback --andrei */ rc = exec_pre_req_cb(msg); if (rc == SCB_DROP_MSG) { update_stat( drp_reqs, 1); goto end; /* drop the message */ } /* exec the routing script */ if (rc & SCB_RUN_TOP_ROUTE) run_top_route(rlist[DEFAULT_RT].a, msg); /* execute post request-script callbacks */ if (rc & SCB_RUN_POST_CBS) exec_post_req_cb(msg); } else if (msg->first_line.type==SIP_REPLY) { update_stat( rcv_rpls, 1); /* sanity checks */ if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){ /* no via, send back error ? */ LM_ERR("no via found in reply\n"); update_stat( err_rpls, 1); goto parse_error; } /* set reply route type --bogdan*/ set_route_type( ONREPLY_ROUTE ); /* execute pre-script callbacks, if any ; * if some of the callbacks said not to continue with * script processing, don't do so ; * if we are here, basic sanity checks are already done * (like presence of at least one via), so you can count * on via1 being parsed in a pre-script callback --andrei */ rc = exec_pre_rpl_cb(msg); if (rc == SCB_DROP_MSG) { update_stat( drp_rpls, 1); goto end; /* drop the reply */ } /* exec the onreply routing script */ if (rc & SCB_RUN_TOP_ROUTE && onreply_rlist[DEFAULT_RT].a && (run_top_route(onreply_rlist[DEFAULT_RT].a,msg) & ACT_FL_DROP) && msg->REPLY_STATUS < 200) { LM_DBG("dropping provisional reply %d\n", msg->REPLY_STATUS); update_stat( drp_rpls, 1); goto end; /* drop the message */ } else { /* send the msg */ forward_reply(msg); /* TODO - TX reply stat */ } /* execute post reply-script callbacks */ if (rc & SCB_RUN_POST_CBS) exec_post_rpl_cb(msg); } end: stop_expire_timer( start, execmsgthreshold, "msg processing", msg->buf, msg->len, 0); reset_longest_action_list(execmsgthreshold); /* free possible loaded avps -bogdan */ reset_avps(); LM_DBG("cleaning up\n"); free_sip_msg(msg); pkg_free(msg); if (in_buff.s != buf) pkg_free(in_buff.s); return 0; parse_error: exec_parse_err_cb(msg); free_sip_msg(msg); pkg_free(msg); error: if (in_buff.s != buf) pkg_free(in_buff.s); return -1; }