Browse code

- 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 authored on 11/12/2006 15:47:32
Showing 7 changed files
... ...
@@ -67,7 +67,7 @@ MAIN_NAME=ser
67 67
 VERSION = 0
68 68
 PATCHLEVEL = 10
69 69
 SUBLEVEL =   99
70
-EXTRAVERSION = -dev63
70
+EXTRAVERSION = -dev64
71 71
 
72 72
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
73 73
 			$(SUBLEVEL) )
... ...
@@ -123,6 +123,7 @@
123 123
 #include "hash_func.h"
124 124
 #include "pt.h"
125 125
 #include "script_cb.h"
126
+#include "nonsip_hooks.h"
126 127
 #include "ut.h"
127 128
 #include "signals.h"
128 129
 #ifdef USE_TCP
... ...
@@ -437,6 +438,7 @@ void cleanup(show_status)
437 437
 #endif
438 438
 	destroy_timer();
439 439
 	destroy_script_cb();
440
+	destroy_nonsip_hooks();
440 441
 	destroy_routes();
441 442
 	destroy_atomic_ops();
442 443
 #ifdef PKG_MALLOC
... ...
@@ -1242,6 +1244,7 @@ int main(int argc, char** argv)
1242 1242
 	}
1243 1243
 	
1244 1244
 	if (init_routes()<0) goto error;
1245
+	if (init_nonsip_hooks()<0) goto error;
1245 1246
 	/* fill missing arguments with the default values*/
1246 1247
 	if (cfg_file==0) cfg_file=CFG_FILE;
1247 1248
 
1248 1249
new file mode 100644
... ...
@@ -0,0 +1,125 @@
0
+/* 
1
+ * $Id$
2
+ * 
3
+ * Copyright (C) 2006 iptelorg GmbH
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program; if not, write to the Free Software
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+/*
27
+ * non-sip callbacks, called whenever a message with protocol != SIP/2.0
28
+ * is received (the message must have at least a sip like first line or
29
+ * else they will be dropped before this callbacks are called
30
+ */
31
+/* 
32
+ * History:
33
+ * --------
34
+ *  2006-11-29  created by andrei
35
+ */
36
+
37
+#include "nonsip_hooks.h"
38
+#include "mem/mem.h"
39
+
40
+static struct nonsip_hook* nonsip_hooks;
41
+static unsigned int nonsip_max_hooks=MAX_NONSIP_HOOKS;
42
+static int last_hook_idx=0;
43
+
44
+
45
+
46
+int init_nonsip_hooks()
47
+{
48
+	nonsip_hooks=pkg_malloc(nonsip_max_hooks*
49
+									sizeof(struct nonsip_hook));
50
+	if (nonsip_hooks==0){
51
+		goto error;
52
+	}
53
+	memset(nonsip_hooks, 0, nonsip_max_hooks*sizeof(struct nonsip_hook));
54
+	return 0;
55
+error:
56
+	LOG(L_ERR, "nonsip_hooks: memory allocation failure\n");
57
+	return -1;
58
+}
59
+
60
+
61
+
62
+void destroy_nonsip_hooks()
63
+{
64
+	int r;
65
+	
66
+	if (nonsip_hooks){
67
+		for (r=0; r<last_hook_idx; r++){
68
+			if (nonsip_hooks[r].destroy)
69
+				nonsip_hooks[r].destroy();
70
+		}
71
+		pkg_free(nonsip_hooks);
72
+		nonsip_hooks=0;
73
+	}
74
+}
75
+
76
+
77
+
78
+/* allocates a new hook
79
+ * returns 0 on success and -1 on error */
80
+int register_nonsip_msg_hook(struct nonsip_hook *h)
81
+{
82
+	struct nonsip_hook* tmp;
83
+	int new_max_hooks;
84
+	
85
+	if (nonsip_max_hooks==0)
86
+		goto error;
87
+	if (last_hook_idx >= nonsip_max_hooks){
88
+		new_max_hooks=2*nonsip_max_hooks;
89
+		tmp=pkg_realloc(nonsip_hooks, 
90
+				new_max_hooks*sizeof(struct nonsip_hook));
91
+		if (tmp==0){
92
+			goto error;
93
+		}
94
+		nonsip_hooks=tmp;
95
+		/* init the new chunk */
96
+		memset(&nonsip_hooks[last_hook_idx+1], 0, 
97
+					(new_max_hooks-nonsip_max_hooks-1)*
98
+						sizeof(struct nonsip_hook));
99
+		nonsip_max_hooks=new_max_hooks;
100
+	}
101
+	nonsip_hooks[last_hook_idx]=*h;
102
+	last_hook_idx++;
103
+	return 0;
104
+error:
105
+	return -1;
106
+}
107
+
108
+
109
+
110
+int nonsip_msg_run_hooks(struct sip_msg* msg)
111
+{
112
+	int r;
113
+	int ret;
114
+	
115
+	ret=NONSIP_MSG_DROP; /* default, if no hook installed, drop */
116
+	for (r=0; r<last_hook_idx; r++){
117
+		ret=nonsip_hooks[r].on_nonsip_req(msg);
118
+		if (ret!=NONSIP_MSG_PASS) break;
119
+	}
120
+	return ret;
121
+}
122
+
123
+
124
+
0 125
new file mode 100644
... ...
@@ -0,0 +1,67 @@
0
+/* 
1
+ * $Id$
2
+ * 
3
+ * Copyright (C) 2006 iptelorg GmbH
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program; if not, write to the Free Software
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+/*
27
+ * non-sip callbacks, called whenever a message with protocol != SIP/2.0
28
+ * is received (the message must have at least a sip like first line or
29
+ * else they will be dropped before this callbacks are called
30
+ */
31
+/* 
32
+ * History:
33
+ * --------
34
+ *  2006-11-29  created by andrei
35
+ */
36
+
37
+
38
+#ifndef _nonsip_hooks_h
39
+#define _nonsip_hooks_h
40
+
41
+#include "parser/msg_parser.h" /* sip_msg */
42
+
43
+#define MAX_NONSIP_HOOKS 1
44
+
45
+enum nonsip_msg_returns{ NONSIP_MSG_ERROR=-1, NONSIP_MSG_DROP=0,
46
+						 NONSIP_MSG_PASS,     NONSIP_MSG_ACCEPT };
47
+
48
+struct nonsip_hook{
49
+	char* name; /* must be !=0, it has only "debugging" value */
50
+	/* called each time a sip like request (from the first line point of view)
51
+	 * with protocol/version !=  SIP/2.0 is received
52
+	 * return: 0 - drop message immediately, >0 - continue with other hooks,
53
+	 *        <0 - error (drop message)
54
+	 */
55
+	int (*on_nonsip_req)(struct sip_msg* msg);
56
+	/* called before ser shutdown (last minute cleanups) */
57
+	void (*destroy)(void);
58
+};
59
+
60
+
61
+int init_nonsip_hooks();
62
+void destroy_nonsip_hooks();
63
+int register_nonsip_msg_hook(struct nonsip_hook *h);
64
+int nonsip_msg_run_hooks(struct sip_msg* msg);
65
+
66
+#endif
... ...
@@ -101,6 +101,11 @@ if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
101 101
     !strncasecmp((req)->first_line.u.request.version.s,             \
102 102
 		HTTP_VERSION, HTTP_VERSION_LEN))
103 103
 
104
+#define IS_SIP(req)                                                \
105
+    ((req)->first_line.u.request.version.len >= SIP_VERSION_LEN && \
106
+    !strncasecmp((req)->first_line.u.request.version.s,             \
107
+		SIP_VERSION, SIP_VERSION_LEN))
108
+
104 109
 /*
105 110
  * Return a URI to which the message should be really sent (not what should
106 111
  * be in the Request URI. The following fields are tried in this order:
... ...
@@ -42,6 +42,8 @@
42 42
 #include "../mem/mem.h"
43 43
 #include "../ut.h"
44 44
 
45
+#define HTTP_REPLY_HACK /* allow HTTP replies */
46
+
45 47
 /* grammar:
46 48
 	request  =  method SP uri SP version CRLF
47 49
 	response =  version SP status  SP reason  CRLF
... ...
@@ -37,6 +37,7 @@
37 37
  * 2004-04-30 exec_pre_cb is called after basic sanity checks (at least one
38 38
  *            via present & parsed ok)  (andrei)
39 39
  * 2004-08-23 avp core changed - destroy_avp-> reset_avps (bogdan)
40
+ * 2006-11-29 nonsip_msg hooks called for non-sip msg (e.g HTTP) (andrei)
40 41
  */
41 42
 
42 43
 
... ...
@@ -55,6 +56,7 @@
55 55
 #include "stats.h"
56 56
 #include "ip_addr.h"
57 57
 #include "script_cb.h"
58
+#include "nonsip_hooks.h"
58 59
 #include "dset.h"
59 60
 #include "usr_avp.h"
60 61
 #include "select_buf.h"
... ...
@@ -122,9 +124,12 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
122 122
 	reset_static_buffer();
123 123
 
124 124
 	if (msg->first_line.type==SIP_REQUEST){
125
+		if (!IS_SIP(msg)){
126
+			if (nonsip_msg_run_hooks(msg)!=NONSIP_MSG_ACCEPT);
127
+				goto end; /* drop the message */
128
+		}
125 129
 		/* sanity checks */
126 130
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
127
-			if (IS_HTTP(msg)) goto skip; /* Skip Via tests for HTTP requests */
128 131
 			/* no via, send back error ? */
129 132
 			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
130 133
 			goto error02;
... ...
@@ -147,7 +152,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
147 147
 		}
148 148
 #endif
149 149
 			
150
-		skip:
150
+	/*	skip: */
151 151
 		DBG("preparing to run routing scripts...\n");
152 152
 #ifdef  STATS
153 153
 		gettimeofday( & tvb, &tz );
... ...
@@ -209,7 +214,8 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
209 209
 				LOG(L_WARN, "WARNING: receive_msg: "
210 210
 						"error while trying onreply script\n");
211 211
 				goto error_rpl;
212
-			}else if (ret==0) goto skip_send_reply; /* drop the message, no error */
212
+			}else if (ret==0) goto skip_send_reply; /* drop the message, 
213
+													   no error */
213 214
 		}
214 215
 		/* send the msg */
215 216
 		forward_reply(msg);