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

📄 record.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: record.c,v 1.14 2004/08/24 09:00:38 janakj Exp $ * * Route & Record-Route module * * 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-04-04 Extracted from common.[ch] (janakj) */#include <string.h>#include "../../mem/mem.h"#include "../../dprint.h"#include "../../parser/parse_uri.h"#include "../../parser/parse_from.h"#include "../../str.h"#include "../../data_lump.h"#include "record.h"#include "rr_mod.h"#define RR_PREFIX "Record-Route: <sip:"#define RR_PREFIX_LEN (sizeof(RR_PREFIX)-1)#define RR_LR_TERM ";lr>"#define RR_LR_TERM_LEN (sizeof(RR_LR_TERM)-1)#define RR_LR_FULL_TERM ";lr=on>"#define RR_LR_FULL_TERM_LEN (sizeof(RR_LR_FULL_TERM)-1)#define RR_SR_TERM ">"#define RR_SR_TERM_LEN (sizeof(RR_SR_TERM)-1)#define RR_FROMTAG ";ftag="#define RR_FROMTAG_LEN (sizeof(RR_FROMTAG)-1)#define RR_R2 ";r2=on"#define RR_R2_LEN (sizeof(RR_R2)-1)#define INBOUND  1  /* Insert inbound Record-Route */#define OUTBOUND 0  /* Insert outbound Record-Route *//* * Extract username from the Request URI * First try to look at the original Request URI and if there * is no username use the new Request URI */static inline int get_username(struct sip_msg* _m, str* _user){	struct sip_uri puri;	     /* first try to look at r-uri for a username */	if (parse_uri(_m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len, &puri) < 0) {		LOG(L_ERR, "get_username(): Error while parsing R-URI\n");		return -1;	}	/* no username in original uri -- hmm; maybe it is a uri	 * with just host address and username is in a preloaded route,	 * which is now no rewritten r-uri (assumed rewriteFromRoute	 * was called somewhere in script's beginning) 	 */	if (!puri.user.len && _m->new_uri.s) {		if (parse_uri(_m->new_uri.s, _m->new_uri.len, &puri) < 0) {			LOG(L_ERR, "get_username(): Error while parsing new_uri\n");			return -2;	        }	}	_user->s = puri.user.s;	_user->len = puri.user.len;	return 0;}/* * build a Record-Route header field */static inline int build_rr(struct lump* _l, struct lump* _l2, int _lr, str* user, str* tag, int _inbound){	char* prefix, *suffix, *crlf, *r2;	int suffix_len, prefix_len;	prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0);	prefix = pkg_malloc(prefix_len);	if (enable_full_lr) {		suffix_len = (_lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN) + 				((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);	} else {		suffix_len = (_lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN) + 				((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);	}	suffix = pkg_malloc(suffix_len);		crlf = pkg_malloc(2);	r2 = pkg_malloc(RR_R2_LEN);	if (!prefix || !suffix || !crlf || !r2) {		LOG(L_ERR, "build_rr(): No memory left\n");		if (suffix) pkg_free(suffix);		if (prefix) pkg_free(prefix);		if (crlf) pkg_free(crlf);		if (r2) pkg_free(r2);		return -3;	}		memcpy(prefix, RR_PREFIX, RR_PREFIX_LEN);	if (user->len) {		memcpy(prefix + RR_PREFIX_LEN, user->s, user->len);#ifdef ENABLE_USER_CHECK		/* don't add the ignored user into a RR */		if(i_user.len && i_user.len == user->len && 				!strncmp(i_user.s, user->s, i_user.len))		{			if(prefix[RR_PREFIX_LEN]=='x')				prefix[RR_PREFIX_LEN]='y';			else				prefix[RR_PREFIX_LEN]='x';		}#endif		prefix[RR_PREFIX_LEN + user->len] = '@';	}		if (tag && tag->len) {		memcpy(suffix, RR_FROMTAG, RR_FROMTAG_LEN);		memcpy(suffix + RR_FROMTAG_LEN, tag->s, tag->len);		if (enable_full_lr) {			memcpy(suffix + RR_FROMTAG_LEN + tag->len, _lr ? RR_LR_FULL_TERM : RR_SR_TERM, _lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN);		} else {			memcpy(suffix + RR_FROMTAG_LEN + tag->len, _lr ? RR_LR_TERM : RR_SR_TERM, _lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN);		}	} else {		if (enable_full_lr) {			memcpy(suffix, _lr ? RR_LR_FULL_TERM : RR_SR_TERM, _lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN);		} else {			memcpy(suffix, _lr ? RR_LR_TERM : RR_SR_TERM, _lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN);		}	}		memcpy(crlf, CRLF, 2);	memcpy(r2, RR_R2, RR_R2_LEN);	if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0))) goto lump_err;	prefix = 0;	if (!(_l = insert_subst_lump_after(_l, _inbound ? SUBST_RCV_ALL : SUBST_SND_ALL, 0))) goto lump_err;	if (enable_double_rr) {		if (!(_l = insert_cond_lump_after(_l, COND_IF_DIFF_REALMS, 0))) goto lump_err;		if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0))) goto lump_err;		r2 = 0;	} else {		pkg_free(r2);		r2 = 0;	}	if (!(_l2 = insert_new_lump_before(_l2, suffix, suffix_len, 0))) goto lump_err;	suffix = 0;	if (!(_l2 = insert_new_lump_before(_l2, crlf, 2, 0))) goto lump_err;	crlf = 0;	return 0;	 lump_err:	LOG(L_ERR, "build_rr(): Error while inserting lumps\n");	if (prefix) pkg_free(prefix);	if (suffix) pkg_free(suffix);	if (r2) pkg_free(r2);	if (crlf) pkg_free(crlf);	return -4;}/* * Insert a new Record-Route header field * And also 2nd one if it is enabled and realm changed so * the 2nd record-route header will be necessary */static inline int insert_RR(struct sip_msg* _m, int _lr){	struct lump* l, *l2;	str user;	struct to_body* from;	str* tag;		from = 0; /* Makes gcc happy */	user.len = 0;		if (add_username) {		if (get_username(_m, &user) < 0) {			LOG(L_ERR, "insert_RR(): Error while extracting username\n");			return -1;		}	}	if (append_fromtag) {		if (parse_from_header(_m) < 0) {			LOG(L_ERR, "insert_RR(): From parsing failed\n");			return -2;		}		from = (struct to_body*)_m->from->parsed;		tag = &from->tag_value;	} else {		tag = 0;	}	if (enable_double_rr) {		l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);		l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);		if (!l || !l2) {			LOG(L_ERR, "insert_RR(): Error while creating an anchor\n");			return -5;		}		l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0);		l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0);		if (!l || !l2) {			LOG(L_ERR, "insert_RR(): Error while inserting conditional lump\n");			return -6;		}		if (build_rr(l, l2, _lr, &user, tag, OUTBOUND) < 0) {			LOG(L_ERR, "insert_RR(): Error while inserting outbound Record-Route\n");			return -7;		}	}		l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);	if (!l || !l2) {		LOG(L_ERR, "insert_RR(): Error while creating an anchor\n");		return -3;	}		if (build_rr(l, l2, _lr, &user, tag, INBOUND) < 0) {		LOG(L_ERR, "insert_RR(): Error while inserting inbound Record-Route\n");		return -4;	}	return 0;}/* * Make sure that the record-route function is not called * twice and if not, execute it */static inline int do_RR(struct sip_msg* _m, int _lr){	static unsigned int last_rr_msg;	if (_m->id == last_rr_msg) {			LOG(L_ERR, "record_route(): Double attempt to record-route\n");			return -1;	}		if (insert_RR(_m, _lr) < 0) {		LOG(L_ERR, "record_route(): Error while inserting Record-Route line\n");		return -3;	}	last_rr_msg=_m->id;		return 1;}/* * Insert a new Record-Route header field with lr parameter */int record_route(struct sip_msg* _m, char* _s1, char* _s2){	return do_RR(_m, 1);}/* * Insert manually created Record-Route header, no checks, no restrictions, * always adds lr parameter, only fromtag is added automatically when requested */int record_route_preset(struct sip_msg* _m, char* _data, char* _s2){	str user;	struct to_body* from;	struct lump* l;	char* hdr, *p;	int hdr_len;	from = 0;	if (get_username(_m, &user) < 0) {		LOG(L_ERR, "record_route_preset(): Error while extracting username\n");		return -1;	}	if (append_fromtag) {		if (parse_from_header(_m) < 0) {			LOG(L_ERR, "record_route_preset(): From parsing failed\n");			return -2;		}		from = (struct to_body*)_m->from->parsed;	}		l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);	if (!l) {		LOG(L_ERR, "record_route_preset(): Error while creating an anchor\n");		return -3;	}	hdr_len = RR_PREFIX_LEN;	hdr_len += user.len;	if (user.len) hdr_len += 1; /* @ */	hdr_len += ((str*)_data)->len;	if (append_fromtag && from->tag_value.len) {		hdr_len += RR_FROMTAG_LEN + from->tag_value.len;	}		if (enable_full_lr) {		hdr_len += RR_LR_FULL_TERM_LEN;	} else {		hdr_len += RR_LR_TERM_LEN;	}	hdr_len += 2; /* CRLF */	hdr = pkg_malloc(hdr_len);	if (!hdr) {		LOG(L_ERR, "record_route_preset(): No memory left\n");		return -4;	}	p = hdr;	memcpy(p, RR_PREFIX, RR_PREFIX_LEN);	p += RR_PREFIX_LEN;	if (user.len) {		memcpy(p, user.s, user.len);		p += user.len;		*p = '@';		p++;	}	memcpy(p, ((str*)_data)->s, ((str*)_data)->len);	p += ((str*)_data)->len;		if (append_fromtag && from->tag_value.len) {		memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);		p += RR_FROMTAG_LEN;		memcpy(p, from->tag_value.s, from->tag_value.len);		p += from->tag_value.len;	}	if (enable_full_lr) {		memcpy(p, RR_LR_FULL_TERM, RR_LR_FULL_TERM_LEN);		p += RR_LR_FULL_TERM_LEN;	} else {		memcpy(p, RR_LR_TERM, RR_LR_TERM_LEN);		p += RR_LR_TERM_LEN;	}	memcpy(p, CRLF, 2);	if (!insert_new_lump_after(l, hdr, hdr_len, 0)) {		LOG(L_ERR, "record_route_preset(): Error while inserting new lump\n");		pkg_free(hdr);		return -5;	}	return 1;}/* * Insert a new Record-Route header field without lr parameter */int record_route_strict(struct sip_msg* _m, char* _s1, char* _s2){	return do_RR(_m, 0);}

⌨️ 快捷键说明

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