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

📄 sipheader.c

📁 性能优秀的SIP Proxy
💻 C
字号:
/* * openser osp module.  * * This module enables openser to communicate with an Open Settlement  * Protocol (OSP) server.  The Open Settlement Protocol is an ETSI  * defined standard for Inter-Domain VoIP pricing, authorization * and usage exchange.  The technical specifications for OSP  * (ETSI TS 101 321 V4.1.1) are available at www.etsi.org. * * Uli Abend was the original contributor to this module. *  * Copyright (C) 2001-2005 Fhg Fokus * * This file is part of openser, a free SIP server. * * openser 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 * * openser 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 */#include "osp_mod.h"#include "provider.h"#include "sipheader.h"#include "../../sr_module.h"#include <stdio.h>#include "osp/osp.h"#include "osp/ospb64.h"#include "../../mem/mem.h"#include "../../timer.h"#include "../../locking.h"#include "../../forward.h"#include "../../parser/parse_uri.h"#include "../../parser/parse_from.h"#include "../../parser/parse_rr.h"#include "../../data_lump.h"int getFromUserpart(struct sip_msg* msg, char *fromuser, int buffer_size){	struct to_body* from;	struct sip_uri uri;	int retVal = 1;	strcpy(fromuser, "");	if (msg->from != NULL) {		if (parse_from_header(msg) == 0) {			from = ((struct to_body *)msg->from->parsed);			if (parse_uri(from->uri.s, from->uri.len, &uri) == 0) {				copy_from_str_to_buffer(&uri.user, fromuser, buffer_size);				skipPlus(fromuser);				retVal = 0;			} else {				LOG(L_ERR, "ERROR: osp: getFromUserpart: could not parse from uri\n");			}		} else {			LOG(L_ERR, "ERROR: osp: getFromUserpart: could not parse from header\n");		}	} else {		LOG(L_ERR, "ERROR: osp: getFromUserpart: could not find from header\n");	}	return retVal;}int getToUserpart(struct sip_msg* msg, char *touser, int buffer_size){	struct to_body* to;	struct sip_uri uri;	int retVal = 1;	strcpy(touser, "");	if (msg->to != NULL) {		to = ((struct to_body *)msg->to->parsed);		if (parse_uri(to->uri.s, to->uri.len, &uri) == 0) {			copy_from_str_to_buffer(&uri.user, touser,buffer_size);			skipPlus(touser);			retVal = 0;		} else {			LOG(L_ERR, "ERROR: osp: getToUserpart: could not parse to uri\n");		}	} else {		LOG(L_ERR, "ERROR: osp: getToUserpart: could not find to header\n");	}	return retVal;}void skipPlus(char* e164) {	if (*e164 == '+') {		strncpy(e164,e164+1,strlen(e164)-1);		e164[strlen(e164)-1] = 0;	}}int append_header_str(struct sip_msg* msg, str *header){	struct lump* anchor;	char *s;		if(msg==0 || header==0 || header->s==0 || header->len<=0) {		LOG(L_ERR, "ERROR:osp:append_header_str: bad parameters\n");		return -1;	}	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {		LOG(L_ERR,			"ERROR:osp:append_header_str: Error while parsing message\n");		return -1;	}	anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);	if (anchor == 0) {		LOG(L_ERR, "ERROR:osp:append_header_str: Can't get anchor\n");		return -1;	}	s = (char*)pkg_malloc(header->len);	if (s==0) {		LOG(L_ERR, "ERROR:osp:append_header_str: No memory left\n");		return -1;	}	memcpy(s, header->s, header->len);	if (insert_new_lump_before(anchor, s, header->len, 0) == 0) {		LOG(L_ERR, "ERROR:osp:append_header_str: Can't insert lump\n");		pkg_free(s);		return -1;	}		return 0;}int addOspHeader(struct sip_msg* msg, unsigned char* token, unsigned int sizeoftoken) {	char headerBuffer[3500];	unsigned char encodedToken[3000];	unsigned int  sizeofencodedToken = sizeof(encodedToken);	str  headerVal;	int  retVal = 1;	if (OSPPBase64Encode(token, sizeoftoken, encodedToken, &sizeofencodedToken) == 0) {		snprintf(headerBuffer,			 sizeof(headerBuffer),			 "%s%.*s\r\n", 			 OSP_HEADER,			 sizeofencodedToken,			 encodedToken);		headerVal.s = headerBuffer;		headerVal.len = strlen(headerBuffer);		DBG("osp: Setting osp token header field - (%s)\n", headerBuffer);		if (append_header_str(msg, &headerVal) == 0) {			retVal = 0;		} else {			LOG(L_ERR, "ERROR: osp: addOspHeader: failed to append osp"					" header to the message\n");		}	} else {		LOG(L_ERR, "ERROR: osp: addOspHeader: base64 encoding failed\n");	}	return retVal;}int getOspHeader(struct sip_msg* msg, unsigned char* token, unsigned int* sizeoftoken) {	struct hdr_field *hf;	int code;	int retVal = 1;	parse_headers(msg, HDR_EOH_T, 0);	for (hf=msg->headers; hf; hf=hf->next) {		if ( (hf->type == HDR_OTHER_T) && (hf->name.len == OSP_HEADER_LEN-2)) {			// possible hit			if (strncasecmp(hf->name.s, OSP_HEADER, OSP_HEADER_LEN) == 0) {				if ( (code=OSPPBase64Decode(hf->body.s, hf->body.len, token, sizeoftoken)) == 0) {					retVal = 0;				} else {					LOG(L_ERR, "ERROR: osp: getOspHeader: failed to base64 decode OSP token, reason - %d\n",code);					LOG(L_ERR, "ERROR: osp: header '%.*s' length %d\n",hf->body.len,hf->body.s,hf->body.len);				}				break;			}				} 	}	return retVal;}int getCallId(struct sip_msg* msg, OSPTCALLID** callid) {	struct hdr_field *cid;	int retVal = 1;	cid = (struct hdr_field*) msg->callid;	if (cid != NULL) {		*callid = OSPPCallIdNew(cid->body.len,(unsigned char*)cid->body.s);		if (*callid) {			retVal = 0;		} else {			LOG(L_ERR, "ERROR: osp: getCallId: failed to allocate call-id object for '%.*s'\n",cid->body.len,cid->body.s);		}	} else {		LOG(L_ERR, "ERROR: osp: getCallId: could not find Call-Id-Header\n");	}		return retVal;}/* get first VIA header and uses the IP or host name */int getSourceAddress(struct sip_msg* msg, char* source_address, int buffer_size){	struct hdr_field* hf;	struct via_body* via_body;	int retVal = 1;	/* no need to call parse_headers, called already and VIA is parsed	 * anyway by default 	 */	for (hf=msg->headers; hf; hf=hf->next) {		if (hf->type == HDR_VIA_T) {			// found first VIA			via_body = (struct via_body*)hf->parsed;				copy_from_str_to_buffer(&via_body->host, source_address, buffer_size);			DBG("osp: getSourceAddress: result is %s\n", source_address);			retVal = 0;			break;		} 	}	return retVal;}/* Get route parameters from the 1st Route or Request Line*/int getRouteParams(struct sip_msg* msg, char* route_params, int buffer_size){	int retVal = 1;        struct hdr_field* hdr;        struct sip_uri puri;        rr_t* rt;	 DBG("osp: getRouteParams: parsed uri: host '%.*s' port '%d' vars '%.*s'\n",             msg->parsed_uri.host.len,msg->parsed_uri.host.s,             msg->parsed_uri.port_no,             msg->parsed_uri.params.len,msg->parsed_uri.params.s);        if (!(hdr=msg->route)) {                DBG("osp: getRouteParams: there is no route headers\n");        } else if (!(rt=(rr_t*)hdr->parsed)) {                LOG(L_ERR, "ERROR: osp: getRouteParams: the route headers are not parsed\n");        } else if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri) != 0) {                LOG(L_ERR, "ERROR: osp: getRouteParams: failed to parse the route URI '%.*s'\n",rt->nameaddr.uri.len,rt->nameaddr.uri.s);        } else if (check_self(&puri.host, puri.port_no ? puri.port_no : SIP_PORT, PROTO_NONE) != 1) {                DBG("osp: getRouteParams: the route uri is NOT mine\n");                DBG("osp: getRouteParams: host '%.*s' port '%d'\n",puri.host.len,puri.host.s,puri.port_no);                DBG("osp: getRouteParams: params '%.*s'\n",puri.params.len,puri.params.s);        } else {                DBG("osp: getRouteParams: the Route IS mine - '%.*s'\n",puri.params.len,puri.params.s);                DBG("osp: getRouteParams: host '%.*s' port '%d'\n",puri.host.len,puri.host.s,puri.port_no);                copy_from_str_to_buffer(&puri.params, route_params, buffer_size);                retVal = 0;        }        if (retVal == 1 && msg->parsed_uri.params.len > 0) {                DBG("osp: getRouteParams: using route params fromt he request uri\n");                copy_from_str_to_buffer(&msg->parsed_uri.params, route_params, buffer_size);                route_params[msg->parsed_uri.params.len] = 0;                retVal = 0;        }	return retVal;}/* Will use the first 'Route' hf not generated by this proxy or * URI from the request line */void getNextHop(struct sip_msg* msg, char* next_hope, int buffer_size){	struct hdr_field* hf;        struct sip_uri puri;	rr_t*   route;	int    found = 0;	DBG("osp: getNextHop: will iterate through the 'Route' header-fields\n");	for (hf=msg->headers; hf; hf=hf->next) {		if (hf->type == HDR_ROUTE_T) {			route = (rr_t*)hf->parsed;				if (parse_uri(route->nameaddr.uri.s,route->nameaddr.uri.len,&puri) == 0) {				DBG("osp: getNextHop: host '%.*s' port '%d'\n",puri.host.len,puri.host.s,puri.port_no);				if (check_self(&puri.host, puri.port_no ? puri.port_no : SIP_PORT, PROTO_NONE) != 1) {					DBG("osp: getNextHop: it is NOT me, FOUND!\n");					copy_from_str_to_buffer(&puri.host, next_hope, buffer_size);					found = 1;					break;				} else {					DBG("osp: getNextHop: it IS me, keep looking\n");				}			} else {				LOG(L_ERR,"ERROR: osp: getNextHop: failed to parsed 'Route' uri '%.*s'\n",route->nameaddr.uri.len,route->nameaddr.uri.s);			}		}	}	if (!found) {		DBG("osp: getNextHop: Using the request line instead host '%.*s' port '%d'\n",		     msg->parsed_uri.host.len,msg->parsed_uri.host.s,		     msg->parsed_uri.port_no);		copy_from_str_to_buffer(&msg->parsed_uri.host, next_hope, buffer_size);		found =1;	}}int rebuildDestionationUri(str *newuri, char *destination, char *port, char *callednumber) {	#define TRANS ";transport=tcp" 	#define TRANS_LEN 14	char* buf;	int sizeofcallednumber;	int sizeofdestination;	int sizeofport;	sizeofcallednumber = strlen(callednumber);	sizeofdestination = strlen(destination);	sizeofport = strlen(port);	DBG("osp: rebuilddestionationstr >%s<(%i) >%s<(%i) >%s<(%i)\n",		callednumber, sizeofcallednumber, destination, sizeofdestination, port, sizeofport);			/* "sip:+" + callednumber + "@" + destination + : + port + " SIP/2.0" */	newuri->s = (char*) pkg_malloc(sizeofdestination + sizeofcallednumber + sizeofport + 1 + 16 + TRANS_LEN);	if (newuri == NULL) {		LOG(L_ERR, "ERROR: osp: rebuilddestionationstr: no memory\n");		return 1;	}		buf = newuri->s;	*buf++ = 's';	*buf++ = 'i';	*buf++ = 'p';	*buf++ = ':';	/* Don't prepend +	if (*callednumber == '+') {		// already starts with	} else {		*buf++ = '+';	}	*/	memcpy(buf, callednumber, sizeofcallednumber);	buf += sizeofcallednumber;	*buf++ = '@';		if (*destination == '[') {		/* leave out annoying [] */		memcpy(buf, destination+1, sizeofdestination-2);		buf += sizeofdestination-2;	} else {		memcpy(buf, destination, sizeofdestination);		buf += sizeofdestination;	}		if (sizeofport > 0) {		*buf++ = ':';		memcpy(buf, port, sizeofport);		buf += sizeofport;	}/*	*buf++ = ' ';	*buf++ = 'S';	*buf++ = 'I';	*buf++ = 'P';	*buf++ = '/';	*buf++ = '2';	*buf++ = '.';	*buf++ = '0';*/	/* zero terminate for convenience */	//memcpy(buf, TRANS, TRANS_LEN);	//buf+=TRANS_LEN;	//*buf = '\0';	newuri->len = buf - newuri->s;	DBG("newuri is >%.*s<\n", newuri->len, newuri->s);	return 0; /* success */}/* Copies a str to a buffer and checks for over-flow */void copy_from_str_to_buffer(str* from, char* buffer, int buffer_size){	int copy_bytes;	if (from->len > buffer_size) {		LOG(L_ERR,"Buffer for copying '%.*s' is too small, will copy the first %d of %d bytes\n",			from->len,from->s,buffer_size,from->len);		copy_bytes = buffer_size;	} else {		copy_bytes = from->len;	}	strncpy(buffer,from->s,copy_bytes);	buffer[copy_bytes] = '\0';}

⌨️ 快捷键说明

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