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

📄 sip_msg.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: sip_msg.c,v 1.84.2.2 2005/09/01 12:33:30 andrei Exp $ *  * cloning a message into shared memory (TM keeps a snapshot * of messages in memory); note that many operations, which * allocate pkg memory (such as parsing) cannot be used with * a cloned message -- it would result in linking pkg structures * to shmem msg and eventually in a memory error  * * the cloned message is stored in a single memory fragment to * save too many shm_mallocs -- these are expensive as they * not only take lookup in fragment table but also a shmem lock * operation (the same for shm_free) * * 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-01-23 - msg_cloner clones msg->from->parsed too (janakj) *  2003-01-29 - scratchpad removed (jiri) *  2003-02-25 - auth_body cloner added (janakj) *  2003-02-28  scratchpad compatibility abandoned (jiri) *  2003-03-31  removed msg->repl_add_rm (andrei) *  2003-04-04  parsed uris are recalculated on cloning (jiri) *  2003-05-07  received, rport & i via shortcuts are also translated (andrei) *  2003-11-11  updated cloning of lump_rpl (bogdan) *  2004-03-31  alias shortcuts are also translated (andrei) */#include "defs.h"#include <stdio.h>#include "sip_msg.h"#include "../../dprint.h"#include "../../mem/mem.h"#include "../../data_lump.h"#include "../../data_lump_rpl.h"#include "../../ut.h"#include "../../parser/digest/digest.h"/* rounds to the first 4 byte multiple on 32 bit archs  * and to the first 8 byte multiple on 64 bit archs */#define ROUND4(s) \	(((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))#define lump_len( _lump) \	(ROUND4(sizeof(struct lump)) +\	ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))#define lump_clone( _new,_old,_ptr) \	{\		(_new) = (struct lump*)(_ptr);\		memcpy( (_new), (_old), sizeof(struct lump) );\		(_new)->flags|=LUMPFLAG_SHMEM; \		(_ptr)+=ROUND4(sizeof(struct lump));\		if ( (_old)->op==LUMP_ADD) {\			(_new)->u.value = (char*)(_ptr);\			memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\			(_ptr)+=ROUND4((_old)->len);}\	}inline struct via_body* via_body_cloner( char* new_buf,					char *org_buf, struct via_body *param_org_via, char **p){	struct via_body *new_via;	struct via_body *first_via, *last_via;	struct via_body *org_via;	first_via = last_via = 0;	org_via = param_org_via;	do	{		/* clones the via_body structure */		new_via = (struct via_body*)(*p);		memcpy( new_via , org_via , sizeof( struct via_body) );		(*p) += ROUND4(sizeof( struct via_body ));		/* hdr (str type) */		new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);		/* name (str type) */		new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);		/* version (str type) */		new_via->version.s=			translate_pointer(new_buf,org_buf,org_via->version.s);		/* transport (str type) */		new_via->transport.s=			translate_pointer(new_buf,org_buf,org_via->transport.s);		/* host (str type) */		new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);		/* port_str (str type) */		new_via->port_str.s=			translate_pointer(new_buf,org_buf,org_via->port_str.s);		/* params (str type) */		new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);		/* transaction id */		new_via->tid.s=			translate_pointer(new_buf, org_buf, org_via->tid.s);		/* comment (str type) */		new_via->comment.s=			translate_pointer(new_buf,org_buf,org_via->comment.s);		if ( org_via->param_lst )		{			struct via_param *vp, *new_vp, *last_new_vp;			for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )			{				new_vp = (struct via_param*)(*p);				memcpy( new_vp , vp , sizeof(struct via_param));				(*p) += ROUND4(sizeof(struct via_param));				new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);				new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);				new_vp->start=translate_pointer(new_buf,org_buf,vp->start);								/* "translate" the shortcuts */				switch(new_vp->type){					case PARAM_BRANCH:							new_via->branch = new_vp;							break;					case PARAM_RECEIVED:							new_via->received = new_vp;							break;					case PARAM_RPORT:							new_via->rport = new_vp;							break;					case PARAM_I:							new_via->i = new_vp;							break;					case PARAM_ALIAS:							new_via->alias = new_vp;							break;				}				if (last_new_vp)					last_new_vp->next = new_vp;				else					new_via->param_lst = new_vp;				last_new_vp = new_vp;				last_new_vp->next = NULL;			}			new_via->last_param = new_vp;		}/*end if via has params */		if (last_via)			last_via->next = new_via;		else			first_via = new_via;		last_via = new_via;		org_via = org_via->next;	}while(org_via);	return first_via;}static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri){	uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);	uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);	uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);	uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);	uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);	uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);}static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p){	struct auth_body* new_auth;	new_auth = (struct auth_body*)(*p);	memcpy(new_auth , auth , sizeof(struct auth_body));	(*p) += ROUND4(sizeof(struct auth_body));		/* authorized field must be cloned elsewhere */	new_auth->digest.username.whole.s =		translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);	new_auth->digest.username.user.s =		translate_pointer(new_buf, org_buf, auth->digest.username.user.s);	new_auth->digest.username.domain.s =		translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);	new_auth->digest.realm.s =		translate_pointer(new_buf, org_buf, auth->digest.realm.s);	new_auth->digest.nonce.s =		translate_pointer(new_buf, org_buf, auth->digest.nonce.s);	new_auth->digest.uri.s =		translate_pointer(new_buf, org_buf, auth->digest.uri.s);	new_auth->digest.response.s =		translate_pointer(new_buf, org_buf, auth->digest.response.s);	new_auth->digest.alg.alg_str.s =		translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);	new_auth->digest.cnonce.s =		translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);	new_auth->digest.opaque.s =		translate_pointer(new_buf, org_buf, auth->digest.opaque.s);	new_auth->digest.qop.qop_str.s =		translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);	new_auth->digest.nc.s =		translate_pointer(new_buf, org_buf, auth->digest.nc.s);	return new_auth;}static inline int clone_authorized_hooks(struct sip_msg* new,					 struct sip_msg* old){	struct hdr_field* ptr, *new_ptr, *hook1, *hook2;	char stop = 0;	get_authorized_cred(old->authorization, &hook1);	if (!hook1) stop = 1;		get_authorized_cred(old->proxy_auth, &hook2);	if (!hook2) stop |= 2;	ptr = old->headers;	new_ptr = new->headers;	while(ptr) {		if (ptr == hook1) {			if (!new->authorization || !new->authorization->parsed) {				LOG(L_CRIT, "BUG: Error in message cloner (authorization)\n");				return -1;			}			((struct auth_body*)new->authorization->parsed)->authorized =				new_ptr;			stop |= 1;		}				if (ptr == hook2) {			if (!new->proxy_auth || !new->proxy_auth->parsed) {				LOG(L_CRIT, "BUG: Error in message cloner (proxy_auth)\n");				return -1;			}			((struct auth_body*)new->proxy_auth->parsed)->authorized =				new_ptr;			stop |= 2;		}		if (stop == 3) break;		ptr = ptr->next;		new_ptr = new_ptr->next;	}	return 0;}#define AUTH_BODY_SIZE sizeof(struct auth_body)#define HOOK_SET(hook) (new_msg->hook != org_msg->hook)struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len ){	unsigned int      len;	struct hdr_field  *hdr,*new_hdr,*last_hdr;	struct via_body   *via;	struct via_param  *prm;	struct to_param   *to_prm,*new_to_prm;	struct sip_msg    *new_msg;	struct lump_rpl   *rpl_lump, **rpl_lump_anchor;	char              *p;	/*computing the length of entire sip_msg structure*/	len = ROUND4(sizeof( struct sip_msg ));	/*we will keep only the original msg +ZT */	len += ROUND4(org_msg->len + 1);	/*the new uri (if any)*/	if (org_msg->new_uri.s && org_msg->new_uri.len)		len+= ROUND4(org_msg->new_uri.len);	/*the dst uri (if any)*/	if (org_msg->dst_uri.s && org_msg->dst_uri.len)		len+= ROUND4(org_msg->dst_uri.len);	/*all the headers*/	for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )	{		/*size of header struct*/		len += ROUND4(sizeof( struct hdr_field));		switch (hdr->type)		{			case HDR_VIA:				for (via=(struct via_body*)hdr->parsed;via;via=via->next)				{					len+=ROUND4(sizeof(struct via_body));					/*via param*/					for(prm=via->param_lst;prm;prm=prm->next)						len+=ROUND4(sizeof(struct via_param ));				}				break;			case HDR_TO:			case HDR_FROM:				/* From header might be unparsed */				if (hdr->parsed) {					len+=ROUND4(sizeof(struct to_body));					     /*to param*/					to_prm = ((struct to_body*)(hdr->parsed))->param_lst;					for(;to_prm;to_prm=to_prm->next)						len+=ROUND4(sizeof(struct to_param ));				}				break;			case HDR_CSEQ:				len+=ROUND4(sizeof(struct cseq_body));				break;			case HDR_AUTHORIZATION:			case HDR_PROXYAUTH:				if (hdr->parsed) {					len += ROUND4(AUTH_BODY_SIZE);				}				break;			case HDR_CALLID:			case HDR_CONTACT:			case HDR_MAXFORWARDS:			case HDR_ROUTE:			case HDR_RECORDROUTE:			case HDR_CONTENTTYPE:			case HDR_CONTENTLENGTH:			case HDR_EXPIRES:			case HDR_SUPPORTED:			case HDR_PROXYREQUIRE:			case HDR_UNSUPPORTED:			case HDR_ALLOW:			case HDR_EVENT:			case HDR_ACCEPT:			case HDR_ACCEPTLANGUAGE:			case HDR_ORGANIZATION:			case HDR_PRIORITY:			case HDR_SUBJECT:			case HDR_USERAGENT:			case HDR_ACCEPTDISPOSITION:			case HDR_CONTENTDISPOSITION:				/* we ignore them for now even if they have something parsed*/				break;			default:				if (hdr->parsed) {					LOG(L_WARN, "WARNING: sip_msg_cloner: "						"header body ignored: %d\n", hdr->type );				}				break;		}/*switch*/	}/*for all headers*/	/* length of the data lump structures */#define LUMP_LIST_LEN(len, list) \do { \        struct lump* tmp, *chain; \	chain = (list); \	while (chain) \	{ \		(len) += lump_len(chain); \		tmp = chain->before; \		while ( tmp ) \		{ \			(len) += lump_len( tmp ); \			tmp = tmp->before; \		} \		tmp = chain->after; \		while ( tmp ) \		{ \			(len) += lump_len( tmp ); \			tmp = tmp->after; \		} \		chain = chain->next; \	} \

⌨️ 快捷键说明

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