Browse Source

- added special callbacks for non-sip msg (e.g http), They are called every
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.

Andrei Pelinescu-Onciul 18 years ago
parent
commit
ac34f9f4eb
7 changed files with 212 additions and 4 deletions
  1. 1 1
      Makefile.defs
  2. 3 0
      main.c
  3. 125 0
      nonsip_hooks.c
  4. 67 0
      nonsip_hooks.h
  5. 5 0
      parser/msg_parser.h
  6. 2 0
      parser/parse_fline.c
  7. 9 3
      receive.c

+ 1 - 1
Makefile.defs

@@ -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) )

+ 3 - 0
main.c

@@ -123,6 +123,7 @@
 #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;
 

+ 125 - 0
nonsip_hooks.c

@@ -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:
+ *    [email protected]
+ *
+ * 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;
+}
+
+
+

+ 67 - 0
nonsip_hooks.h

@@ -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:
+ *    [email protected]
+ *
+ * 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

+ 5 - 0
parser/msg_parser.h

@@ -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:

+ 2 - 0
parser/parse_fline.c

@@ -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

+ 9 - 3
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);