Browse Source

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

Bogdan-Andrei Iancu 20 năm trước cách đây
mục cha
commit
2e89dc9248
3 tập tin đã thay đổi với 147 bổ sung70 xóa
  1. 19 28
      receive.c
  2. 112 35
      script_cb.c
  3. 16 7
      script_cb.h

+ 19 - 28
receive.c

@@ -81,7 +81,6 @@ str default_via_port={0,0};
 int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
 {
 	struct sip_msg* msg;
-	int ret;
 #ifdef STATS
 	int skipped = 1;
 	struct timeval tvb, tve;	
@@ -125,7 +124,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
 			/* no via, send back error ? */
 			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
-			goto error;
+			goto error02;
 		}
 		/* check if necessary to add receive?->moved to forward_req */
 		/* check for the alias stuff */
@@ -156,16 +155,14 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		   (like presence of at least one via), so you can count
 		   on via1 being parsed in a pre-script callback --andrei
 		*/
-		ret=exec_pre_cb(msg);
-		if (ret<=0){
-			if (ret<0) goto error;
-			else goto end; /* drop the message -- no error -- andrei */
-		}
+		if (exec_pre_req_cb(msg)==0 )
+			goto end; /* drop the request */
+
 		/* exec the routing script */
 		if (run_actions(rlist[0], msg)<0) {
 			LOG(L_WARN, "WARNING: receive_msg: "
 					"error while trying script\n");
-			goto error;
+			goto error_req;
 		}
 
 #ifdef STATS
@@ -176,21 +173,16 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		DBG("successfully ran routing scripts...(%d usec)\n", diff);
 		STATS_RX_REQUEST( msg->first_line.u.request.method_value );
 #endif
+
+		/* execute post request-script callbacks */
+		exec_post_req_cb(msg);
 	}else if (msg->first_line.type==SIP_REPLY){
 		/* sanity checks */
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
 			/* no via, send back error ? */
 			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
-			goto error;
-		}
-#if 0
-		if ((msg->via2==0) || (msg->via2->error!=PARSE_OK)){
-			/* no second via => error? */
-			LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
-			goto error;
+			goto error02;
 		}
-		/* check if via1 == us */
-#endif
 
 #ifdef STATS
 		gettimeofday( & tvb, &tz );
@@ -204,11 +196,8 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		   (like presence of at least one via), so you can count
 		   on via1 being parsed in a pre-script callback --andrei
 		*/
-		ret=exec_pre_cb(msg);
-		if (ret<=0){
-			if (ret<0) goto error;
-			else goto end; /* drop the message -- no error -- andrei */
-		}
+		if (exec_pre_rpl_cb(msg)==0 )
+			goto end; /* drop the request */
 
 		/* send the msg */
 		forward_reply(msg);
@@ -220,13 +209,15 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		stats->acc_res_time+=diff;
 		DBG("successfully ran reply processing...(%d usec)\n", diff);
 #endif
+
+		/* execute post reply-script callbacks */
+		exec_post_rpl_cb(msg);
 	}
+
 end:
 #ifdef STATS
 	skipped = 0;
 #endif
-	/* execute post-script callbacks, if any; -jiri */
-	exec_post_cb(msg);
 	/* free possible loaded avps -bogdan */
 	reset_avps();
 	DBG("receive_msg: cleaning up\n");
@@ -236,10 +227,10 @@ end:
 	if (skipped) STATS_RX_DROPS;
 #endif
 	return 0;
-error:
-	DBG("error:...\n");
-	/* execute post-script callbacks, if any; -jiri */
-	exec_post_cb(msg);
+error_req:
+	DBG("receive_msg: error:...\n");
+	/* execute post request-script callbacks */
+	exec_post_req_cb(msg);
 	/* free possible loaded avps -bogdan */
 	reset_avps();
 error02:

+ 112 - 35
script_cb.c

@@ -28,11 +28,12 @@
  * 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
- */
-/* History:
+ *
+ * History:
  * --------
  *  2003-03-29  cleaning pkg allocation introduced (jiri)
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
+ *  2005-02-13  script callbacks devided into request and reply types (bogdan)
  */
 
 
@@ -42,61 +43,137 @@
 #include "error.h"
 #include "mem/mem.h"
 
-static struct script_cb *pre_cb=0;
-static struct script_cb *post_cb=0;
+static struct script_cb *pre_req_cb=0;
+static struct script_cb *post_req_cb=0;
+
+static struct script_cb *pre_rpl_cb=0;
+static struct script_cb *post_rpl_cb=0;
+
 static unsigned int cb_id=0;
 
-int register_script_cb( cb_function f, callback_t t, void *param )
+
+static inline int add_callback( struct script_cb **list,
+	cb_function f, void *param)
 {
 	struct script_cb *new_cb;
 
 	new_cb=pkg_malloc(sizeof(struct script_cb));
 	if (new_cb==0) {
-		LOG(L_ERR, "ERROR: register_script_cb: out of memory\n");
-		return E_OUT_OF_MEM;
+		LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
+		return -1;
 	}
-	new_cb->cbf=f;
-	new_cb->id=cb_id++;
-	new_cb->param=param;
-	/* insert into appropriate list */
-	if (t==PRE_SCRIPT_CB) {
-		new_cb->next=pre_cb;
-		pre_cb=new_cb;
-	} else if (t==POST_SCRIPT_CB) {
-		new_cb->next=post_cb;
-		post_cb=new_cb;
-	} else {
-		LOG(L_CRIT, "ERROR: register_script_cb: unknown CB type\n");
-		return E_BUG;
+	new_cb->cbf = f;
+	new_cb->id = cb_id++;
+	new_cb->param = param;
+	/* link at the beginning of the list */
+	new_cb->next = *list;
+	*list = new_cb;
+	return 0;
+}
+
+
+int register_script_cb( cb_function f, int type, void *param )
+{
+	/* type checkings */
+	if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
+		LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
+			"type not specified\n");
+		goto error;
 	}
-	/* ok, callback installed */
-	return 1;
+	if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
+	(type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
+		LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
+			"be exactly one\n");
+		goto error;
+	}
+
+	if (type&REQ_TYPE_CB) {
+		/* callback for request script */
+		if (type&PRE_SCRIPT_CB) {
+			if (add_callback( &pre_req_cb, f, param)<0)
+				goto add_error;
+		} else if (type&POST_SCRIPT_CB) {
+			if (add_callback( &post_req_cb, f, param)<0)
+				goto add_error;
+		}
+	}
+	if (type&REQ_TYPE_CB) {
+		/* callback (also) for reply script */
+		if (type&PRE_SCRIPT_CB) {
+			if (add_callback( &pre_rpl_cb, f, param)<0)
+				goto add_error;
+		} else if (type&POST_SCRIPT_CB) {
+			if (add_callback( &post_rpl_cb, f, param)<0)
+				goto add_error;
+		}
+	}
+
+	return 0;
+add_error:
+	LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
+error:
+	return -1;
 }
 
-void destroy_script_cb()
+
+static inline void destroy_cb_list(struct script_cb **list)
 {
-	struct script_cb *cb, *foo;
+	struct script_cb *foo;
+
+	while( *list ) {
+		foo = *list;
+		*list = (*list)->next;
+		pkg_free( foo );
+	}
+}
 
-	cb=pre_cb;
-	while(cb) { foo=cb->next;pkg_free(cb);cb=foo; }
-	cb=post_cb;
-	while(cb) { foo=cb->next;pkg_free(cb);cb=foo; }
+
+void destroy_script_cb()
+{
+	destroy_cb_list( &pre_req_cb  );
+	destroy_cb_list( &post_req_cb );
+	destroy_cb_list( &pre_rpl_cb  );
+	destroy_cb_list( &post_req_cb );
 }
 
-int exec_pre_cb( struct sip_msg *msg)
+
+static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
 {
-	struct script_cb *i;
-	for (i=pre_cb; i; i=i->next) {
+	for ( ; cb ; cb=cb->next ) {
 		/* stop on error */
-		if (i->cbf(msg, i->param)==0)
+		if (cb->cbf(msg, cb->param)==0)
 			return 0;
 	}
 	return 1;
 }
 
-void exec_post_cb( struct sip_msg *msg)
+
+static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
+{
+	for ( ; cb ; cb=cb->next){
+		cb->cbf( msg, cb->param);
+	}
+	return 1;
+}
+
+
+int exec_pre_req_cb( struct sip_msg *msg)
+{
+	return exec_pre_cb( msg, pre_req_cb);
+}
+
+int exec_pre_rpl_cb( struct sip_msg *msg)
+{
+	return exec_pre_cb( msg, pre_rpl_cb);
+}
+
+int exec_post_req_cb( struct sip_msg *msg)
+{
+	return exec_post_cb( msg, post_req_cb);
+}
+
+int exec_post_rpl_cb( struct sip_msg *msg)
 {
-	struct script_cb *i;
-	for (i=post_cb; i; i=i->next) i->cbf(msg, i->param);
+	return exec_post_cb( msg, post_rpl_cb);
 }
 

+ 16 - 7
script_cb.h

@@ -23,6 +23,10 @@
  * 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
+ *
+ * History:
+ * --------
+ *  2005-02-13  script callbacks devided into request and reply types (bogdan)
  */
 
 #ifndef _SCRIPT_CB_H_
@@ -32,10 +36,11 @@
 
 typedef int (cb_function)( struct sip_msg *msg, void *param );
 
-typedef enum {
-    PRE_SCRIPT_CB,
-	POST_SCRIPT_CB
-} callback_t;       /* Allowed types of callbacks */
+
+#define PRE_SCRIPT_CB    (1<<0)
+#define POST_SCRIPT_CB   (1<<1)
+#define REQ_TYPE_CB      (1<<2)
+#define RPL_TYPE_CB      (1<<3)
 
 
 struct script_cb{
@@ -45,10 +50,14 @@ struct script_cb{
 	void *param;
 };
 
-int register_script_cb( cb_function f, callback_t t, void *param );
-int exec_pre_cb( struct sip_msg *msg);
-void exec_post_cb( struct sip_msg *msg);
+int register_script_cb( cb_function f, int type, void *param );
 void destroy_script_cb();
 
+int exec_pre_req_cb( struct sip_msg *msg);
+int exec_post_req_cb( struct sip_msg *msg);
+
+int exec_pre_rpl_cb( struct sip_msg *msg);
+int exec_post_rpl_cb( struct sip_msg *msg);
+
 #endif