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