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

📄 loose.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Route & Record-Route module, loose routing support * * $Id: loose.c,v 1.35.2.1 2005/05/31 13:48:30 janakj Exp $ * * Copyright (C) 2001-2004 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-02-28 scratchpad compatibility abandoned (jiri) * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri) */#include <string.h>#include "../../ut.h"#include "../../str.h"#include "../../dprint.h"#include "../../forward.h"#include "../../data_lump.h"#include "../../parser/parse_rr.h"#include "../../parser/parse_uri.h"#include "../../mem/mem.h"#include "../../dset.h"#include "loose.h"#include "rr_mod.h"#define RR_ERROR -1       /* An error occured while processing route set */#define RR_DRIVEN 1       /* The next hop is determined from the route set */#define NOT_RR_DRIVEN -1  /* The next hop is not determined from the route set */#define ROUTE_PREFIX "Route: <"#define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX)-1)#define ROUTE_SUFFIX ">\r\n"#define ROUTE_SUFFIX_LEN (sizeof(ROUTE_SUFFIX)-1)/* * Test whether we are processing pre-loaded route set * by looking at the To tag */static int is_preloaded(struct sip_msg* msg){	str tag;	if (!msg->to && parse_headers(msg, HDR_TO, 0) == -1) {		LOG(L_ERR, "is_preloaded: Cannot parse To header field\n");		return -1;	}	if (!msg->to) {		LOG(L_ERR, "is_preloaded: To header field not found\n");		return -1;	}	tag = get_to(msg)->tag_value;	if (tag.s == 0 || tag.len == 0) {		DBG("is_preloaded: Yes\n");		return 1;	}	DBG("is_preloaded: No\n");	return 0;}/* * Parse the message and find first occurrence of * Route header field. The function returns -1 or -2  * on a parser error, 0 if there is a Route HF and * 1 if there is no Route HF. */static inline int find_first_route(struct sip_msg* _m){	if (parse_headers(_m, HDR_ROUTE, 0) == -1) {		LOG(L_ERR, "find_first_route: Error while parsing headers\n");		return -1;	} else {		if (_m->route) {			if (parse_rr(_m->route) < 0) {				LOG(L_ERR, "find_first_route: Error while parsing Route HF\n");				return -2;			}			return 0;		} else {			DBG("find_first_route: No Route headers found\n");			return 1;		}	}}/* * Find out if a URI contains r2 parameter which indicates * that we put 2 record routes */static inline int is_2rr(str* _params){	str s;	int i, state = 0;	if (_params->len == 0) return 0;	s = *_params;	for(i = 0; i < s.len; i++) {		switch(state) {		case 0:			switch(s.s[i]) {			case ' ':			case '\r':			case '\n':			case '\t':           break;			case 'r':			case 'R': state = 1; break;			default:  state = 4; break;			}			break;		case 1:			switch(s.s[i]) {			case '2': state = 2; break;			default:  state = 4; break;			}			break;		case 2:			switch(s.s[i]) {			case ';':  return 1;			case '=':  return 1;			case ' ':			case '\r':			case '\n':			case '\t': state = 3; break;			default:   state = 4; break;			}			break;		case 3:			switch(s.s[i]) {			case ';':  return 1;			case '=':  return 1;			case ' ':			case '\r':			case '\n':			case '\t': break;			default:   state = 4; break;			}			break;		case 4:			switch(s.s[i]) {			case '\"': state = 5; break;			case ';':  state = 0; break;			default:              break;			}			break;					case 5:			switch(s.s[i]) {			case '\\': state = 6; break;			case '\"': state = 4; break;			default:              break;			}			break;		case 6: state = 5; break;		}	}		if ((state == 2) || (state == 3)) return 1;	else return 0;}/* * Check if URI is myself */#ifdef ENABLE_USER_CHECKstatic inline int is_myself(str *_user, str* _host, unsigned short _port)#elsestatic inline int is_myself(str* _host, unsigned short _port)#endif{	int ret;		ret = check_self(_host, _port ? _port : SIP_PORT, 0);/* match all protos*/	if (ret < 0) return 0;#ifdef ENABLE_USER_CHECK	if(i_user.len && i_user.len==_user->len			&& !strncmp(i_user.s, _user->s, _user->len))	{		DBG("is_myself: this URI isn't mine\n");		return -1;	}#endif		return ret;}/* * Find and parse next Route header field */static inline int find_next_route(struct sip_msg* _m, struct hdr_field** _hdr){	struct hdr_field* ptr;	ptr = (*_hdr)->next;	     /* Try to find already parsed Route headers */	while(ptr) {		if (ptr->type == HDR_ROUTE) goto found;		ptr = ptr->next;	}	     /* There are no already parsed Route headers, try to find next	      * occurrence of Route header	      */	if (parse_headers(_m, HDR_ROUTE, 1) == -1) {		LOG(L_ERR, "find_next_route: Error while parsing headers\n");		return -1;	}	if ((_m->last_header->type != HDR_ROUTE) || (_m->last_header == *_hdr)) {		DBG("find_next_route: No next Route HF found\n");		return 1;	}	ptr = _m->last_header; found:	if (parse_rr(ptr) < 0) {		LOG(L_ERR, "find_next_route: Error while parsing Route body\n");		return -2;	}	*_hdr = ptr;	return 0;}/* * Check if the given uri contains lr parameter which marks loose routers */static inline int is_strict(str* _params){	str s;	int i, state = 0;	if (_params->len == 0) return 1;	s.s = _params->s;	s.len = _params->len;	for(i = 0; i < s.len; i++) {		switch(state) {		case 0:			switch(s.s[i]) {			case ' ':			case '\r':			case '\n':			case '\t':           break;			case 'l':			case 'L': state = 1; break;			default:  state = 4; break;			}			break;		case 1:			switch(s.s[i]) {			case 'r':			case 'R': state = 2; break;			default:  state = 4; break;			}			break;		case 2:			switch(s.s[i]) {			case ';':  return 0;			case '=':  return 0;			case ' ':			case '\r':			case '\n':			case '\t': state = 3; break;			default:   state = 4; break;			}			break;		case 3:			switch(s.s[i]) {			case ';':  return 0;			case '=':  return 0;			case ' ':			case '\r':			case '\n':			case '\t': break;			default:   state = 4; break;			}			break;		case 4:			switch(s.s[i]) {			case '\"': state = 5; break;			case ';':  state = 0; break;			default:              break;			}			break;					case 5:			switch(s.s[i]) {			case '\\': state = 6; break;			case '\"': state = 4; break;			default:              break;			}			break;		case 6: state = 5; break;		}	}		if ((state == 2) || (state == 3)) return 0;	else return 1;}/* * Put Request-URI as last Route header of a SIP * message, this is necessary when forwarding to * a strict router */static inline int save_ruri(struct sip_msg* _m){	struct lump* anchor;	char *s;	int len;	     /* We must parse the whole message header here,	      * because Request-URI must be saved in last	      * Route HF in the message	      */	if (parse_headers(_m, HDR_EOH, 0) == -1) {		LOG(L_ERR, "save_ruri: Error while parsing message\n");		return -1;	}	     /* Create an anchor */	anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);	if (anchor == 0) {		LOG(L_ERR, "save_ruri: Can't get anchor\n");		return -2;	}	     /* Create buffer for new lump */	len = ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len + ROUTE_SUFFIX_LEN;	s = (char*)pkg_malloc(len);	if (!s) {		LOG(L_ERR, "save_ruri: No memory left\n");		return -3;	}	     /* Create new header field */	memcpy(s, ROUTE_PREFIX, ROUTE_PREFIX_LEN);	memcpy(s + ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len);	memcpy(s + ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len, ROUTE_SUFFIX, ROUTE_SUFFIX_LEN);	DBG("save_ruri: New header: '%.*s'\n", len, ZSW(s));	     /* Insert it */	if (insert_new_lump_before(anchor, s, len, 0) == 0) {

⌨️ 快捷键说明

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