- added special callbacks for non-sip msg (e.g http), They are called every
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 11 Dec 2006 15:47:32 +0000 (15:47 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 11 Dec 2006 15:47:32 +0000 (15:47 +0000)
 time a message with the first line in sip/http format is received and the
 protocol != SIP.
 These callbacks are needed as a part of an xmlrpc bug fix.

Makefile.defs
main.c
nonsip_hooks.c [new file with mode: 0644]
nonsip_hooks.h [new file with mode: 0644]
parser/msg_parser.h
parser/parse_fline.c
receive.c

index 922f34b..1059c7a 100644 (file)
@@ -67,7 +67,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev63
+EXTRAVERSION = -dev64
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
                        $(SUBLEVEL) )
diff --git a/main.c b/main.c
index b63ce82..77baa2e 100644 (file)
--- a/main.c
+++ b/main.c
 #include "hash_func.h"
 #include "pt.h"
 #include "script_cb.h"
+#include "nonsip_hooks.h"
 #include "ut.h"
 #include "signals.h"
 #ifdef USE_TCP
@@ -437,6 +438,7 @@ void cleanup(show_status)
 #endif
        destroy_timer();
        destroy_script_cb();
+       destroy_nonsip_hooks();
        destroy_routes();
        destroy_atomic_ops();
 #ifdef PKG_MALLOC
@@ -1242,6 +1244,7 @@ int main(int argc, char** argv)
        }
        
        if (init_routes()<0) goto error;
+       if (init_nonsip_hooks()<0) goto error;
        /* fill missing arguments with the default values*/
        if (cfg_file==0) cfg_file=CFG_FILE;
 
diff --git a/nonsip_hooks.c b/nonsip_hooks.c
new file mode 100644 (file)
index 0000000..e55f98f
--- /dev/null
@@ -0,0 +1,125 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2006 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    info@iptel.org
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * non-sip callbacks, called whenever a message with protocol != SIP/2.0
+ * is received (the message must have at least a sip like first line or
+ * else they will be dropped before this callbacks are called
+ */
+/* 
+ * History:
+ * --------
+ *  2006-11-29  created by andrei
+ */
+
+#include "nonsip_hooks.h"
+#include "mem/mem.h"
+
+static struct nonsip_hook* nonsip_hooks;
+static unsigned int nonsip_max_hooks=MAX_NONSIP_HOOKS;
+static int last_hook_idx=0;
+
+
+
+int init_nonsip_hooks()
+{
+       nonsip_hooks=pkg_malloc(nonsip_max_hooks*
+                                                                       sizeof(struct nonsip_hook));
+       if (nonsip_hooks==0){
+               goto error;
+       }
+       memset(nonsip_hooks, 0, nonsip_max_hooks*sizeof(struct nonsip_hook));
+       return 0;
+error:
+       LOG(L_ERR, "nonsip_hooks: memory allocation failure\n");
+       return -1;
+}
+
+
+
+void destroy_nonsip_hooks()
+{
+       int r;
+       
+       if (nonsip_hooks){
+               for (r=0; r<last_hook_idx; r++){
+                       if (nonsip_hooks[r].destroy)
+                               nonsip_hooks[r].destroy();
+               }
+               pkg_free(nonsip_hooks);
+               nonsip_hooks=0;
+       }
+}
+
+
+
+/* allocates a new hook
+ * returns 0 on success and -1 on error */
+int register_nonsip_msg_hook(struct nonsip_hook *h)
+{
+       struct nonsip_hook* tmp;
+       int new_max_hooks;
+       
+       if (nonsip_max_hooks==0)
+               goto error;
+       if (last_hook_idx >= nonsip_max_hooks){
+               new_max_hooks=2*nonsip_max_hooks;
+               tmp=pkg_realloc(nonsip_hooks, 
+                               new_max_hooks*sizeof(struct nonsip_hook));
+               if (tmp==0){
+                       goto error;
+               }
+               nonsip_hooks=tmp;
+               /* init the new chunk */
+               memset(&nonsip_hooks[last_hook_idx+1], 0, 
+                                       (new_max_hooks-nonsip_max_hooks-1)*
+                                               sizeof(struct nonsip_hook));
+               nonsip_max_hooks=new_max_hooks;
+       }
+       nonsip_hooks[last_hook_idx]=*h;
+       last_hook_idx++;
+       return 0;
+error:
+       return -1;
+}
+
+
+
+int nonsip_msg_run_hooks(struct sip_msg* msg)
+{
+       int r;
+       int ret;
+       
+       ret=NONSIP_MSG_DROP; /* default, if no hook installed, drop */
+       for (r=0; r<last_hook_idx; r++){
+               ret=nonsip_hooks[r].on_nonsip_req(msg);
+               if (ret!=NONSIP_MSG_PASS) break;
+       }
+       return ret;
+}
+
+
+
diff --git a/nonsip_hooks.h b/nonsip_hooks.h
new file mode 100644 (file)
index 0000000..1d4c014
--- /dev/null
@@ -0,0 +1,67 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2006 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    info@iptel.org
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * non-sip callbacks, called whenever a message with protocol != SIP/2.0
+ * is received (the message must have at least a sip like first line or
+ * else they will be dropped before this callbacks are called
+ */
+/* 
+ * History:
+ * --------
+ *  2006-11-29  created by andrei
+ */
+
+
+#ifndef _nonsip_hooks_h
+#define _nonsip_hooks_h
+
+#include "parser/msg_parser.h" /* sip_msg */
+
+#define MAX_NONSIP_HOOKS 1
+
+enum nonsip_msg_returns{ NONSIP_MSG_ERROR=-1, NONSIP_MSG_DROP=0,
+                                                NONSIP_MSG_PASS,     NONSIP_MSG_ACCEPT };
+
+struct nonsip_hook{
+       char* name; /* must be !=0, it has only "debugging" value */
+       /* called each time a sip like request (from the first line point of view)
+        * with protocol/version !=  SIP/2.0 is received
+        * return: 0 - drop message immediately, >0 - continue with other hooks,
+        *        <0 - error (drop message)
+        */
+       int (*on_nonsip_req)(struct sip_msg* msg);
+       /* called before ser shutdown (last minute cleanups) */
+       void (*destroy)(void);
+};
+
+
+int init_nonsip_hooks();
+void destroy_nonsip_hooks();
+int register_nonsip_msg_hook(struct nonsip_hook *h);
+int nonsip_msg_run_hooks(struct sip_msg* msg);
+
+#endif
index b74a157..1277d37 100644 (file)
@@ -101,6 +101,11 @@ if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
     !strncasecmp((req)->first_line.u.request.version.s,             \
                HTTP_VERSION, HTTP_VERSION_LEN))
 
+#define IS_SIP(req)                                                \
+    ((req)->first_line.u.request.version.len >= SIP_VERSION_LEN && \
+    !strncasecmp((req)->first_line.u.request.version.s,             \
+               SIP_VERSION, SIP_VERSION_LEN))
+
 /*
  * Return a URI to which the message should be really sent (not what should
  * be in the Request URI. The following fields are tried in this order:
index 86f9431..dab8762 100644 (file)
@@ -42,6 +42,8 @@
 #include "../mem/mem.h"
 #include "../ut.h"
 
+#define HTTP_REPLY_HACK /* allow HTTP replies */
+
 /* grammar:
        request  =  method SP uri SP version CRLF
        response =  version SP status  SP reason  CRLF
index 2599f9f..9fb17f2 100644 (file)
--- a/receive.c
+++ b/receive.c
@@ -37,6 +37,7 @@
  * 2004-04-30 exec_pre_cb is called after basic sanity checks (at least one
  *            via present & parsed ok)  (andrei)
  * 2004-08-23 avp core changed - destroy_avp-> reset_avps (bogdan)
+ * 2006-11-29 nonsip_msg hooks called for non-sip msg (e.g HTTP) (andrei)
  */
 
 
@@ -55,6 +56,7 @@
 #include "stats.h"
 #include "ip_addr.h"
 #include "script_cb.h"
+#include "nonsip_hooks.h"
 #include "dset.h"
 #include "usr_avp.h"
 #include "select_buf.h"
@@ -122,9 +124,12 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
        reset_static_buffer();
 
        if (msg->first_line.type==SIP_REQUEST){
+               if (!IS_SIP(msg)){
+                       if (nonsip_msg_run_hooks(msg)!=NONSIP_MSG_ACCEPT);
+                               goto end; /* drop the message */
+               }
                /* sanity checks */
                if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
-                       if (IS_HTTP(msg)) goto skip; /* Skip Via tests for HTTP requests */
                        /* no via, send back error ? */
                        LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
                        goto error02;
@@ -147,7 +152,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                }
 #endif
                        
-               skip:
+       /*      skip: */
                DBG("preparing to run routing scripts...\n");
 #ifdef  STATS
                gettimeofday( & tvb, &tz );
@@ -209,7 +214,8 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                                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 if (ret==0) goto skip_send_reply; /* drop the message, 
+                                                                                                          no error */
                }
                /* send the msg */
                forward_reply(msg);