Browse code

- script callbacks splitted into REQUEST and REPLY callbacks for flexibility and efficiency reasons

Bogdan-Andrei Iancu authored on 13/02/2005 18:25:11
Showing 3 changed files
... ...
@@ -81,7 +81,6 @@ str default_via_port={0,0};
81 81
 int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
82 82
 {
83 83
 	struct sip_msg* msg;
84
-	int ret;
85 84
 #ifdef STATS
86 85
 	int skipped = 1;
87 86
 	struct timeval tvb, tve;	
... ...
@@ -125,7 +124,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
125 125
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
126 126
 			/* no via, send back error ? */
127 127
 			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
128
-			goto error;
128
+			goto error02;
129 129
 		}
130 130
 		/* check if necessary to add receive?->moved to forward_req */
131 131
 		/* check for the alias stuff */
... ...
@@ -156,16 +155,14 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
156 156
 		   (like presence of at least one via), so you can count
157 157
 		   on via1 being parsed in a pre-script callback --andrei
158 158
 		*/
159
-		ret=exec_pre_cb(msg);
160
-		if (ret<=0){
161
-			if (ret<0) goto error;
162
-			else goto end; /* drop the message -- no error -- andrei */
163
-		}
159
+		if (exec_pre_req_cb(msg)==0 )
160
+			goto end; /* drop the request */
161
+
164 162
 		/* exec the routing script */
165 163
 		if (run_actions(rlist[0], msg)<0) {
166 164
 			LOG(L_WARN, "WARNING: receive_msg: "
167 165
 					"error while trying script\n");
168
-			goto error;
166
+			goto error_req;
169 167
 		}
170 168
 
171 169
 #ifdef STATS
... ...
@@ -176,21 +173,16 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
176 176
 		DBG("successfully ran routing scripts...(%d usec)\n", diff);
177 177
 		STATS_RX_REQUEST( msg->first_line.u.request.method_value );
178 178
 #endif
179
+
180
+		/* execute post request-script callbacks */
181
+		exec_post_req_cb(msg);
179 182
 	}else if (msg->first_line.type==SIP_REPLY){
180 183
 		/* sanity checks */
181 184
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
182 185
 			/* no via, send back error ? */
183 186
 			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
184
-			goto error;
185
-		}
186
-#if 0
187
-		if ((msg->via2==0) || (msg->via2->error!=PARSE_OK)){
188
-			/* no second via => error? */
189
-			LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
190
-			goto error;
187
+			goto error02;
191 188
 		}
192
-		/* check if via1 == us */
193
-#endif
194 189
 
195 190
 #ifdef STATS
196 191
 		gettimeofday( & tvb, &tz );
... ...
@@ -204,11 +196,8 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
204 204
 		   (like presence of at least one via), so you can count
205 205
 		   on via1 being parsed in a pre-script callback --andrei
206 206
 		*/
207
-		ret=exec_pre_cb(msg);
208
-		if (ret<=0){
209
-			if (ret<0) goto error;
210
-			else goto end; /* drop the message -- no error -- andrei */
211
-		}
207
+		if (exec_pre_rpl_cb(msg)==0 )
208
+			goto end; /* drop the request */
212 209
 
213 210
 		/* send the msg */
214 211
 		forward_reply(msg);
... ...
@@ -220,13 +209,15 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
220 220
 		stats->acc_res_time+=diff;
221 221
 		DBG("successfully ran reply processing...(%d usec)\n", diff);
222 222
 #endif
223
+
224
+		/* execute post reply-script callbacks */
225
+		exec_post_rpl_cb(msg);
223 226
 	}
227
+
224 228
 end:
225 229
 #ifdef STATS
226 230
 	skipped = 0;
227 231
 #endif
228
-	/* execute post-script callbacks, if any; -jiri */
229
-	exec_post_cb(msg);
230 232
 	/* free possible loaded avps -bogdan */
231 233
 	reset_avps();
232 234
 	DBG("receive_msg: cleaning up\n");
... ...
@@ -236,10 +227,10 @@ end:
236 236
 	if (skipped) STATS_RX_DROPS;
237 237
 #endif
238 238
 	return 0;
239
-error:
240
-	DBG("error:...\n");
241
-	/* execute post-script callbacks, if any; -jiri */
242
-	exec_post_cb(msg);
239
+error_req:
240
+	DBG("receive_msg: error:...\n");
241
+	/* execute post request-script callbacks */
242
+	exec_post_req_cb(msg);
243 243
 	/* free possible loaded avps -bogdan */
244 244
 	reset_avps();
245 245
 error02:
... ...
@@ -28,11 +28,12 @@
28 28
  * You should have received a copy of the GNU General Public License 
29 29
  * along with this program; if not, write to the Free Software 
30 30
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31
- */
32
-/* History:
31
+ *
32
+ * History:
33 33
  * --------
34 34
  *  2003-03-29  cleaning pkg allocation introduced (jiri)
35 35
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
36
+ *  2005-02-13  script callbacks devided into request and reply types (bogdan)
36 37
  */
37 38
 
38 39
 
... ...
@@ -42,61 +43,137 @@
42 42
 #include "error.h"
43 43
 #include "mem/mem.h"
44 44
 
45
-static struct script_cb *pre_cb=0;
46
-static struct script_cb *post_cb=0;
45
+static struct script_cb *pre_req_cb=0;
46
+static struct script_cb *post_req_cb=0;
47
+
48
+static struct script_cb *pre_rpl_cb=0;
49
+static struct script_cb *post_rpl_cb=0;
50
+
47 51
 static unsigned int cb_id=0;
48 52
 
49
-int register_script_cb( cb_function f, callback_t t, void *param )
53
+
54
+static inline int add_callback( struct script_cb **list,
55
+	cb_function f, void *param)
50 56
 {
51 57
 	struct script_cb *new_cb;
52 58
 
53 59
 	new_cb=pkg_malloc(sizeof(struct script_cb));
54 60
 	if (new_cb==0) {
55
-		LOG(L_ERR, "ERROR: register_script_cb: out of memory\n");
56
-		return E_OUT_OF_MEM;
61
+		LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
62
+		return -1;
57 63
 	}
58
-	new_cb->cbf=f;
59
-	new_cb->id=cb_id++;
60
-	new_cb->param=param;
61
-	/* insert into appropriate list */
62
-	if (t==PRE_SCRIPT_CB) {
63
-		new_cb->next=pre_cb;
64
-		pre_cb=new_cb;
65
-	} else if (t==POST_SCRIPT_CB) {
66
-		new_cb->next=post_cb;
67
-		post_cb=new_cb;
68
-	} else {
69
-		LOG(L_CRIT, "ERROR: register_script_cb: unknown CB type\n");
70
-		return E_BUG;
64
+	new_cb->cbf = f;
65
+	new_cb->id = cb_id++;
66
+	new_cb->param = param;
67
+	/* link at the beginning of the list */
68
+	new_cb->next = *list;
69
+	*list = new_cb;
70
+	return 0;
71
+}
72
+
73
+
74
+int register_script_cb( cb_function f, int type, void *param )
75
+{
76
+	/* type checkings */
77
+	if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
78
+		LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
79
+			"type not specified\n");
80
+		goto error;
71 81
 	}
72
-	/* ok, callback installed */
73
-	return 1;
82
+	if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
83
+	(type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
84
+		LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
85
+			"be exactly one\n");
86
+		goto error;
87
+	}
88
+
89
+	if (type&REQ_TYPE_CB) {
90
+		/* callback for request script */
91
+		if (type&PRE_SCRIPT_CB) {
92
+			if (add_callback( &pre_req_cb, f, param)<0)
93
+				goto add_error;
94
+		} else if (type&POST_SCRIPT_CB) {
95
+			if (add_callback( &post_req_cb, f, param)<0)
96
+				goto add_error;
97
+		}
98
+	}
99
+	if (type&REQ_TYPE_CB) {
100
+		/* callback (also) for reply script */
101
+		if (type&PRE_SCRIPT_CB) {
102
+			if (add_callback( &pre_rpl_cb, f, param)<0)
103
+				goto add_error;
104
+		} else if (type&POST_SCRIPT_CB) {
105
+			if (add_callback( &post_rpl_cb, f, param)<0)
106
+				goto add_error;
107
+		}
108
+	}
109
+
110
+	return 0;
111
+add_error:
112
+	LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
113
+error:
114
+	return -1;
74 115
 }
75 116
 
76
-void destroy_script_cb()
117
+
118
+static inline void destroy_cb_list(struct script_cb **list)
77 119
 {
78
-	struct script_cb *cb, *foo;
120
+	struct script_cb *foo;
121
+
122
+	while( *list ) {
123
+		foo = *list;
124
+		*list = (*list)->next;
125
+		pkg_free( foo );
126
+	}
127
+}
79 128
 
80
-	cb=pre_cb;
81
-	while(cb) { foo=cb->next;pkg_free(cb);cb=foo; }
82
-	cb=post_cb;
83
-	while(cb) { foo=cb->next;pkg_free(cb);cb=foo; }
129
+
130
+void destroy_script_cb()
131
+{
132
+	destroy_cb_list( &pre_req_cb  );
133
+	destroy_cb_list( &post_req_cb );
134
+	destroy_cb_list( &pre_rpl_cb  );
135
+	destroy_cb_list( &post_req_cb );
84 136
 }
85 137
 
86
-int exec_pre_cb( struct sip_msg *msg)
138
+
139
+static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
87 140
 {
88
-	struct script_cb *i;
89
-	for (i=pre_cb; i; i=i->next) {
141
+	for ( ; cb ; cb=cb->next ) {
90 142
 		/* stop on error */
91
-		if (i->cbf(msg, i->param)==0)
143
+		if (cb->cbf(msg, cb->param)==0)
92 144
 			return 0;
93 145
 	}
94 146
 	return 1;
95 147
 }
96 148
 
97
-void exec_post_cb( struct sip_msg *msg)
149
+
150
+static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
151
+{
152
+	for ( ; cb ; cb=cb->next){
153
+		cb->cbf( msg, cb->param);
154
+	}
155
+	return 1;
156
+}
157
+
158
+
159
+int exec_pre_req_cb( struct sip_msg *msg)
160
+{
161
+	return exec_pre_cb( msg, pre_req_cb);
162
+}
163
+
164
+int exec_pre_rpl_cb( struct sip_msg *msg)
165
+{
166
+	return exec_pre_cb( msg, pre_rpl_cb);
167
+}
168
+
169
+int exec_post_req_cb( struct sip_msg *msg)
170
+{
171
+	return exec_post_cb( msg, post_req_cb);
172
+}
173
+
174
+int exec_post_rpl_cb( struct sip_msg *msg)
98 175
 {
99
-	struct script_cb *i;
100
-	for (i=post_cb; i; i=i->next) i->cbf(msg, i->param);
176
+	return exec_post_cb( msg, post_rpl_cb);
101 177
 }
102 178
 
... ...
@@ -23,6 +23,10 @@
23 23
  * You should have received a copy of the GNU General Public License 
24 24
  * along with this program; if not, write to the Free Software 
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ *
27
+ * History:
28
+ * --------
29
+ *  2005-02-13  script callbacks devided into request and reply types (bogdan)
26 30
  */
27 31
 
28 32
 #ifndef _SCRIPT_CB_H_
... ...
@@ -32,10 +36,11 @@
32 32
 
33 33
 typedef int (cb_function)( struct sip_msg *msg, void *param );
34 34
 
35
-typedef enum {
36
-    PRE_SCRIPT_CB,
37
-	POST_SCRIPT_CB
38
-} callback_t;       /* Allowed types of callbacks */
35
+
36
+#define PRE_SCRIPT_CB    (1<<0)
37
+#define POST_SCRIPT_CB   (1<<1)
38
+#define REQ_TYPE_CB      (1<<2)
39
+#define RPL_TYPE_CB      (1<<3)
39 40
 
40 41
 
41 42
 struct script_cb{
... ...
@@ -45,10 +50,14 @@ struct script_cb{
45 45
 	void *param;
46 46
 };
47 47
 
48
-int register_script_cb( cb_function f, callback_t t, void *param );
49
-int exec_pre_cb( struct sip_msg *msg);
50
-void exec_post_cb( struct sip_msg *msg);
48
+int register_script_cb( cb_function f, int type, void *param );
51 49
 void destroy_script_cb();
52 50
 
51
+int exec_pre_req_cb( struct sip_msg *msg);
52
+int exec_post_req_cb( struct sip_msg *msg);
53
+
54
+int exec_pre_rpl_cb( struct sip_msg *msg);
55
+int exec_post_rpl_cb( struct sip_msg *msg);
56
+
53 57
 #endif
54 58