Browse Source

- dst blacklist measurements added

Gergely Kovacs 18 năm trước cách đây
mục cha
commit
5744b6f8e6
2 tập tin đã thay đổi với 140 bổ sung33 xóa
  1. 133 31
      dst_blacklist.c
  2. 7 2
      dst_blacklist.h

+ 133 - 31
dst_blacklist.c

@@ -22,8 +22,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
+ * 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:
@@ -32,6 +32,7 @@
  *  2007-05-39  added hooks for add; more locks to reduce contention (andrei)
  *  2007-06-26  added hooks for search (andrei)
  *  2007-07-30  added dst_blacklist_del() and dst_blacklist_add_to()  (andrei)
+ *  2007-07-30  dst blacklist measurements added (Gergo)
  */
 
 
@@ -48,6 +49,9 @@
 #include "rpc.h"
 #include "compiler_opt.h"
 #include "resolve.h" /* for str2ip */
+#ifdef USE_DST_BLACKLIST_STATS
+#include "pt.h"
+#endif
 
 
 
@@ -58,7 +62,7 @@ struct dst_blst_entry{
 	unsigned short port;
 	unsigned char proto;
 	unsigned char flags; /* contains the address type + error flags */
-	unsigned char ip[4]; /* 4 for ipv4, 16 for ipv6 */ 
+	unsigned char ip[4]; /* 4 for ipv4, 16 for ipv6 */
 };
 
 #define DST_BLST_ENTRY_SIZE(b) \
@@ -127,7 +131,9 @@ unsigned int blst_timeout=DEFAULT_BLST_TIMEOUT;
 unsigned int blst_timer_interval=DEFAULT_BLST_TIMER_INTERVAL;
 struct dst_blst_lst_head* dst_blst_hash=0;
 
-
+#ifdef USE_DST_BLACKLIST_STATS
+struct t_dst_blacklist_stats* dst_blacklist_stats=0;
+#endif
 
 #ifdef DST_BLACKLIST_HOOKS
 
@@ -221,7 +227,7 @@ int register_blacklist_hook(struct blacklist_hook *h, int type)
 	struct blst_callbacks_lst* cb_lst;
 	struct blacklist_hook* tmp;
 	int new_max_hooks;
-	
+
 	switch(type){
 		case DST_BLACKLIST_ADD_CB:
 			cb_lst=&blst_add_cb;
@@ -240,15 +246,15 @@ int register_blacklist_hook(struct blacklist_hook *h, int type)
 
 	if (cb_lst->last_idx >= cb_lst->max_hooks){
 		new_max_hooks=2*cb_lst->max_hooks;
-		tmp=pkg_realloc(cb_lst->hooks, 
+		tmp=pkg_realloc(cb_lst->hooks,
 				new_max_hooks*sizeof(struct blacklist_hook));
 		if (tmp==0){
 			goto error;
 		}
 		cb_lst->hooks=tmp;
-		/* init the new chunk (but not the current entry which is 
+		/* init the new chunk (but not the current entry which is
 		 * overwritten anyway) */
-		memset(&cb_lst->hooks[cb_lst->max_hooks+1], 0, 
+		memset(&cb_lst->hooks[cb_lst->max_hooks+1], 0,
 					(new_max_hooks-cb_lst->max_hooks-1)*
 						sizeof(struct blacklist_hook));
 		cb_lst->max_hooks=new_max_hooks;
@@ -267,8 +273,8 @@ inline static int blacklist_run_hooks(struct blst_callbacks_lst *cb_lst,
 {
 	int r;
 	int ret;
-	
-	ret=DST_BLACKLIST_CONTINUE; /* default, if no hook installed accept 
+
+	ret=DST_BLACKLIST_CONTINUE; /* default, if no hook installed accept
 								blacklist operation */
 	if (likely(cb_lst->last_idx==0))
 		return ret;
@@ -313,7 +319,7 @@ inline static unsigned short dst_blst_hash_no(unsigned char proto,
 {
 	str s1;
 	str s2;
-	
+
 	s1.s=(char*)ip->u.addr;
 	s1.len=ip->len;
 	s2.s=(char*)&port;
@@ -329,7 +335,7 @@ void destroy_dst_blacklist()
 	struct dst_blst_entry** crt;
 	struct dst_blst_entry** tmp;
 	struct dst_blst_entry* e;
-	
+
 	if (blst_timer_h){
 		timer_del(blst_timer_h);
 		timer_free(blst_timer_h);
@@ -351,10 +357,10 @@ void destroy_dst_blacklist()
 		blst_lock=0;
 	}
 #endif
-	
+
 	if (dst_blst_hash){
 		for(r=0; r<DST_BLST_HASH_SIZE; r++){
-			for (crt=&dst_blst_hash[r].first, tmp=&(*crt)->next; *crt; 
+			for (crt=&dst_blst_hash[r].first, tmp=&(*crt)->next; *crt;
 					crt=tmp, tmp=&(*crt)->next){
 			e=*crt;
 			*crt=(*crt)->next;
@@ -371,6 +377,11 @@ void destroy_dst_blacklist()
 #ifdef DST_BLACKLIST_HOOKS
 	destroy_blacklist_hooks();
 #endif
+
+#ifdef USE_DST_BLACKLIST_STATS
+	if (dst_blacklist_stats)
+		shm_free(dst_blacklist_stats);
+#endif
 }
 
 
@@ -381,7 +392,7 @@ int init_dst_blacklist()
 #ifdef BLST_LOCK_PER_BUCKET
 	int r;
 #endif
-	
+
 	ret=-1;
 #ifdef DST_BLACKLIST_HOOKS
 	if (init_blacklist_hooks()!=0){
@@ -457,6 +468,22 @@ error:
 	return ret;
 }
 
+#ifdef USE_DST_BLACKLIST_STATS
+int init_dst_blacklist_stats(int iproc_num)
+{
+	/* if it is already initialized */
+	if (dst_blacklist_stats)
+		shm_free(dst_blacklist_stats);
+
+	dst_blacklist_stats=shm_malloc(sizeof(*dst_blacklist_stats) * iproc_num);
+	if (dst_blacklist_stats==0){
+		return E_OUT_OF_MEM;
+	}
+	memset(dst_blacklist_stats, 0, sizeof(*dst_blacklist_stats) * iproc_num);
+
+	return 0;
+}
+#endif
 
 /* must be called with the lock held
  * struct dst_blst_entry** head, struct dst_blst_entry* e */
@@ -484,7 +511,7 @@ inline static struct dst_blst_entry* _dst_blacklist_lst_find(
 	struct dst_blst_entry* e;
 	struct dst_blst_entry** head;
 	unsigned char type;
-	
+
 	head=&dst_blst_hash[hash].first;
 	type=(ip->af==AF_INET6)*BLST_IS_IPV6;
 	for (crt=head, tmp=&(*head)->next; *crt; crt=tmp, tmp=&(*crt)->next){
@@ -498,7 +525,7 @@ inline static struct dst_blst_entry* _dst_blacklist_lst_find(
 			blst_destroy_entry(e);
 		}else if ((e->port==port) && ((e->flags & BLST_IS_IPV6)==type) &&
 				((e->proto==PROTO_NONE) || (proto==PROTO_NONE) ||
-					(e->proto==proto)) && 
+					(e->proto==proto)) &&
 					(memcmp(ip->u.addr, e->ip, ip->len)==0)){
 			return e;
 		}
@@ -553,9 +580,9 @@ inline static int _dst_blacklist_del(
 
 
 /* frees all the expired entries until either there are no more of them
- *  or the total memory used is <= target (to free all of them use -1 for 
+ *  or the total memory used is <= target (to free all of them use -1 for
  *  targer)
- *  params:   target  - free expired entries until no more then taget memory 
+ *  params:   target  - free expired entries until no more then taget memory
  *                      is used  (use 0 to free all of them)
  *            delta   - consider an entry expired if it expires after delta
  *                      ticks from now
@@ -577,7 +604,7 @@ inline static int dst_blacklist_clean_expired(unsigned int target,
 	ticks_t now;
 	int no=0;
 	int i;
-	
+
 	now=start_time=get_ticks_raw();
 	for(h=start; h!=(start+DST_BLST_HASH_SIZE); h++){
 		i=h%DST_BLST_HASH_SIZE;
@@ -632,7 +659,7 @@ static ticks_t blst_timer(ticks_t ticks, struct timer_ln* tl, void* data)
  * returns 0 on success, -1 on error (blacklist full -- would use more then
  *  blst:_max_mem, or out of shm. mem.)
  */
-inline static int dst_blacklist_add_ip(unsigned char err_flags, 
+inline static int dst_blacklist_add_ip(unsigned char err_flags,
 									unsigned char proto,
 									struct ip_addr* ip, unsigned short port,
 									ticks_t timeout)
@@ -642,7 +669,7 @@ inline static int dst_blacklist_add_ip(unsigned char err_flags,
 	unsigned short hash;
 	ticks_t now;
 	int ret;
-	
+
 	ret=0;
 	if (ip->af==AF_INET){
 		err_flags&=~BLST_IS_IPV6; /* make sure the ipv6 flag is reset */
@@ -661,10 +688,13 @@ inline static int dst_blacklist_add_ip(unsigned char err_flags,
 			e->expire=now+timeout; /* update the timeout */
 		}else{
 			if (unlikely((*blst_mem_used+size)>=blst_max_mem)){
+#ifdef USE_DST_BLACKLIST_STATS
+				dst_blacklist_stats[process_no].bkl_lru_cnt++;
+#endif
 				UNLOCK_BLST(hash);
 				/* first try to free some memory  (~ 12%), but don't
 				 * spend more then 250 ms*/
-				dst_blacklist_clean_expired(*blst_mem_used/16*14, 0, 
+				dst_blacklist_clean_expired(*blst_mem_used/16*14, 0,
 															MS_TO_TICKS(250));
 				if (unlikely(*blst_mem_used+size>=blst_max_mem)){
 					ret=-1;
@@ -704,7 +734,7 @@ inline static int dst_is_blacklisted_ip(unsigned char proto,
 	unsigned short hash;
 	ticks_t now;
 	int ret;
-	
+
 	ret=0;
 	now=get_ticks_raw();
 	hash=dst_blst_hash_no(proto, ip, port);
@@ -726,6 +756,9 @@ int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
 {
 	struct ip_addr ip;
 
+#ifdef USE_DST_BLACKLIST_STATS
+	dst_blacklist_stats[process_no].bkl_hit_cnt++;
+#endif
 #ifdef DST_BLACKLIST_HOOKS
 	if (unlikely (blacklist_run_hooks(&blst_add_cb, si, &err_flags, msg) ==
 					DST_BLACKLIST_DENY))
@@ -740,6 +773,7 @@ int dst_blacklist_add_to(unsigned char err_flags,  struct dest_info* si,
 
 int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg)
 {
+	int ires;
 	struct ip_addr ip;
 #ifdef DST_BLACKLIST_HOOKS
 	unsigned char err_flags;
@@ -757,7 +791,12 @@ int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg)
 			return err_flags;
 	}
 #endif
-	return dst_is_blacklisted_ip(si->proto, &ip, su_getport(&si->to));
+	ires=dst_is_blacklisted_ip(si->proto, &ip, su_getport(&si->to));
+#ifdef USE_DST_BLACKLIST_STATS
+	if (ires)
+		dst_blacklist_stats[process_no].bkl_hit_cnt++;
+#endif
+	return ires;
 }
 
 
@@ -811,6 +850,69 @@ static char* get_proto_name(unsigned char proto)
 }
 
 
+#ifdef USE_DST_BLACKLIST_STATS
+void dst_blst_stats_get(rpc_t* rpc, void* c)
+{
+	char *name=NULL;
+	void *handle;
+	int found=0,i=0;
+	int reset=0;
+	char* dst_blacklist_stats_names[] = {
+		"bkl_hit_cnt",
+		"bkl_lru_cnt",
+		NULL
+	};
+	unsigned long  stat_sum(int ivar, int breset) {
+		unsigned long isum=0;
+		int i1=0;
+
+		for (; i1 < get_max_procs(); i1++)
+			switch (ivar) {
+				case 0:
+					isum+=dst_blacklist_stats[i1].bkl_hit_cnt;
+					if (breset)
+						dst_blacklist_stats[i1].bkl_hit_cnt=0;
+					break;
+				case 1:
+					isum+=dst_blacklist_stats[i1].bkl_lru_cnt;
+					if (breset)
+						dst_blacklist_stats[i1].bkl_lru_cnt=0;
+					break;
+			}
+
+			return isum;
+	}
+
+	if (rpc->scan(c, "s", &name) < 0)
+		return;
+	if (rpc->scan(c, "d", &reset) < 0)
+		return;
+	if (!strcasecmp(name, DST_BLACKLIST_ALL_STATS)) {
+		/* dump all the dns cache stat values */
+		rpc->add(c, "{", &handle);
+		for (i=0; dst_blacklist_stats_names[i]; i++)
+			rpc->struct_add(handle, "d",
+							dst_blacklist_stats_names[i],
+							stat_sum(i, reset));
+
+		found=1;
+	} else {
+		for (i=0; dst_blacklist_stats_names[i]; i++)
+			if (!strcasecmp(dst_blacklist_stats_names[i], name)) {
+			rpc->add(c, "{", &handle);
+			rpc->struct_add(handle, "d",
+							dst_blacklist_stats_names[i],
+							stat_sum(i, reset));
+			found=1;
+			break;
+			}
+	}
+	if(!found)
+		rpc->fault(c, 500, "unknown dst blacklist stat parameter");
+
+	return;
+}
+#endif /* USE_DST_BLACKLIST_STATS */
 
 /* only for debugging, it helds the lock too long for "production" use */
 void dst_blst_debug(rpc_t* rpc, void* ctx)
@@ -819,14 +921,14 @@ void dst_blst_debug(rpc_t* rpc, void* ctx)
 	struct dst_blst_entry* e;
 	ticks_t now;
 	struct ip_addr ip;
-	
+
 	now=get_ticks_raw();
 		for(h=0; h<DST_BLST_HASH_SIZE; h++){
 			LOCK_BLST(h);
 			for(e=dst_blst_hash[h].first; e; e=e->next){
 				dst_blst_entry2ip(&ip, e);
-				rpc->add(ctx, "ssddd", get_proto_name(e->proto), 
-										ip_addr2a(&ip), e->port, 
+				rpc->add(ctx, "ssddd", get_proto_name(e->proto),
+										ip_addr2a(&ip), e->port,
 										(s_ticks_t)(now-e->expire)<=0?
 										TICKS_TO_S(e->expire-now):
 										-TICKS_TO_S(now-e->expire) ,
@@ -843,10 +945,10 @@ void dst_blst_hash_stats(rpc_t* rpc, void* ctx)
 	struct dst_blst_entry* e;
 #ifdef BLST_HASH_STATS
 	int n;
-	
+
 	n=0;
 #endif
-	
+
 		for(h=0; h<DST_BLST_HASH_SIZE; h++){
 #ifdef BLST_HASH_STATS
 			LOCK_BLST(h);
@@ -867,7 +969,7 @@ void dst_blst_view(rpc_t* rpc, void* ctx)
 	ticks_t now;
 	struct ip_addr ip;
 	void* handle;
-	
+
 	now=get_ticks_raw();
 		for(h=0; h<DST_BLST_HASH_SIZE; h++){
 			LOCK_BLST(h);

+ 7 - 2
dst_blacklist.h

@@ -22,13 +22,14 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
+ * 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:
  * --------
  *  2006-07-29  created by andrei
+ *  2007-07-30  dst blacklist measurements added (Gergo)
  */
 
 #ifndef dst_black_list_h
@@ -75,6 +76,10 @@ int register_blacklist_hook(struct blacklist_hook *h, int type);
 #endif /* DST_BLACKLIST_HOOKS */
 
 int init_dst_blacklist();
+#ifdef USE_DST_BLACKLIST_STATS
+int init_dst_blacklist_stats(int iproc_num);
+#define DST_BLACKLIST_ALL_STATS "bkl_all_stats"
+#endif
 void destroy_dst_blacklist();