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

📄 cpl_proxy.h

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * $Id: cpl_proxy.h,v 1.22.2.2 2005/06/21 17:52:13 andrei 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-07-29: file created (bogdan) * 2004-06-14: flag CPL_IS_STATEFUL is set now immediately after the  *             transaction is created (bogdan) */#include "../tm/h_table.h"#include "../../parser/contact/parse_contact.h"#define duplicate_str( _orig_ , _new_ ) \	do {\		(_new_) = (str*)shm_malloc(sizeof(str)+(_orig_)->len);\		if (!(_new_)) goto mem_error;\		(_new_)->len = (_orig_)->len;\		(_new_)->s = (char*)((_new_))+sizeof(str);\		memcpy((_new_)->s,(_orig_)->s,(_orig_)->len);\	} while(0)#define search_and_duplicate_hdr( _intr_ , _field_ , _name_ , _sfoo_ ) \	do {\		if (!(_intr_)->_field_) {\			if (!(_intr_)->msg->_field_) { \				if (parse_headers((_intr_)->msg,_name_,0)==-1) {\					LOG(L_ERR,"ERROR:run_proxy: bad %u hdr\n",_name_);\					goto runtime_error;\				} else if ( !(_intr_)->msg->_field_) {\					(_intr_)->_field_ = STR_NOT_FOUND;\				} else {\					(_sfoo_) = &((_intr_)->msg->_field_->body);\					duplicate_str( (_sfoo_) , (_intr_)->_field_ );\				}\			} else {\				(_sfoo_) = &((_intr_)->msg->_field_->body);\				duplicate_str( (_sfoo_) , (_intr_)->_field_ );\			}\		} else {\			(_sfoo_) = (_intr_)->_field_;\			duplicate_str( (_sfoo_) , (_intr_)->_field_ );\		}\	}while(0)static inline int parse_q(str *q, unsigned int *prio){	if (q->s[0]=='0')		*prio=0;	else if (q->s[0]=='1')		*prio=10;	else		goto error;	if (q->s[1]!='.')		goto error;	if (q->s[2]<'0' || q->s[2]>'9')		goto error;	*prio += q->s[2] - '0';	if (*prio>10)		goto error;	return 0;error:	LOG(L_ERR,"ERROR:cpl-c:parse_q:bad q param <%.*s>\n",q->len,q->s);	return -1;}static inline int add_contacts_to_loc_set(struct sip_msg* msg,													struct location **loc_set){	struct sip_uri uri;	struct contact *contacts;	unsigned int prio;	/* we need to have the contact header */	if (msg->contact==0) {		/* find and parse the Contact header */		if ((parse_headers(msg, HDR_CONTACT, 0)==-1) || (msg->contact==0) ) {			LOG(L_ERR,"ERROR:cpl-c:add_contacts_to_loc_set: error parsing or "				"no Contact hdr found!\n");			goto error;		}	}	/* extract from contact header the all the addresses */	if (parse_contact( msg->contact )!=0) {		LOG(L_ERR,"ERROR:cpl-c:add_contacts_to_loc_set: unable to parse "			"Contact hdr!\n");		goto error;	}	/* in contact hdr, in parsed attr, we should have a list of contacts */	if ( msg->contact->parsed ) {		contacts = ((struct contact_body*)msg->contact->parsed)->contacts;		for( ; contacts ; contacts=contacts->next) {			/* check if the contact is a valid sip uri */			if (parse_uri( contacts->uri.s, contacts->uri.len , &uri)!=0) {				continue;			}			/* convert the q param to int value (if any) */			if (contacts->q) {				if (parse_q( &(contacts->q->body), &prio )!=0)					continue;			} else {				prio = 10; /* set default to minimum */			}			/* add the uri to location set */			if (add_location( loc_set, &contacts->uri,prio, CPL_LOC_DUPL)!=0) {				LOG(L_ERR,"ERROR:cpl-c:add_contacts_to_loc_set: unable to add "				"<%.*s>\n",contacts->uri.len,contacts->uri.s);			}		}	}	return 0;error:	return -1;}static void reply_callback( struct cell* t, int type, struct tmcb_params* ps){	struct cpl_interpreter *intr = (struct cpl_interpreter*)(*(ps->param));	struct location        *loc  = 0;	int rez;	if (intr==0) {		LOG(L_WARN,"WARNING:cpl-c:reply_callback: param=0 for callback %d,"			" transaction=%p \n",type,t);		return;	}	if (type&TMCB_RESPONSE_OUT) {		/* the purpose of the final reply is to trash down the interpreter		 * structure! it's the safest place to do that, since this callback		 * it's called only once per transaction for final codes (>=200) ;-) */		if (ps->code>=200) {			DBG("DEBUG:cpl-c:final_reply: code=%d  -------------->\n"				" --------------------------> final reply received\n",			ps->code);			/* CPL interpretation done, call established -> destroy */			free_cpl_interpreter( intr );			/* set to zero the param callback*/			*(ps->param) = 0;		}		return;	} else if (!type&TMCB_ON_FAILURE) {		LOG(L_ERR,"BUG:cpl-c:reply_callback: unknown type %d\n",type);		goto exit;	}	DBG("DEBUG:cpl-c:negativ_reply: ------------------------------>\n"		" ---------------------------------> negativ reply received\n");	intr->flags |= CPL_PROXY_DONE;	intr->msg = ps->req;	/* if it's a redirect-> do I have to added to the location set ? */	if (intr->proxy.recurse && (ps->code)/100==3) {		DBG("DEBUG:cpl-c:negativ_reply: recurse level %d processing..\n",				intr->proxy.recurse);		intr->proxy.recurse--;		/* get the locations from the Contact */		add_contacts_to_loc_set( ps->rpl, &(intr->loc_set));		switch (intr->proxy.ordering) {			case SEQUENTIAL_VAL:				/* update the last_to_proxy to last location from set */				if (intr->proxy.last_to_proxy==0) {					/* the pointer went through entire old set -> set it to the					 * updated set, from the beginning  */					if (intr->loc_set==0)						/* the updated set is also empty -> proxy ended */						break;					intr->proxy.last_to_proxy = intr->loc_set;				}				while(intr->proxy.last_to_proxy->next)					intr->proxy.last_to_proxy=intr->proxy.last_to_proxy->next;				break;			case PARALLEL_VAL:				/* push the whole new location set to be proxy */				intr->proxy.last_to_proxy = intr->loc_set;				break;			case FIRSTONLY_VAL:				intr->proxy.last_to_proxy = 0;				break;		}	}	/* the current proxying failed -> do I have another location to try ?	 * This applies only for SERIAL forking or if RECURSE is set */	if (intr->proxy.last_to_proxy) {		/* continue proxying */		DBG("DEBUG:cpl-c:failed_reply: resuming proxying....\n");		switch (intr->proxy.ordering) {			case PARALLEL_VAL:				/* I get here only if I got a 3xx and RECURSE in on ->				 * forward to all location from location set */				intr->proxy.last_to_proxy = 0;				cpl_proxy_to_loc_set(intr->msg,&(intr->loc_set),intr->flags );				break;			case SEQUENTIAL_VAL:				/* place a new branch to the next location from loc. set*/				loc = remove_first_location( &(intr->loc_set) );				/*print_location_set(intr->loc_set);*/				/* update (if necessary) the last_to_proxy location  */				if (intr->proxy.last_to_proxy==loc)					intr->proxy.last_to_proxy = 0;				cpl_proxy_to_loc_set(intr->msg,&loc,intr->flags );				break;			default:				LOG(L_CRIT,"BUG:cpl_c:failed_reply: unexpected ordering found "					"when continuing proxying (%d)\n",intr->proxy.ordering);				goto exit;		}		/* nothing more to be done */		return;	} else {		/* done with proxying.... -> process the final response */		DBG("DEBUG:cpl-c:failed_reply:final_reply: got a final %d\n",ps->code);		intr->ip = 0;		if (ps->code==486 || ps->code==600) {			/* busy response */			intr->ip = intr->proxy.busy;		} else if (ps->code==408) {			/* request timeout -> no response */			intr->ip = intr->proxy.noanswer;		} else if (((ps->code)/100)==3) {			/* redirection */			/* add to the location list all the addresses from Contact */			add_contacts_to_loc_set( ps->rpl, &(intr->loc_set));			print_location_set( intr->loc_set );			intr->ip = intr->proxy.redirect;		} else {			/* generic failure */			intr->ip = intr->proxy.failure;		}		if (intr->ip==0)			intr->ip = (intr->proxy.default_)?				intr->proxy.default_:DEFAULT_ACTION;		if (intr->ip!=DEFAULT_ACTION)			intr->ip = get_first_child( intr->ip );

⌨️ 快捷键说明

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