⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pike_funcs.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/*  * $Id: pike_funcs.c,v 1.23 2004/11/05 14:21:00 bogdan Exp $ * * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * 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  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* History: * -------- *  2003-03-11  converted to the new locking interface: locking.h -- *               major changes (andrei) */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include "../../mem/shm_mem.h"#include "../../locking.h"#include "../../timer.h"#include "../../ip_addr.h"#include "../../resolve.h"#include "ip_tree.h"#include "pike_funcs.h"#include "timer.h"extern gen_lock_t*       timer_lock;extern struct list_link* timer;extern int               timeout;void print_timer_list(struct list_link *head){	struct list_link *ll;	DBG("DEBUG:pike:print_timer_list --->\n");	for ( ll=head->next ; ll!=head; ll=ll->next) {		DBG("\t %p [byte=%x](expires=%d)\n",			ll, ll2ipnode(ll)->byte, ll2ipnode(ll)->expires);	}}#define _testint pike_check_req(struct sip_msg *msg, char *foo, char *bar){	struct ip_node *node;	struct ip_node *father;	unsigned char flags;	struct ip_addr* ip;#ifdef _test	/* get the ip address from second via */	if (parse_headers(msg, HDR_VIA1, 0)!=0 )		return -1;	if (msg->via1==0 )		return -1;	/* convert from string to ip_addr */	ip = str2ip( &msg->via1->host );	if (ip==0)		return -1;#else	ip = &(msg->rcv.src_ip);#endif	/* first lock the proper tree branch and mark the IP with one more hit*/	lock_tree_branch( ip->u.addr[0] );	node = mark_node( ip->u.addr, ip->len, &father, &flags);	if (node==0) {		/* even if this is an error case, we return true in script to avoid		 * considering the IP as marked (bogdan) */		return 1;	}	DBG("DEBUG:pike_check_req: src IP [%s]; hits=[%d,%d],[%d,%d] flags=%d\n",		ip_addr2a( ip ),		node->hits[PREV_POS],node->hits[CURR_POS],		node->leaf_hits[PREV_POS],node->leaf_hits[CURR_POS], flags);	/* update the timer */	lock_get(timer_lock);	if ( flags&NEW_NODE ) {		/* put this node into the timer list and remove its		   father only if this has one kid and is not a LEAF_NODE*/		node->expires =  get_ticks() + timeout;		append_to_timer( timer, &(node->timer_ll) );		if (father)		DBG("DEBUG:pike_check_req: father: leaf_hits=%d kids->next=%p\n",			father->leaf_hits[CURR_POS],father->kids->next);		if (father && father->leaf_hits[CURR_POS]==0 && father->kids->next==0){			assert( has_timer_set(&(father->timer_ll)) ); /* debug */			remove_from_timer( timer, &(father->timer_ll) );		}	} else {		/* update the timer -> in timer can be only nodes		 * as IP-leaf(complete address) or tree-leaf */		if (node->leaf_hits[CURR_POS] || node->kids==0) {			/* tree leafs which are not potential red nodes are not update in			 * order to make them to expire */			assert( has_timer_set(&(node->timer_ll)) ); /* debug */			if ( !(flags&NO_UPDATE) ) {				node->expires = get_ticks() + timeout;				update_in_timer( timer, &(node->timer_ll) );			}		} else {			assert( !has_timer_set(&(node->timer_ll)) ); /* debug */			assert( node->hits[CURR_POS] && node->kids ); /* debug */		}	}	/*print_timer_list( timer );*/ /* debug*/	lock_release(timer_lock);	unlock_tree_branch( ip->u.addr[0] );	/*print_tree( 0 );*/ /* debug */	if (flags&RED_NODE) {		LOG(L_WARN,"DEBUG:pike_check_req: ALARM - TOO MANY HITS on "			"%s !!\n", ip_addr2a( ip ) );		return -1;	}	return 1;}void clean_routine(unsigned int ticks , void *param){	static unsigned char mask[32];  /* 256 positions mask */	struct list_link head;	struct list_link *ll;	struct ip_node   *dad;	struct ip_node   *node;	int i;	/* DBG("DEBUG:pike:clean_routine:  entering (%d)\n",ticks); */	/* before locking check first if the list is not empty and if can	 * be at least one element removed */	if ( is_list_empty( timer ) || ll2ipnode(timer->next)->expires>ticks )		return;	/* get the expired elements */	lock_get( timer_lock );	check_and_split_timer( timer, ticks, &head, mask);	/*print_timer_list(timer);*/ /* debug */	lock_release( timer_lock );	/*print_tree( 0 );*/  /*debug*/	/* got something back? */	if ( is_list_empty(&head) )		return;	/* process what we got -> don't forget to lock the tree!! */	for(i=0;i<MAX_IP_BRANCHES;i++) {		/* if no element from this branch -> skip it */		if ( ((mask[i>>3])&(1<<(i&0x07)))==0 )			continue;		lock_tree_branch( i );		for( ll=head.next ; ll!=&head ; ) {			node = ll2ipnode( ll );			ll = ll->next;			/* skip nodes from a different branch */			if (node->branch!=i)				continue;			/* unlink the node -> the list will get shorter and it will be			 * faster for the next branches to process it */			ll->prev->prev->next = ll;			ll->prev = ll->prev->prev;			node->expires = 0;			node->timer_ll.prev = node->timer_ll.next = 0;			/* process the node */			DBG("DEBUG:pike:clean_routine: clean node %p (kids=%p;"				"hits=[%d,%d];leaf=[%d,%d])\n", node,node->kids,				node->hits[PREV_POS],node->hits[CURR_POS],				node->leaf_hits[PREV_POS],node->leaf_hits[CURR_POS]);			/* if it's a node, leaf for an ipv4 address inside an			 * ipv6 address -> just remove it from timer it will be deleted			 * only when all its kids will be deleted also */			if (node->kids) {				assert( node->leaf_hits[CURR_POS] );				node->leaf_hits[CURR_POS] = 0;			} else {				/* if the node has no prev, means its a top branch node -> just				 * removed and destroy it */				if (node->prev!=0) {					/* if this is the last kid, we have to put the father					 * into timer list */					if (node->prev->kids==node && node->next==0) {						/* this is the last kid node */						dad = node->prev;						/* put it in the list only if it's not an IP leaf						 * (in this case, it's already there) */						if (dad->leaf_hits[CURR_POS]==0) {							lock_get(timer_lock);							dad->expires = get_ticks() + timeout;							assert( !has_timer_set(&(dad->timer_ll)) );							append_to_timer( timer, &(dad->timer_ll));							lock_release(timer_lock);						} else {							assert( has_timer_set(&(dad->timer_ll)) );						}					}				}				DBG("DEBUG:pike:clean_routine: rmv node %p[%d] \n",					node,node->byte);				/* del the node */				remove_node( node);			}		} /* for all expired elements */		unlock_tree_branch( i );	} /* for all branches */}void refresh_node( struct ip_node *node){	for( ; node ; node=node->next ) {		node->hits[PREV_POS] = node->hits[CURR_POS];		node->hits[CURR_POS] = 0;		node->leaf_hits[PREV_POS] = node->leaf_hits[CURR_POS];		node->leaf_hits[CURR_POS] = 0;		if (node->kids)			refresh_node( node->kids );	}}void swap_routine( unsigned int ticks, void *param){	struct ip_node *node;	int i;	/* DBG("DEBUG:pike:swap_routine:  entering \n"); */	for(i=0;i<MAX_IP_BRANCHES;i++) {		node = get_tree_branch(i);		if (node) {			lock_tree_branch( i );			refresh_node( node );			unlock_tree_branch( i );		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -