Makefile.defs: version set 3.4.0-dev2
[sip-router] / receive.c
index beb4c58..a4018ff 100644 (file)
--- a/receive.c
+++ b/receive.c
  * 2006-11-29 nonsip_msg hooks called for non-sip msg (e.g HTTP) (andrei)
  */
 
+/*!
+ * \file
+ * \brief SIP-router core :: 
+ * \ingroup core
+ * Module: \ref core
+ */
+
 
 #include <string.h>
 #include <stdlib.h>
 #include "nonsip_hooks.h"
 #include "dset.h"
 #include "usr_avp.h"
+#ifdef WITH_XAVP
+#include "xavp.h"
+#endif
 #include "select_buf.h"
 
 #include "tcp_server.h" /* for tcpconn_add_alias */
 #include "tcp_options.h" /* for access to tcp_accept_aliases*/
 #include "cfg/cfg.h"
+#include "core_stats.h"
 
 #ifdef DEBUG_DMALLOC
 #include <mem/dmalloc.h>
@@ -76,6 +87,13 @@ str default_global_port={0,0};
 str default_via_address={0,0};
 str default_via_port={0,0};
 
+/**
+ * increment msg_no and return the new value
+ */
+unsigned int inc_msg_no(void)
+{
+       return ++msg_no;
+}
 
 
 /* WARNING: buf must be 0 terminated (buf[len]=0) or some things might 
@@ -84,14 +102,20 @@ str default_via_port={0,0};
 int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
 {
        struct sip_msg* msg;
+       struct run_act_ctx ctx;
        int ret;
-       struct run_act_ctx ra_ctx;
 #ifdef STATS
        int skipped = 1;
        struct timeval tvb, tve;        
        struct timezone tz;
        unsigned int diff;
 #endif
+       str inb;
+
+       inb.s = buf;
+       inb.len = len;
+       sr_event_exec(SREV_NET_DATA_IN, (void*)&inb);
+       len = inb.len;
 
        msg=pkg_malloc(sizeof(struct sip_msg));
        if (msg==0) {
@@ -111,11 +135,15 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
        /* buf[len]=0; */ /* WARNING: zero term removed! */
        msg->rcv=*rcv_info;
        msg->id=msg_no;
+       msg->pid=my_pid();
        msg->set_global_address=default_global_address;
        msg->set_global_port=default_global_port;
        
+       if(likely(sr_msg_time==1)) msg_set_time(msg);
+
        if (parse_msg(buf,len, msg)!=0){
-               LOG(L_ERR, "ERROR: receive_msg: parse_msg failed\n");
+               LOG(cfg_get(core, core_cfg, corelog),
+                               "ERROR: receive_msg: parse_msg failed\n");
                goto error02;
        }
        DBG("After parse_msg...\n");
@@ -123,17 +151,21 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 
        /* ... clear branches from previous message */
        clear_branches();
-       reset_static_buffer();
 
        if (msg->first_line.type==SIP_REQUEST){
+               ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
                if (!IS_SIP(msg)){
-                       if (nonsip_msg_run_hooks(msg)!=NONSIP_MSG_ACCEPT)
+                       if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
+                               if (unlikely(ret==NONSIP_MSG_ERROR))
+                                       goto error03;
                                goto end; /* drop the message */
+                       }
                }
                /* sanity checks */
                if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
                        /* no via, send back error ? */
                        LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
+                       STATS_BAD_MSG();
                        goto error02;
                }
                /* check if necessary to add receive?->moved to forward_req */
@@ -153,7 +185,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                        }
                }
 #endif
-                       
+
        /*      skip: */
                DBG("preparing to run routing scripts...\n");
 #ifdef  STATS
@@ -166,13 +198,15 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                   (like presence of at least one via), so you can count
                   on via1 being parsed in a pre-script callback --andrei
                */
-               if (exec_pre_req_cb(msg)==0 )
+               if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
+               {
+                       STATS_REQ_FWD_DROP();
                        goto end; /* drop the request */
+               }
 
                set_route_type(REQUEST_ROUTE);
                /* exec the routing script */
-               init_run_actions_ctx(&ra_ctx);
-               if (run_actions(&ra_ctx, main_rt.rlist[DEFAULT_RT], msg)<0){
+               if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
                        LOG(L_WARN, "WARNING: receive_msg: "
                                        "error while trying script\n");
                        goto error_req;
@@ -188,12 +222,13 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 #endif
 
                /* execute post request-script callbacks */
-               exec_post_req_cb(msg);
+               exec_post_script_cb(msg, REQUEST_CB_TYPE);
        }else if (msg->first_line.type==SIP_REPLY){
                /* sanity checks */
                if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
                        /* no via, send back error ? */
                        LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
+                       STATS_BAD_RPL();
                        goto error02;
                }
 
@@ -209,20 +244,27 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                   (like presence of at least one via), so you can count
                   on via1 being parsed in a pre-script callback --andrei
                */
-               if (exec_pre_rpl_cb(msg)==0 )
-                       goto end; /* drop the request */
+               if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
+               {
+                       STATS_RPL_FWD_DROP();
+                       goto end; /* drop the reply */
+               }
 
                /* exec the onreply routing script */
                if (onreply_rt.rlist[DEFAULT_RT]){
-                       set_route_type(ONREPLY_ROUTE);
-                       init_run_actions_ctx(&ra_ctx);
-                       ret=run_actions(&ra_ctx, onreply_rt.rlist[DEFAULT_RT], msg);
-                       if (ret<0){
+                       set_route_type(CORE_ONREPLY_ROUTE);
+                       ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
+#ifndef NO_ONREPLY_ROUTE_ERROR
+                       if (unlikely(ret<0)){
                                LOG(L_WARN, "WARNING: receive_msg: "
                                                "error while trying onreply script\n");
                                goto error_rpl;
-                       }else if (ret==0) goto skip_send_reply; /* drop the message, 
-                                                                                                          no error */
+                       }else
+#endif /* NO_ONREPLY_ROUTE_ERROR */
+                       if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
+                               STATS_RPL_FWD_DROP();
+                               goto skip_send_reply; /* drop the message, no error */
+                       }
                }
                /* send the msg */
                forward_reply(msg);
@@ -236,7 +278,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 #endif
 
                /* execute post reply-script callbacks */
-               exec_post_rpl_cb(msg);
+               exec_post_script_cb(msg, ONREPLY_CB_TYPE);
        }
 
 end:
@@ -245,6 +287,9 @@ end:
 #endif
        /* free possible loaded avps -bogdan */
        reset_avps();
+#ifdef WITH_XAVP
+       xavp_reset_list();
+#endif
        DBG("receive_msg: cleaning up\n");
        free_sip_msg(msg);
        pkg_free(msg);
@@ -252,17 +297,26 @@ end:
        if (skipped) STATS_RX_DROPS;
 #endif
        return 0;
+#ifndef NO_ONREPLY_ROUTE_ERROR
 error_rpl:
        /* execute post reply-script callbacks */
-       exec_post_rpl_cb(msg);
+       exec_post_script_cb(msg, ONREPLY_CB_TYPE);
        reset_avps();
+#ifdef WITH_XAVP
+       xavp_reset_list();
+#endif
        goto error02;
+#endif /* NO_ONREPLY_ROUTE_ERROR */
 error_req:
        DBG("receive_msg: error:...\n");
        /* execute post request-script callbacks */
-       exec_post_req_cb(msg);
+       exec_post_script_cb(msg, REQUEST_CB_TYPE);
+error03:
        /* free possible loaded avps -bogdan */
        reset_avps();
+#ifdef WITH_XAVP
+       xavp_reset_list();
+#endif
 error02:
        free_sip_msg(msg);
        pkg_free(msg);