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