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

📄 cpl_proxy.h

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 H
📖 第 1 页 / 共 2 页
字号:
		if( intr->ip==DEFAULT_ACTION)			rez = run_default(intr);		else			rez = cpl_run_script(intr);		switch ( rez ) {			case SCRIPT_END:				/* we don't need to free the interpreter here since it will 				 * be freed in the final_reply callback */			case SCRIPT_TO_BE_CONTINUED:				return;			case SCRIPT_RUN_ERROR:			case SCRIPT_FORMAT_ERROR:				goto exit;			default:				LOG(L_CRIT,"BUG:cpl-c:failed_reply: improper result %d\n",					rez);				goto exit;		}	}exit:	/* in case of error the default response chosen by ser at the last	 * proxying will be forwarded to the UAC */	free_cpl_interpreter( intr );	/* set to zero the param callback*/	*(ps->param) = 0;	return;}static inline char *run_proxy( struct cpl_interpreter *intr ){	unsigned short attr_name;	unsigned short n;	char *kid;	char *p;	int i;	str *s;	struct location *loc;	int_str tmp;	intr->proxy.ordering = PARALLEL_VAL;	intr->proxy.recurse = (unsigned short)cpl_env.proxy_recurse;	/* identify the attributes */	for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) {		get_basic_attr( p, attr_name, n, intr, script_error);		switch (attr_name) {			case TIMEOUT_ATTR:				if (cpl_env.timer_avp.n || cpl_env.timer_avp.s) {					tmp.n=(int)n;					if ( add_avp( cpl_env.timer_avp_type,					cpl_env.timer_avp, tmp)<0) {						LOG(L_ERR,"ERROR:run_proxy: unable to set "							"timer AVP\n");						/* continue */					}				}				break;			case RECURSE_ATTR:				switch (n) {					case NO_VAL:						intr->proxy.recurse = 0;						break;					case YES_VAL:						/* already set as default */						break;					default:						LOG(L_ERR,"ERROR:run_proxy: invalid value (%u) found"							" for attr. RECURSE in PROXY node!\n",n);						goto script_error;				}				break;			case ORDERING_ATTR:				if (n!=PARALLEL_VAL && n!=SEQUENTIAL_VAL && n!=FIRSTONLY_VAL){					LOG(L_ERR,"ERROR:run_proxy: invalid value (%u) found"						" for attr. ORDERING in PROXY node!\n",n);					goto script_error;				}				intr->proxy.ordering = n;				break;			default:				LOG(L_ERR,"ERROR:run_proxy: unknown attribute (%d) in"					"PROXY node\n",attr_name);				goto script_error;		}	}	intr->proxy.busy = intr->proxy.noanswer = 0;	intr->proxy.redirect = intr->proxy.failure = intr->proxy.default_ = 0;	/* this is quite an "expensive" node to run, so let's make some checking	 * before getting deeply into it */	for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) {		kid = intr->ip + KID_OFFSET(intr->ip,i);		check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error);		switch ( NODE_TYPE(kid) ) {			case BUSY_NODE :				intr->proxy.busy = kid;				break;			case NOANSWER_NODE:				intr->proxy.noanswer = kid;				break;			case REDIRECTION_NODE:				intr->proxy.redirect = kid;				break;			case FAILURE_NODE:				intr->proxy.failure = kid;				break;			case DEFAULT_NODE:				intr->proxy.default_ = kid;				break;			default:				LOG(L_ERR,"ERROR:run_proxy: unknown output node type"					" (%d) for PROXY node\n",NODE_TYPE(kid));				goto script_error;		}	}	/* if the location set if empty, I will go directly on failure/default */	if (intr->loc_set==0) {		DBG("DEBUG:run_proxy: location set found empty -> going on "			"failure/default branch\n");			if (intr->proxy.failure)				return get_first_child(intr->proxy.failure);			else if (intr->proxy.default_)				return get_first_child(intr->proxy.default_);			else return DEFAULT_ACTION;	}	/* if it's the first execution of a proxy node, force parsing of the needed	 * headers and duplicate them in shared memory */	if (!(intr->flags&CPL_PROXY_DONE)) {		/* user name is already in shared memory */		/* requested URI - mandatory in SIP msg (cannot be STR_NOT_FOUND) */		s = GET_RURI( intr->msg );		duplicate_str( s , intr->ruri );		intr->flags |= CPL_RURI_DUPLICATED;		/* TO header - mandatory in SIP msg (cannot be STR_NOT_FOUND) */		if (!intr->to) {			if (!intr->msg->to &&			(parse_headers(intr->msg,HDR_TO,0)==-1 || !intr->msg->to)) {				LOG(L_ERR,"ERROR:run_proxy: bad msg or missing TO header\n");				goto runtime_error;			}			s = &(get_to(intr->msg)->uri);		} else {			s = intr->to;		}		duplicate_str( s , intr->to );		intr->flags |= CPL_TO_DUPLICATED;		/* FROM header - mandatory in SIP msg (cannot be STR_NOT_FOUND) */		if (!intr->from) {			if (parse_from_header( intr->msg )==-1)				goto runtime_error;			s = &(get_from(intr->msg)->uri);		} else {			s = intr->from;		}		duplicate_str( s , intr->from );		intr->flags |= CPL_FROM_DUPLICATED;		/* SUBJECT header - optional in SIP msg (can be STR_NOT_FOUND) */		if (intr->subject!=STR_NOT_FOUND) {			search_and_duplicate_hdr(intr,subject,HDR_SUBJECT,s);			if (intr->subject!=STR_NOT_FOUND)				intr->flags |= CPL_SUBJECT_DUPLICATED;		}		/* ORGANIZATION header - optional in SIP msg (can be STR_NOT_FOUND) */		if ( intr->organization!=STR_NOT_FOUND) {			search_and_duplicate_hdr(intr,organization,HDR_ORGANIZATION,s);			if ( intr->organization!=STR_NOT_FOUND)				intr->flags |= CPL_ORGANIZATION_DUPLICATED;		}		/* USER_AGENT header - optional in SIP msg (can be STR_NOT_FOUND) */		if (intr->user_agent!=STR_NOT_FOUND) {			search_and_duplicate_hdr(intr,user_agent,HDR_USERAGENT,s);			if (intr->user_agent!=STR_NOT_FOUND)				intr->flags |= CPL_USERAGENT_DUPLICATED;		}		/* ACCEPT_LANGUAGE header - optional in SIP msg		 * (can be STR_NOT_FOUND) */		if (intr->accept_language!=STR_NOT_FOUND) {			search_and_duplicate_hdr(intr,accept_language,				HDR_ACCEPTLANGUAGE,s);			if (intr->accept_language!=STR_NOT_FOUND)				intr->flags |= CPL_ACCEPTLANG_DUPLICATED;		}		/* PRIORITY header - optional in SIP msg (can be STR_NOT_FOUND) */		if (intr->priority!=STR_NOT_FOUND) {			search_and_duplicate_hdr(intr,priority,HDR_PRIORITY,s);			if (intr->priority!=STR_NOT_FOUND)				intr->flags |= CPL_PRIORITY_DUPLICATED;		}		/* now is the first time doing proxy, so I can still be stateless;		 * as proxy is done all the time stateful, I have to switch from		 * stateless to stateful if necessary.  */		if ( !(intr->flags&CPL_IS_STATEFUL) ) {			i = cpl_fct.tmb.t_newtran( intr->msg );			if (i<0) {				LOG(L_ERR,"ERROR:cpl-c:run_proxy: failed to build new "					"transaction!\n");				goto runtime_error;			} else if (i==0) {				LOG(L_ERR,"ERROR:cpl-c:run_proxy: processed INVITE is a "					"retransmission!\n");				/* instead of generating an error is better just to break the				 * script by returning EO_SCRIPT */				return EO_SCRIPT;			}			intr->flags |= CPL_IS_STATEFUL;		}		/* as I am interested in getting the responses back - I need to install		 * some callback functions for replies  */		if (cpl_fct.tmb.register_tmcb(intr->msg,0,		TMCB_ON_FAILURE|TMCB_RESPONSE_OUT,reply_callback,(void*)intr) <= 0 ) {			LOG(L_ERR, "ERROR:cpl_c:run_proxy: failed to register "				"TMCB_RESPONSE_OUT callback\n");			goto runtime_error;		}	}	switch (intr->proxy.ordering) {		case FIRSTONLY_VAL:			/* forward the request only to the first address from loc. set */			/* location set cannot be empty -> was checked before */			loc = remove_first_location( &(intr->loc_set) );			intr->proxy.last_to_proxy = 0;			/* set the new ip before proxy -> otherwise race cond with rpls */			intr->ip = CPL_TO_CONTINUE;			if (cpl_proxy_to_loc_set(intr->msg,&loc,intr->flags )==-1)				goto runtime_error;			break;		case PARALLEL_VAL:			/* forward to all location from location set */			intr->proxy.last_to_proxy = 0;			/* set the new ip before proxy -> otherwise race cond with rpls */			intr->ip = CPL_TO_CONTINUE;			if (cpl_proxy_to_loc_set(intr->msg,&(intr->loc_set),intr->flags)			==-1)				goto runtime_error;			break;		case SEQUENTIAL_VAL:			/* forward the request one at the time to all addresses from			 * loc. set; location set cannot be empty -> was checked before */			/* use the first location from set */			loc = remove_first_location( &(intr->loc_set) );			/* set as the last_to_proxy the last location from set */			intr->proxy.last_to_proxy = intr->loc_set;			while (intr->proxy.last_to_proxy&&intr->proxy.last_to_proxy->next)				intr->proxy.last_to_proxy = intr->proxy.last_to_proxy->next;			/* set the new ip before proxy -> otherwise race cond with rpls */			intr->ip = CPL_TO_CONTINUE;			if (cpl_proxy_to_loc_set(intr->msg,&loc,intr->flags)==-1)				goto runtime_error;			break;	}	return CPL_TO_CONTINUE;script_error:	return CPL_SCRIPT_ERROR;mem_error:	LOG(L_ERR,"ERROR:run_proxy: no more free shm memory\n");runtime_error:	return CPL_RUNTIME_ERROR;}

⌨️ 快捷键说明

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