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

📄 t_msgbuilder.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: t_msgbuilder.c,v 1.40 2004/11/09 15:15:12 andrei Exp $ * * message printing * * 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-27  next baby-step to removing ZT - PRESERVE_ZT (jiri) * 2003-02-13  build_uac_request uses proto (andrei) * 2003-02-28  scratchpad compatibility abandoned (jiri) * 2003-04-14  build_local no longer checks reply status as it *             is now called before reply status is updated to *             avoid late ACK sending (jiri) * 2003-10-02  added via_builder set host/port support (andrei) * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri) * 2004-02-13: t->is_invite and t->local replaced with flags (bogdan) */#include "defs.h"#include "../../comp_defs.h"#include "../../hash_func.h"#include "../../globals.h"#include "t_funcs.h"#include "../../dprint.h"#include "../../config.h"#include "../../parser/parser_f.h"#include "../../ut.h"#include "../../parser/msg_parser.h"#include "../../parser/contact/parse_contact.h"#include "t_msgbuilder.h"#include "uac.h"#define ROUTE_PREFIX "Route: "#define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)#define ROUTE_SEPARATOR ", "#define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)#define  append_mem_block(_d,_s,_len) \		do{\			memcpy((_d),(_s),(_len));\			(_d) += (_len);\		}while(0);#define append_str(_p,_str) \	do{  \		memcpy((_p), (_str).s, (_str).len); \		(_p)+=(_str).len;  \ 	} while(0);/* Build a local request based on a previous request; main   customers of this function are local ACK and local CANCEL */char *build_local(struct cell *Trans,unsigned int branch,	unsigned int *len, char *method, int method_len, str *to){	char                *cancel_buf, *p, *via;	unsigned int         via_len;	struct hdr_field    *hdr;	char branch_buf[MAX_BRANCH_PARAM_LEN];	int branch_len;	str branch_str;	struct hostport hp;#ifdef _OBSO	if ( Trans->uac[branch].last_received<100)	{		DBG("DEBUG: build_local: no response ever received"			" : dropping local request! \n");		goto error;	}#endif	/* method, separators, version: "CANCEL sip:p2@iptel.org SIP/2.0" */	*len=SIP_VERSION_LEN + method_len + 2 /* spaces */ + CRLF_LEN;	*len+=Trans->uac[branch].uri.len;	/*via*/	if (!t_calc_branch(Trans,  branch, 		branch_buf, &branch_len ))		goto error;	branch_str.s=branch_buf;	branch_str.len=branch_len;	set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));	via=via_builder(&via_len, Trans->uac[branch].request.dst.send_sock,		&branch_str, 0, Trans->uac[branch].request.dst.proto, &hp );	if (!via)	{		LOG(L_ERR, "ERROR: build_local: "			"no via header got from builder\n");		goto error;	}	*len+= via_len;	/*headers*/	*len+=Trans->from.len+Trans->callid.len+to->len+		+Trans->cseq_n.len+1+method_len+CRLF_LEN; 	/* copy'n'paste Route headers */	if (!is_local(Trans)) {		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )			 if (hdr->type==HDR_ROUTE)				*len+=hdr->len;	}	/* User Agent */	if (server_signature) {		*len += USER_AGENT_LEN + CRLF_LEN;	}	/* Content Length, EoM */	*len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN;	cancel_buf=shm_malloc( *len+1 );	if (!cancel_buf)	{		LOG(L_ERR, "ERROR: build_local: cannot allocate memory\n");		goto error01;	}	p = cancel_buf;	append_mem_block( p, method, method_len );	append_mem_block( p, " ", 1 );	append_str( p, Trans->uac[branch].uri );	append_mem_block( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );	/* insert our via */	append_mem_block(p,via,via_len);	/*other headers*/	append_str( p, Trans->from );	append_str( p, Trans->callid );	append_str( p, *to );	append_str( p, Trans->cseq_n );	append_mem_block( p, " ", 1 );	append_mem_block( p, method, method_len );	append_mem_block( p, CRLF, CRLF_LEN );	if (!is_local(Trans))  {		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )			if(hdr->type==HDR_ROUTE) {				append_mem_block(p, hdr->name.s, hdr->len );			}	}	/* User Agent header */	if (server_signature) {		append_mem_block(p,USER_AGENT CRLF, USER_AGENT_LEN+CRLF_LEN );	}	/* Content Length, EoM */	append_mem_block(p, CONTENT_LENGTH "0" CRLF CRLF ,		CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);	*p=0;	pkg_free(via);	return cancel_buf;error01:	pkg_free(via);error:	return NULL;}struct rte {	rr_t* ptr;	struct rte* next;};  	 static inline void free_rte_list(struct rte* list){	struct rte* ptr;		while(list) {		ptr = list;		list = list->next;		pkg_free(ptr);	}}static inline int process_routeset(struct sip_msg* msg, str* contact, struct rte** list, str* ruri, str* next_hop){	struct hdr_field* ptr;	rr_t* p;	struct rte* t, *head;	struct sip_uri puri;		ptr = msg->record_route;	head = 0;	while(ptr) {		if (ptr->type == HDR_RECORDROUTE) {			if (parse_rr(ptr) < 0) {				LOG(L_ERR, "process_routeset: Error while parsing Record-Route header\n");				return -1;			}						p = (rr_t*)ptr->parsed;			while(p) {				t = (struct rte*)pkg_malloc(sizeof(struct rte));				if (!t) {					LOG(L_ERR, "process_routeset: No memory left\n");					free_rte_list(head);					return -1;				}				t->ptr = p;				t->next = head;				head = t;				p = p->next;			}		}		ptr = ptr->next;	}		if (head) {		if (parse_uri(head->ptr->nameaddr.uri.s, head->ptr->nameaddr.uri.len, &puri) == -1) {			LOG(L_ERR, "process_routeset: Error while parsing URI\n");			free_rte_list(head);			return -1;		}				if (puri.lr.s) {			     /* Next hop is loose router */			*ruri = *contact;			*next_hop = head->ptr->nameaddr.uri;		} else {			     /* Next hop is strict router */			*ruri = head->ptr->nameaddr.uri;			*next_hop = *ruri;			t = head;			head = head->next;			pkg_free(t);		}	} else {		     /* No routes */		*ruri = *contact;		*next_hop = *contact;	}		*list = head;	return 0;}static inline int calc_routeset_len(struct rte* list, str* contact){	struct rte* ptr;	int ret;		if (list || contact) {		ret = ROUTE_PREFIX_LEN + CRLF_LEN;	} else {		return 0;	}		ptr = list;	while(ptr) {		if (ptr != list) {			ret += ROUTE_SEPARATOR_LEN;		}		ret += ptr->ptr->len;		ptr = ptr->next;	}		if (contact) {		if (list) ret += ROUTE_SEPARATOR_LEN;		ret += 2 + contact->len;	}		return ret;}     /*      * Print the route set      */static inline char* print_rs(char* p, struct rte* list, str* contact){	struct rte* ptr;		if (list || contact) {		memapp(p, ROUTE_PREFIX, ROUTE_PREFIX_LEN);	} else {		return p;	}		ptr = list;	while(ptr) {		if (ptr != list) {			memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);		}				memapp(p, ptr->ptr->nameaddr.name.s, ptr->ptr->len);		ptr = ptr->next;	}		if (contact) {		if (list) memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);		*p++ = '<';		append_str(p, *contact);		*p++ = '>';	}		memapp(p, CRLF, CRLF_LEN);	return p;}     /*      * Parse Contact header field body and extract URI      * Does not parse headers !      */static inline int get_contact_uri(struct sip_msg* msg, str* uri){	contact_t* c;		uri->len = 0;	if (!msg->contact) return 1;		if (parse_contact(msg->contact) < 0) {		LOG(L_ERR, "get_contact_uri: Error while parsing Contact body\n");		return -1;	}		c = ((contact_body_t*)msg->contact->parsed)->contacts;		if (!c) {		LOG(L_ERR, "get_contact_uri: Empty body or * contact\n");		return -2;	}		*uri = c->uri;	return 0;}     /*      * The function creates an ACK to 200 OK. Route set will be created      * and parsed and next_hop parameter will contain uri the which the      * request should be send. The function is used by tm when it generates      * local ACK to 200 OK (on behalf of applications using uac      */char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch,		    str* to, unsigned int *len, str *next_hop){	char *req_buf, *p, *via;	unsigned int via_len;	char branch_buf[MAX_BRANCH_PARAM_LEN];	int branch_len;	str branch_str;	struct hostport hp;	struct rte* list;	str contact, ruri, *cont;	struct socket_info* send_sock;	union sockaddr_union to_su;		if (get_contact_uri(rpl, &contact) < 0) {		return 0;	}		if (process_routeset(rpl, &contact, &list, &ruri, next_hop) < 0) {

⌨️ 快捷键说明

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