当前位置: 首页>>代码示例>>C++>>正文


C++ parse_headers函数代码示例

本文整理汇总了C++中parse_headers函数的典型用法代码示例。如果您正苦于以下问题:C++ parse_headers函数的具体用法?C++ parse_headers怎么用?C++ parse_headers使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了parse_headers函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: w_is_first_hop

int w_is_first_hop(sip_msg_t *msg, char *p1, char *p2)
{
	int ret;
	rr_t* r = NULL;
	sip_uri_t puri;
	struct ip_addr *ip;

	if(msg==NULL)
		return -1;

	if(msg->first_line.type == SIP_REQUEST) {
		if (parse_headers( msg, HDR_VIA2_F, 0 )<0
				|| (msg->via2==0) || (msg->via2->error!=PARSE_OK))
		{
			/* sip request: if more than one via, then not first hop */
			/* no second via or error */
			LM_DBG("no 2nd via found - first hop\n");
			return 1;
		}
		return -1;
	} else if(msg->first_line.type == SIP_REPLY) {
		/* sip reply: if top record-route is myself
		 * and not received from myself (loop), then is first hop */
		if (parse_headers( msg, HDR_EOH_F, 0 )<0) {
			LM_DBG("error parsing headers\n");
			return -1;
		}
		if(msg->record_route==NULL) {
			LM_DBG("no record-route header - first hop\n");
			return 1;
		}
		if(parse_rr(msg->record_route)<0) {
			LM_DBG("failed to parse first record-route header\n");
			return -1;
		}
		r = (rr_t*)msg->record_route->parsed;
		if(parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &puri)<0) {
			LM_DBG("failed to parse uri in first record-route header\n");
			return -1;
		}
		if (((ip = str2ip(&(puri.host))) == NULL)
				&& ((ip = str2ip6(&(puri.host))) == NULL)) {
			LM_DBG("uri host is not an ip address\n");
			return -1;
		}
		ret = check_self(&puri.host, (puri.port.s)?puri.port_no:0,
				(puri.transport_val.s)?puri.proto:0);
		if(ret!=1) {
			LM_DBG("top record route uri is not myself\n");
			return -1;
		}
		if (ip_addr_cmp(ip, &(msg->rcv.src_ip))
				&& ((msg->rcv.src_port == puri.port_no)
					|| ((puri.port.len == 0) && (msg->rcv.src_port == 5060)))
				&& (puri.proto==msg->rcv.proto
					|| (puri.proto==0 && msg->rcv.proto==PROTO_UDP)) ) {
			LM_DBG("source address matches top record route uri - loop\n");
			return -1;
		}
		/* todo - check spirals */
		return 1;
	} else {
		return -1;
	}
}
开发者ID:Jared-Prime,项目名称:kamailio,代码行数:65,代码来源:sipops.c

示例2: t_reply_matching


//.........这里部分代码省略.........
	/* sanity check */
	if (reverse_hex2int(hashi, hashl, &hash_index)<0
		||hash_index>=TABLE_ENTRIES
		|| reverse_hex2int(branchi, branchl, &branch_id)<0
		||branch_id>=MAX_BRANCHES
		|| (syn_branch ? (reverse_hex2int(syni, synl, &entry_label))<0 
			: loopl!=MD5_LEN )
	) {
		DBG("DEBUG: t_reply_matching: poor reply labels %d label %d "
			"branch %d\n", hash_index, entry_label, branch_id );
		goto nomatch2;
	}


	DBG("DEBUG: t_reply_matching: hash %d label %d branch %d\n",
		hash_index, entry_label, branch_id );


	/* search the hash table list at entry 'hash_index'; lock the
	   entry first 
	*/
	cseq_method=get_cseq(p_msg)->method;
	is_cancel=cseq_method.len==CANCEL_LEN 
		&& memcmp(cseq_method.s, CANCEL, CANCEL_LEN)==0;
	LOCK_HASH(hash_index);
	for (p_cell = get_tm_table()->entrys[hash_index].first_cell; p_cell; 
		p_cell=p_cell->next_cell) {

		/* first look if branch matches */

		if (syn_branch) {
			if (p_cell->label != entry_label) 
				continue;
		} else {
			if ( memcmp(p_cell->md5, loopi,MD5_LEN)!=0)
					continue;
		}

		/* sanity check ... too high branch ? */
		if ( branch_id>=p_cell->nr_of_outgoings )
			continue;

		/* does method match ? (remember -- CANCELs have the same branch
		   as canceled transactions) */
		req_method=p_cell->method;
		if ( /* method match */
			! ((cseq_method.len==req_method.len 
			&& memcmp( cseq_method.s, req_method.s, cseq_method.len )==0)
			/* or it is a local cancel */
			|| (is_cancel && is_invite(p_cell)
				/* commented out -- should_cancel_branch set it to
				   BUSY_BUFFER to avoid collisions with replies;
				   thus, we test here by buffer size
				*/
				/* && p_cell->uac[branch_id].local_cancel.buffer ))) */
				&& p_cell->uac[branch_id].local_cancel.buffer_len ))) 
			continue;


		/* we passed all disqualifying factors .... the transaction has been
		   matched !
		*/
		set_t(p_cell);
		*p_branch =(int) branch_id;
		REF_UNSAFE( T );
		UNLOCK_HASH(hash_index);
		DBG("DEBUG: t_reply_matching: reply matched (T=%p)!\n",T);
		/* if this is a 200 for INVITE, we will wish to store to-tags to be
		 * able to distinguish retransmissions later and not to call
 		 * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are
		 * enabled -- except callback customers, nobody cares about 
		 * retransmissions of multiple 200/INV or ACK/200s
		 */
		if (is_invite(p_cell) && p_msg->REPLY_STATUS>=200 
		&& p_msg->REPLY_STATUS<300 
		&& ( (!is_local(p_cell) &&
				has_tran_tmcbs(p_cell,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )
			|| (is_local(p_cell)&&has_tran_tmcbs(p_cell,TMCB_LOCAL_COMPLETED))
		)) {
			if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
				LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
			}
		}
		if (!is_local(p_cell)) {
			run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request, p_msg,
				p_msg->REPLY_STATUS);
		}
		return 1;
	} /* for cycle */

	/* nothing found */
	UNLOCK_HASH(hash_index);
	DBG("DEBUG: t_reply_matching: no matching transaction exists\n");

nomatch2:
	DBG("DEBUG: t_reply_matching: failure to match a transaction\n");
	*p_branch = -1;
	set_t(0);
	return -1;
}
开发者ID:winer632,项目名称:openimscore-code,代码行数:101,代码来源:t_lookup.c

示例3: extract_node_list

/**
 * extract the node list from the body of a notification request SIP message
 * the SIP request will look something like:
 * 	KDMQ sip:10.0.0.0:5062
 * 	To: ...
 * 	From: ...
 * 	Max-Forwards: ...
 * 	Content-Length: 22
 * 	
 * 	sip:host1:port1;param1=value1
 * 	sip:host2:port2;param2=value2
 * 	...
 */
int extract_node_list(dmq_node_list_t* update_list, struct sip_msg* msg)
{
	int content_length, total_nodes = 0;
	str body;
	str tmp_uri;
	dmq_node_t *cur = NULL;
	dmq_node_t *ret, *find;
	char *tmp, *end, *match;

	if(!msg->content_length && (parse_headers(msg,HDR_CONTENTLENGTH_F,0)<0 || !msg->content_length)) {
		LM_ERR("no content length header found\n");
		return -1;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		return total_nodes;
	}
	body.s = get_body(msg);
	body.len = content_length;
	tmp = body.s;
	end = body.s + body.len;
	
	/* acquire big list lock */
	lock_get(&update_list->lock);
	while(tmp < end) {
		match = q_memchr(tmp, '\n', end - tmp);
		if(match) {
			match++;
		} else {
			/* for the last line - take all of it */
			match = end;
		}
		/* create the orig_uri from the parsed uri line and trim it */
		tmp_uri.s = tmp;
		tmp_uri.len = match - tmp - 1;
		tmp = match;
		/* trim the \r, \n and \0's */
		trim_r(tmp_uri);
		find = build_dmq_node(&tmp_uri, 0);
		if(find==NULL)
			return -1;
		ret = find_dmq_node(update_list, find);
		if (!ret) {
			LM_DBG("found new node %.*s\n", STR_FMT(&tmp_uri));
			cur = build_dmq_node(&tmp_uri, 1);
			if(!cur) {
				LM_ERR("error creating new dmq node\n");
				goto error;
			}
			cur->next = update_list->nodes;
			update_list->nodes = cur;
			update_list->count++;
			total_nodes++;
		} else if (find->params && ret->status != find->status) {
			LM_DBG("updating status on %.*s from %d to %d\n",
				STR_FMT(&tmp_uri), ret->status, find->status);
			ret->status = find->status;
			total_nodes++;
		}
		destroy_dmq_node(find, 0);
	}

	/* release big list lock */
	lock_release(&update_list->lock);
	return total_nodes;
error:
	lock_release(&update_list->lock);
	return -1;
}
开发者ID:SipCoSystems,项目名称:hush,代码行数:83,代码来源:notification_peer.c

示例4: rls_handle_subscribe

int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, *pfrom = NULL; 
	subs_t subs;
	pres_ev_t* event= NULL;
	str* contact= NULL;
	xmlDocPtr doc= NULL;
	xmlNodePtr service_node= NULL;
	unsigned int hash_code= 0;
	event_t* parsed_event;
	param_t* ev_param= NULL;
	int init_req;
	int reply_code;
	str reply_str;

	/*** filter: 'For me or for presence server?' */

	reply_code = 400;
	reply_str = pu_400_rpl;

	memset(&subs, 0, sizeof(subs_t));

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		goto error;
	}

	/* check for Support: eventlist header */
	if(!msg->supported)
	{
		LM_DBG("no supported header found\n");
		return to_presence_code;
	}
	
	if(parse_supported(msg) < 0)
	{
		LM_ERR("failed to parse supported headers\n");
		reply_code = 500;
		reply_str = pu_500_rpl;
		goto error;
	}

	if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST))
	{
		LM_DBG("No 'Support: eventlist' header found\n");
		return to_presence_code;
	}

	/* inspecting the Event header field */
	if(msg->event && msg->event->body.len > 0)
	{
		if (!msg->event->parsed && (parse_event(msg->event) < 0))
		{
			LM_ERR("cannot parse Event header\n");
			reply_code = 500;
			reply_str = pu_500_rpl;
			goto error;
		}
		if(! ( ((event_t*)msg->event->parsed)->parsed & rls_events) )
		{
			return to_presence_code;
		}
	}
	else
	{
		goto bad_event;
	}

	/* search event in the list */
	parsed_event= (event_t*)msg->event->parsed;
	event= pres_search_event(parsed_event);
	if(event== NULL)
	{
		goto bad_event;
	}
	subs.event= event;
	
	/* extract the id if any*/
	ev_param= parsed_event->params;
	while(ev_param)
	{
		if(ev_param->name.len== 2 && strncasecmp(ev_param->name.s, "id", 2)== 0)
		{
			subs.event_id= ev_param->body;
			break;
		}
		ev_param= ev_param->next;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK)
	{
		LM_ERR("parsing 'To' header failed\n");
		goto error;
	}

	if(parse_from_uri(msg)<0)
	{
		LM_ERR("failed to parse From header\n");
//.........这里部分代码省略.........
开发者ID:KISSMonX,项目名称:opensips,代码行数:101,代码来源:subscribe.c

示例5: Notify2Xmpp

int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, *pfrom= NULL;
	str to_uri;
	str from_uri={0, 0};
	struct hdr_field* hdr= NULL;
	str body;
	xmlDocPtr doc= NULL;
	int is_terminated= 0;
	str id;
	ua_pres_t dialog;
	int event_flag= 0;
	char buf_to[256];

	memset(&dialog, 0, sizeof(ua_pres_t));

	LM_DBG("start...\n\n");

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return -1;
	}

	dialog.watcher_uri= &pto->uri;

	URI_ADD_NULL_TERM(to_uri, buf_to, dialog.watcher_uri);

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		goto error;
	}
	id=  pto->tag_value;
	dialog.from_tag= id;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("ERROR cannot find 'from' header!\n");
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_ERR("ERROR cannot parse From header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	from_uri.s = xmpp_uri_sip2xmpp(dialog.pres_uri);
	if(from_uri.s == 0)
	{
		LM_ERR("Failed to translate uri from sip to xmpp [%.*s]\n",
				dialog.pres_uri->len, dialog.pres_uri->s);
		goto error;
	}
	from_uri.len= strlen(from_uri.s);

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}

	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= XMPP_SUBSCRIBE;
	if(msg->event->body.len== 8 &&
			(strncasecmp(msg->event->body.s,"presence",8 )==0))
		event_flag|= PRESENCE_EVENT;
	else
	if(msg->event->body.len== 14 &&
			(strncasecmp(msg->event->body.s,"presence.winfo",14 )==0))
//.........这里部分代码省略.........
开发者ID:Danfx,项目名称:opensips,代码行数:101,代码来源:simple2xmpp.c

示例6: ims_find_credentials

/*
 * Find credentials with given realm in a SIP message header
 */
inline int ims_find_credentials(struct sip_msg* _m, str* _realm,
		hdr_types_t _hftype, struct hdr_field** _h) {
	struct hdr_field** hook, *ptr, *prev;
	hdr_flags_t hdr_flags;
	int res;
	str* r;

	LM_DBG("Searching credentials in realm [%.*s]\n", _realm->len, _realm->s);

	/*
	 * Determine if we should use WWW-Authorization or
	 * Proxy-Authorization header fields, this parameter
	 * is set in www_authorize and proxy_authorize
	 */
	switch (_hftype) {
	case HDR_AUTHORIZATION_T:
		hook = &(_m->authorization);
		hdr_flags = HDR_AUTHORIZATION_F;
		break;
	case HDR_PROXYAUTH_T:
		hook = &(_m->proxy_auth);
		hdr_flags = HDR_PROXYAUTH_F;
		break;
	default:
		hook = &(_m->authorization);
		hdr_flags = HDR_T2F(_hftype);
		break;
	}

	/*
	 * If the credentials haven't been parsed yet, do it now
	 */
	if (*hook == 0) {
		/* No credentials parsed yet */
		LM_DBG("*hook == 0, No credentials parsed yet\n");
		if (parse_headers(_m, hdr_flags, 0) == -1) {
			LM_ERR("Error while parsing headers\n");
			return -1;
		}
	}

	ptr = *hook;
	LM_DBG("*hook = %p\n", ptr);
	/*
	 * Iterate through the credentials in the message and
	 * find credentials with given realm
	 */
	while (ptr) {
		res = parse_credentials(ptr);
		if (res < 0) {
			LM_ERR("Error while parsing credentials\n");
			return (res == -1) ? -2 : -3;
		} else if (res == 0) {
			LM_DBG("Credential parsed successfully\n");
			if (_realm->len) {
				r = &(((auth_body_t*) (ptr->parsed))->digest.realm);
				LM_DBG("Comparing realm <%.*s> and <%.*s>\n", _realm->len, _realm->s, r->len, r->s);
				if (r->len == _realm->len) {
					if (!strncasecmp(_realm->s, r->s, r->len)) {
						*_h = ptr;
						return 0;
					}
				}
			} else {
				*_h = ptr;
				return 0;
			}

		}

		prev = ptr;
		if (parse_headers(_m, hdr_flags, 1) == -1) {
			LM_ERR("Error while parsing headers\n");
			return -4;
		} else {
			if (prev != _m->last_header) {
				if (_m->last_header->type == _hftype)
					ptr = _m->last_header;
				else
					break;
			} else
				break;
		}
	}

	/*
	 * Credentials with given realm not found
	 */
	LM_DBG("Credentials with given realm not found\n");
	return 1;
}
开发者ID:gbour,项目名称:kamailio,代码行数:94,代码来源:utils.c

示例7: __dialog_sendpublish

static void
__dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
{
	str tag = {0,0};
	struct to_body from;
	str peer_uri= {0, 0};
	char flag = DLG_PUB_AB;
	str flag_str;
	struct to_body peer_to_body;
	str entity_uri= {0, 0};
	int buf_len = 255;

	flag_str.s = &flag;
	flag_str.len = 1;

	memset(&from, 0, sizeof(struct to_body));
	memset(&peer_to_body, 0, sizeof(struct to_body));

	from.uri = dlg->from_uri;

	peer_uri.len = buf_len;
	peer_uri.s = (char*)pkg_malloc(buf_len);
	if(peer_uri.s == NULL)
	{
		LM_ERR("No more memory\n");
		goto error;
	}
	/* extract the peer_uri */
	if(dlg_api.fetch_dlg_value(dlg, &peer_dlg_var, &peer_uri, 1) < 0 || peer_uri.len==0)
	{
		LM_ERR("Failed to fetch peer uri dialog variable\n");
		goto error;
	}

	LM_DBG("peer_uri = %.*s\n", peer_uri.len, peer_uri.s);

	parse_to(peer_uri.s, peer_uri.s+peer_uri.len, &peer_to_body);
	if(peer_to_body.error != PARSE_OK)
	{
		LM_ERR("Failed to peer uri [%.*s]\n", peer_uri.len, peer_uri.s);
		goto error;
	}

	/* try to extract the flag */
	dlg_api.fetch_dlg_value(dlg, &flag_dlg_var, &flag_str, 1);
	LM_DBG("flag = %c\n", flag);

	entity_uri.len = buf_len;
	entity_uri.s = (char*)pkg_malloc(buf_len);
	if(entity_uri.s == NULL)
	{
		LM_ERR("No more memory\n");
		goto error;
	}
	/* check if entity is also custom */
	if(dlg_api.fetch_dlg_value(dlg, &entity_dlg_var, &entity_uri, 1) == 0)
	{
		/* overwrite from with this value */
		parse_to(entity_uri.s, entity_uri.s + entity_uri.len, &from);
		if(from.error != PARSE_OK)
		{
			LM_ERR("Wrong format for entity body\n");
			goto error;
		}
		LM_DBG("entity_uri = %.*s\n", entity_uri.len, entity_uri.s);
		LM_DBG("from uri = %.*s\n", from.uri.len, from.uri.s);
	}

	switch (type) {
	case DLGCB_FAILED:
	case DLGCB_TERMINATED:
	case DLGCB_EXPIRED:
		LM_DBG("dialog over, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			dialog_publish("terminated", &from, &peer_to_body, &(dlg->callid), 1, 0, 0, 0);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			dialog_publish("terminated", &peer_to_body, &from, &(dlg->callid), 0, 0, 0, 0);
		break;
	case DLGCB_CONFIRMED:
	case DLGCB_REQ_WITHIN:
		LM_DBG("dialog confirmed, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_A)
			dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, 0, 0);
		if(flag == DLG_PUB_AB || flag == DLG_PUB_B)
			dialog_publish("confirmed", &peer_to_body, &from, &(dlg->callid), 0, dlg->lifetime, 0, 0);
		break;
	case DLGCB_EARLY:
		LM_DBG("dialog is early, from=%.*s\n", from.uri.len, from.uri.s);
		if (include_tags) {
			/* get to tag*/
			if ( !_params->msg->to && ((parse_headers(_params->msg, HDR_TO_F,0)<0) || !_params->msg->to) ) {
				LM_ERR("bad reply or missing TO hdr :-/\n");
				tag.s = 0;
				tag.len = 0;
			} else {
				tag = get_to(_params->msg)->tag_value;
				if (tag.s==0 || tag.len==0) {
					LM_ERR("missing TAG param in TO hdr :-/\n");
					tag.s = 0;
					tag.len = 0;
//.........这里部分代码省略.........
开发者ID:UIKit0,项目名称:OpenSIPS,代码行数:101,代码来源:pua_dialoginfo.c

示例8: decode_contact_header

	int
decode_contact_header (struct sip_msg *msg,char *unused1,char *unused2)
{

	contact_body_t *cb;
	contact_t *c;
	str uri;
	str newUri;
	char separator;
	int res;


#ifdef DEBUG
	str* ruri;
	fprintf (stdout,"---START--------DECODE CONTACT HEADER-----------------\n");
#endif

	if ((msg->contact == NULL)&&((parse_headers(msg,HDR_CONTACT_F,0) == -1) ||
				(msg->contact== NULL) ))
	{
		LM_ERR("no Contact header present\n");
		return -1;
	}

	separator = DEFAULT_SEPARATOR[0];
	if (contact_flds_separator != NULL)
		if (strlen(contact_flds_separator)>=1)
			separator = contact_flds_separator[0];

#ifdef DEBUG
	fprintf (stdout,"Using separator %c\n",separator);
	ruri = GET_RURI(msg);
	fprintf (stdout,"[len = %d]New uri is->%.*s\n",
			ruri->len,ruri->len,ruri->s);
	ruri = &msg->first_line.u.request.uri;
	fprintf (stdout, "INITIAL.s=[%.*s]\n", ruri->len, ruri->s);
#endif

	if (msg->contact->parsed == NULL) parse_contact (msg->contact);
	if (msg->contact->parsed != NULL)
	{
		cb = (contact_body_t *) msg->contact->parsed;
		c = cb->contacts;
		// we visit each contact
		if (c != NULL)
		{
			uri = c->uri;

			res = decode_uri (uri, separator, &newUri);
#ifdef DEBUG
			fprintf (stdout, "newuri.s=[%.*s]\n", newUri.len, newUri.s);
#endif
			if (res != 0)
			{
				LM_ERR("failed decoding contact.Code %d\n", res);
#ifdef STRICT_CHECK
				return res;
#endif
			}
			else
				if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
				{
					LM_ERR("lumping failed in mangling port \n");
					return -2;
				}

#ifdef DECODE_ALL_CONTACTS
			while (c->next != NULL)
			{
				c = c->next;
				uri = c->uri;

				res = decode_uri (uri, separator, &newUri);
				if (res != 0)
				{
					LM_ERR("failed decoding contact.Code %d\n",res);
#ifdef STRICT_CHECK
					return res;
#endif
				}
				else
					if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
					{
						LM_ERR("lumping failed in mangling port \n");
						return -3;
					}
			} // end while
#endif
		} // if c!= NULL
	} // end if
	else // after parsing still NULL
	{
		LM_ERR("unable to parse Contact header\n");
		return -4;
	}
#ifdef DEBUG
	fprintf (stdout,"---END--------DECODE CONTACT HEADER-----------------\n");fflush(stdout);
#endif
	return 1;
}
开发者ID:TheGrandWazoo,项目名称:kamailio,代码行数:100,代码来源:contact_ops.c

示例9: encode_contact

//#define DEBUG
	int
encode_contact (struct sip_msg *msg, char *encoding_prefix,char *public_ip)
{

	contact_body_t *cb;
	contact_t *c;
	str uri;
	str newUri;
	int res;
	char separator;



	/*
	 * I have a list of contacts in contact->parsed which is of type contact_body_t
	 * inside i have a contact->parsed->contact which is the head of the list of contacts
	 * inside it is a
	 * str uri;
	 * struct contact *next;
	 * I just have to visit each uri and encode each uri according to a scheme
	 */

	if ((msg->contact == NULL)&&((parse_headers(msg,HDR_CONTACT_F,0) == -1) ||
				(msg->contact == NULL) ))
	{
		LM_ERR("no Contact header present\n");
		return -1;
	}


	separator = DEFAULT_SEPARATOR[0];
	if (contact_flds_separator != NULL)
		if (strlen(contact_flds_separator)>=1)
			separator = contact_flds_separator[0];

	if (msg->contact->parsed == NULL)	parse_contact (msg->contact);
	if (msg->contact->parsed != NULL)
	{
		cb = (contact_body_t *) msg->contact->parsed;
		c = cb->contacts;
		/* we visit each contact */
		if (c != NULL)
		{
			uri = c->uri;
			res = encode_uri (uri, encoding_prefix, public_ip,separator, &newUri);

			if (res != 0)
			{
				LM_ERR("failed encoding contact.Code %d\n", res);
#ifdef STRICT_CHECK
				return res;
#endif
			}
			else
				if (patch (msg, uri.s, uri.len, newUri.s, newUri.len) < 0)
				{
					LM_ERR("lumping failed in mangling port \n");
					return -2;
				}

			/* encoding next contacts too?*/
#ifdef ENCODE_ALL_CONTACTS
			while (c->next != NULL)
			{
				c = c->next;
				uri = c->uri;

				res = encode_uri (uri, encoding_prefix,public_ip,separator,&newUri);
				if (res != 0)
				{
					LM_ERR("failed encode_uri.Code %d\n",res);
#ifdef STRICT_CHECK
					return res;
#endif
				}
				else
					if (patch (msg, uri.s, uri.len, newUri.s, newUri.len)< 0)
					{
						LM_ERR("lumping failed in mangling port \n");
						return -3;
					}
			} /* while */
#endif /* ENCODE_ALL_CONTACTS */
		} /* if c != NULL */

	} /* end if */
	else /* after parsing still NULL */
	{
		LM_ERR("unable to parse Contact header\n");
		return -4;
	}
	return 1;
}
开发者ID:TheGrandWazoo,项目名称:kamailio,代码行数:94,代码来源:contact_ops.c

示例10: xjab_manage_sipmsg

/**
 * manage SIP message
 */
int xjab_manage_sipmsg(struct sip_msg *msg, int type)
{
	str body, dst, from_uri;
	xj_sipmsg jsmsg;
	int pipe, fl;
	t_xj_jkey jkey, *p;
	int mime;

	body.s=0;  /* fixes gcc 4.0 warning */
	body.len=0;
	// extract message body - after that whole SIP MESSAGE is parsed
	if (type==XJ_SEND_MESSAGE)
	{
		/* get the message's body */
		body.s = get_body( msg );
		if(body.s==0)
		{
			LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR cannot extract body from"
				" msg\n");
			goto error;
		}

		/* content-length (if present) must be already parsed */
		if(!msg->content_length)
		{
			LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR no Content-Length"
					" header found!\n");
			goto error;
		}
		body.len = get_content_length(msg);

		/* parse the content-type header */
		if((mime=parse_content_type_hdr(msg))<1)
		{
			LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR cannot parse"
					" Content-Type header\n");
			goto error;
		}

		/* check the content-type value */
		if(mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
			&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM)
		{
			LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR invalid content-type for"
				" a message request! type found=%d\n", mime);
			goto error;
		}
	}

	// check for TO and FROM headers - if is not SIP MESSAGE
	if(parse_headers( msg, HDR_TO_F|HDR_FROM_F, 0)==-1 || !msg->to
			|| !msg->from)
	{
		LOG(L_ERR,"XJAB:xjab_manage_sipmsg: cannot find TO or FROM HEADERS!\n");
		goto error;
	}

	/* parsing from header */
	if ( parse_from_header( msg )==-1 || msg->from->parsed==NULL)
	{
		DBG("ERROR:xjab_manage_sipmsg: cannot get FROM header\n");
		goto error;
	}
	from_uri.s = ((struct to_body*)msg->from->parsed)->uri.s;
	from_uri.len = ((struct to_body*)msg->from->parsed)->uri.len;
	if(xj_extract_aor(&from_uri, 0))
	{
		DBG("ERROR:xjab_manage_sipmsg: cannot get AoR from FROM header\n");
		goto error;
	}

	jkey.hash = xj_get_hash(&from_uri, NULL);
	jkey.id = &from_uri;
	// get the communication pipe with the worker
	switch(type)
	{
		case XJ_SEND_MESSAGE:
		case XJ_JOIN_JCONF:
		case XJ_GO_ONLINE:
			if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0)
			{
				DBG("XJAB:xjab_manage_sipmsg: cannot find pipe of the worker!\n");
				goto error;
			}
		break;
		case XJ_EXIT_JCONF:
		case XJ_GO_OFFLINE:
			if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0)
			{
				DBG("XJAB:xjab_manage_sipmsg: no open Jabber session for"
						" <%.*s>!\n", from_uri.len, from_uri.s);
				goto error;
			}
		break;
		default:
			DBG("XJAB:xjab_manage_sipmsg: ERROR:strange SIP msg type!\n");
			goto error;
//.........这里部分代码省略.........
开发者ID:4N7HR4X,项目名称:kamailio,代码行数:101,代码来源:jabber.c

示例11: parse_msg

/* returns 0 if ok, -1 for errors */
int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
{

	char *tmp;
	char* rest;
	struct msg_start *fl;
	int offset;
	hdr_flags_t flags;

	/* eat crlf from the beginning */
	for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
			(unsigned int)(tmp-buf) < len ; tmp++);
	offset=tmp-buf;
	fl=&(msg->first_line);
	rest=parse_first_line(tmp, len-offset, fl);

	offset+=rest-tmp;
	tmp=rest;
	switch(fl->type){
		case SIP_INVALID:
			LM_DBG("invalid message\n");
			/* if failed to parse the first line, we simply consider that the whole
			   buffer was parsed, so that nothing is left to be parsed :) - this will
			   do the trick and make "msg" struct acceptable for following parsing
			   attempts */
			msg->unparsed = msg->buf + msg->len;
			goto error;
			break;
		case SIP_REQUEST:
			LM_DBG("SIP Request:\n");
			LM_DBG(" method:  <%.*s>\n",fl->u.request.method.len,
				ZSW(fl->u.request.method.s));
			LM_DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
				ZSW(fl->u.request.uri.s));
			LM_DBG(" version: <%.*s>\n",fl->u.request.version.len,
				ZSW(fl->u.request.version.s));
			flags=HDR_VIA_F;
			break;
		case SIP_REPLY:
			LM_DBG("SIP Reply  (status):\n");
			LM_DBG(" version: <%.*s>\n",fl->u.reply.version.len,
					ZSW(fl->u.reply.version.s));
			LM_DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
					ZSW(fl->u.reply.status.s));
			LM_DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
					ZSW(fl->u.reply.reason.s));
			flags=HDR_VIA_F;
			break;
		default:
			LM_DBG("unknown type %d\n",fl->type);
			goto error;
	}
	msg->unparsed=tmp;
	/*find first Via: */
	if (parse_headers(msg, flags, 0)==-1) goto error;

#ifdef EXTRA_DEBUG
	/* dump parsed data */
	if (msg->via1){
		LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
			msg->via1->name.len,
			ZSW(msg->via1->name.s),
			msg->via1->version.len,
			ZSW(msg->via1->version.s),
			msg->via1->transport.len,
			ZSW(msg->via1->transport.s),
			msg->via1->host.len,
			ZSW(msg->via1->host.s),
			msg->via1->port_str.len,
			ZSW(msg->via1->port_str.s),
			msg->via1->port);
		if (msg->via1->params.s)  LM_DBG(";<%.*s>",
				msg->via1->params.len, ZSW(msg->via1->params.s));
		if (msg->via1->comment.s)
				LM_DBG(" <%.*s>",
					msg->via1->comment.len, ZSW(msg->via1->comment.s));
		LM_DBG ("\n");
	}
	if (msg->via2){
		LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
			msg->via2->name.len,
			ZSW(msg->via2->name.s),
			msg->via2->version.len,
			ZSW(msg->via2->version.s),
			msg->via2->transport.len,
			ZSW(msg->via2->transport.s),
			msg->via2->host.len,
			ZSW(msg->via2->host.s),
			msg->via2->port_str.len,
			ZSW(msg->via2->port_str.s),
			msg->via2->port);
		if (msg->via2->params.s)  LM_DBG(";<%.*s>",
				msg->via2->params.len, ZSW(msg->via2->params.s));
		if (msg->via2->comment.s) LM_DBG(" <%.*s>",
				msg->via2->comment.len, ZSW(msg->via2->comment.s));
		LM_DBG ("\n");
	}
#endif

//.........这里部分代码省略.........
开发者ID:alias-neo,项目名称:opensips,代码行数:101,代码来源:msg_parser.c

示例12: do_forward_reply

/* removes first via & sends msg to the second
 * - mode param controls if modules sip response callbacks are executed */
static int do_forward_reply(struct sip_msg* msg, int mode)
{
	char* new_buf;
	struct dest_info dst;
	unsigned int new_len;
	int r;
#ifdef USE_TCP
	char* s;
	int len;
#endif
	init_dest_info(&dst);
	new_buf=0;
	/*check if first via host = us */
	if (check_via){
		if (check_self(&msg->via1->host,
					msg->via1->port?msg->via1->port:SIP_PORT,
					msg->via1->proto)!=1){
			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
					" %.*s:%d\n", msg->via1->host.len, msg->via1->host.s,
									msg->via1->port);
			/* send error msg back? */
			goto error;
		}
	}
	
	/* check modules response_f functions */
	if(likely(mode==0)) {
		for (r=0; r<mod_response_cbk_no; r++)
			if (mod_response_cbks[r](msg)==0) goto skip;
	}
	/* we have to forward the reply stateless, so we need second via -bogdan*/
	if (parse_headers( msg, HDR_VIA2_F, 0 )==-1 
		|| (msg->via2==0) || (msg->via2->error!=PARSE_OK))
	{
		/* no second via => error */
		LOG(L_DBG, "reply cannot be forwarded - no 2nd via\n");
		goto error;
	}

	new_buf = build_res_buf_from_sip_res( msg, &new_len);
	if (!new_buf){
		LOG(L_ERR, "ERROR: forward_reply: building failed\n");
		goto error;
	}

	dst.proto=msg->via2->proto;
	SND_FLAGS_OR(&dst.send_flags, &msg->fwd_send_flags, &msg->rpl_send_flags);
	if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
#ifdef USE_COMP
	dst.comp=msg->via2->comp_no;
#endif

#if defined USE_TCP || defined USE_SCTP
	if (
#ifdef USE_TCP
			dst.proto==PROTO_TCP
			|| dst.proto==PROTO_WS
#ifdef USE_TLS
			|| dst.proto==PROTO_TLS
			|| dst.proto==PROTO_WSS
#endif
#ifdef USE_SCTP
			||
#endif /* USE_SCTP */
#endif /* USE_TCP */
#ifdef USE_SCTP
			dst.proto==PROTO_SCTP
#endif /* USE_SCTP */
			){
		/* find id in i param if it exists */
		if (msg->via1->i && msg->via1->i->value.s){
			s=msg->via1->i->value.s;
			len=msg->via1->i->value.len;
			DBG("forward_reply: i=%.*s\n",len, ZSW(s));
			if (reverse_hex2int(s, len, (unsigned int*)&dst.id)<0){
				LOG(L_ERR, "ERROR: forward_reply: bad via i param \"%.*s\"\n",
						len, ZSW(s));
					dst.id=0;
			}
		}		
				
	} 
#endif

	apply_force_send_socket(&dst, msg);

	if (msg_send(&dst, new_buf, new_len)<0)
	{
		STATS_RPL_FWD_DROP();
		goto error;
	}
	/* call onsend_route */
	if(dst.send_sock == NULL) {
		dst.send_sock=get_send_socket(msg, &dst.to, dst.proto);
		if (dst.send_sock==0){
			LOG(L_ERR, "forward_reply: ERROR: cannot forward reply\n");
			goto done;
		}
//.........这里部分代码省略.........
开发者ID:carlosp,项目名称:kamailio,代码行数:101,代码来源:forward.c

示例13: forward_reply

/*! \brief removes first via & sends msg to the second */
int forward_reply(struct sip_msg* msg)
{
	char* new_buf;
	union sockaddr_union* to;
	unsigned int new_len;
	struct sr_module *mod;
	int proto;
	int id; /* used only by tcp*/
	struct socket_info *send_sock;
#ifdef USE_TCP
	char* s;
	int len;
#endif
	
	to=0;
	id=0;
	new_buf=0;
	/*check if first via host = us */
	if (check_via){
		if (check_self(&msg->via1->host,
					msg->via1->port?msg->via1->port:SIP_PORT,
					msg->via1->proto)!=1){
			LM_ERR("host in first via!=me : %.*s:%d\n", 
				msg->via1->host.len, msg->via1->host.s,	msg->via1->port);
			/* send error msg back? */
			goto error;
		}
	}
	/* quick hack, slower for multiple modules*/
	for (mod=modules;mod;mod=mod->next){
		if ((mod->exports) && (mod->exports->response_f)){
			LM_DBG("found module %s, passing reply to it\n",
					mod->exports->name);
			if (mod->exports->response_f(msg)==0) goto skip;
		}
	}

	/* if stateless fwd was disabled, we cannot have stateless replies here*/
	if (sl_fwd_disabled)
		goto skip;

	/* we have to forward the reply stateless, so we need second via -bogdan*/
	if (parse_headers( msg, HDR_VIA2_F, 0 )==-1 
		|| (msg->via2==0) || (msg->via2->error!=PARSE_OK))
	{
		/* no second via => error */
		LM_ERR("no 2nd via found in reply from %s:%d <%.*s>\n",
			ip_addr2a(&msg->rcv.src_ip),msg->rcv.src_port, msg->len,msg->buf );
		goto error;
	}

	to=(union sockaddr_union*)pkg_malloc(sizeof(union sockaddr_union));
	if (to==0){
		LM_ERR("out of pkg memory\n");
		goto error;
	}

	proto=msg->via2->proto;
	if (update_sock_struct_from_via( to, msg, msg->via2 )==-1) goto error;

#ifdef USE_TCP
	if (proto==PROTO_TCP
#ifdef USE_TLS
			|| proto==PROTO_TLS
#endif
			){
		/* find id in i param if it exists */
		if (msg->via1->i&&msg->via1->i->value.s){
			s=msg->via1->i->value.s;
			len=msg->via1->i->value.len;
			id=reverse_hex2int(s, len);
		}
	}
#endif

	send_sock = get_send_socket(msg, to, proto);

	new_buf = build_res_buf_from_sip_res( msg, &new_len, send_sock);
	if (!new_buf){
		LM_ERR("failed to build rpl from req failed\n");
		goto error;
	}

	if (msg_send(send_sock, proto, to, id, new_buf, new_len)<0) {
		update_stat( drp_rpls, 1);
		goto error0;
	}
	update_stat( fwd_rpls, 1);
	/*
	 * If no port is specified in the second via, then this
	 * message output a wrong port number - zero. Despite that
	 * the correct port is choosen in update_sock_struct_from_via,
	 * as its visible with su_getport(to); .
	 */
	LM_DBG("reply forwarded to %.*s:%d\n", msg->via2->host.len, 
		msg->via2->host.s, (unsigned short) msg->via2->port);

	pkg_free(new_buf);
	pkg_free(to);
//.........这里部分代码省略.........
开发者ID:iamroger,项目名称:voip,代码行数:101,代码来源:forward.c

示例14: select_anyheader

int select_anyheader(str* res, select_t* s, struct sip_msg* msg)
{
	struct hdr_field *hf, *hf0;
	int hi;
	char c;
	struct hdr_field hdr;
	
	if(msg==NULL) {
		if (res!=NULL) return -1;

		/* "fixup" call, res & msg are NULL */
		if (s->n <3) return -1;

		if (s->params[2].type==SEL_PARAM_STR) {
				/* replace _ with - (for P-xxx headers) */
			for (hi=s->params[2].v.s.len-1; hi>0; hi--)
				if (s->params[2].v.s.s[hi]=='_')
					s->params[2].v.s.s[hi]='-';
				/* if header name is parseable, parse it and set SEL_PARAM_DIV */
			c=s->params[2].v.s.s[s->params[2].v.s.len];
			s->params[2].v.s.s[s->params[2].v.s.len]=':';
			if (parse_hname2(s->params[2].v.s.s,s->params[2].v.s.s+(s->params[2].v.s.len<3?4:s->params[2].v.s.len+1),
						&hdr)==0) {
				ERR("select_anyhdr:fixup_call:parse error\n");
				return -1;
			}
			s->params[2].v.s.s[s->params[2].v.s.len]=c;
			
			if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T) {
				/* pkg_free(s->params[1].v.s.s); */
				/* don't free it (the mem can leak only once at startup)
				 * the parsed string can live inside larger string block
				 * e.g. when xlog's select is parsed
				 */
				s->params[2].type = SEL_PARAM_DIV;
				s->params[2].v.i = hdr.type;
			}
		}
		return 1;
	}

	hf0 = NULL;

	/* extract header index if present */
	if (s->param_offset[s->lvl+1] == 4) {
		if (s->params[3].type == SEL_PARAM_INT) {
			hi = s->params[3].v.i;
		} else {
			hi = -1;
		}
	} else {
		hi = 1;
	}

	/* we need to be sure we have parsed all headers */
	if (!msg->eoh && (parse_headers(msg,HDR_EOH_F,0)==-1 || !msg->eoh)) {
		ERR("bad msg while parsing to EOH \n");
		return -1;
	}
	for (hf=msg->headers; hf; hf=hf->next) {
		if(s->params[2].type==SEL_PARAM_DIV) {
			if (s->params[2].v.i!=hf->type)	continue;
		} else if(s->params[2].type==SEL_PARAM_STR) {
			if (s->params[2].v.s.len!=hf->name.len)	continue;
			if (strncasecmp(s->params[2].v.s.s, hf->name.s, hf->name.len)!=0) continue;
		}
		hf0 = hf;
		hi--;
		if (!hi) break;
	}
	if(hf0==NULL || hi>0)
		return 1;
	res->s = hf0->body.s;
	res->len = hf0->body.len;
	trim(res);
	return 0;
}
开发者ID:asyn,项目名称:openvims,代码行数:77,代码来源:select_core.c

示例15: subs_cback_func

void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
{
	struct sip_msg* msg= NULL;
	int lexpire= 0;
	unsigned int cseq;
	ua_pres_t* presentity= NULL, *hentity= NULL;
	struct to_body *pto = NULL, TO = {0}, *pfrom = NULL;
	int size= 0;
	unsigned int hash_code;
	int flag ;
	str record_route= {0, 0};
	int rt;
	str contact;
	int initial_request = 0;
	int end_transaction = 1;

	if( ps->param== NULL || *ps->param== NULL )
	{
		LM_ERR("null callback parameter\n");
		return;
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	LM_DBG("completed with status %d\n",ps->code) ;
	hentity= (ua_pres_t*)(*ps->param);
	hash_code= core_hash(hentity->pres_uri,hentity->watcher_uri,
				HASH_SIZE);
	flag= hentity->flag;
	if(hentity->flag & XMPP_INITIAL_SUBS)
		hentity->flag= XMPP_SUBSCRIBE;

	/* get dialog information from reply message: callid, to_tag, from_tag */
	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n ");
		goto error;
	}

	if(msg== FAKED_REPLY)
	{
		struct hdr_field *callid = NULL, *from = NULL;
		struct to_body FROM = {0};

		callid = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (callid == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(callid, 0, sizeof(struct hdr_field));
		get_hdr_field(t->callid.s, t->callid.s + t->callid.len, callid);
		hentity->call_id = callid->body;

		from = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (from == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(from, 0, sizeof(struct hdr_field));
		get_hdr_field(t->from.s, t->from.s + t->from.len, from);
		parse_to(from->body.s, from->body.s + from->body.len + 1, &FROM);
		if(FROM.uri.len <= 0) 
		{
			LM_ERR("'From' header NOT parsed\n");
			goto faked_error;
		}
	
		hentity->call_id = callid->body;
		hentity->from_tag = (&FROM)->tag_value;
		hentity->to_tag.s = NULL;
		hentity->to_tag.len = 0;

		find_and_delete_dialog(hentity, hash_code);
faked_error:
		if (callid) pkg_free(callid);
		free_to_params(&FROM);
		if (from) pkg_free(from);
		goto done;
	}
	
	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("when parsing headers\n");
		goto error;
	}

	if(ps->rpl->expires && msg->expires->body.len > 0)
	{
		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
		{
//.........这里部分代码省略.........
开发者ID:kiryu,项目名称:kamailio,代码行数:101,代码来源:send_subscribe.c


注:本文中的parse_headers函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。