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

📄 t_msgbuilder.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 for a local INVITE. If 200 OK, route set  * will be created and parsed */char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,							unsigned int branch, str* to, unsigned int *len){	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;	str next_hop;	if (rpl->first_line.u.reply.statuscode < 300 ) {		/* build e2e ack for 2xx reply -> we need the route set */		if (get_contact_uri(rpl, &contact) < 0) {			return 0;		}		if (process_routeset(rpl, &contact, &list, &ruri, &next_hop) < 0) {			return 0;		}		if ((contact.s != ruri.s) || (contact.len != ruri.len)) {			/* contact != ruri means that the next			 * hop is a strict router, cont will be non-zero			 * and print_routeset will append it at the end			 * of the route set			 */			cont = &contact;		} else {			/* Next hop is a loose router, nothing to append */			cont = 0;		}	} else {		/* build hop-by-hop ack for negative reply ->		 * ruri is the same as in INVITE; no route set */		ruri = Trans->uac[branch].uri;		cont = 0;		list = 0;	}	/* method, separators, version: "ACK sip:user@domain.org SIP/2.0" */	*len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;	*len += ruri.len;	/* use same socket as for INVITE -bogdan */	send_sock = Trans->uac[branch].request.dst.send_sock;	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, 0);	/* build via */	via = via_builder(&via_len, send_sock, &branch_str, 0, 			send_sock->proto, &hp);	if (!via) {		LOG(L_ERR, "build_dlg_ack: 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 + ACK_LEN + CRLF_LEN;	/* copy'n'paste Route headers */	*len += calc_routeset_len(list, cont);	/* User Agent */	if (server_signature)		*len += user_agent_header.len + CRLF_LEN;	/* Content Length, EoM */	*len += CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN;	req_buf = shm_malloc(*len + 1);	if (!req_buf) {		LOG(L_ERR, "build_dlg_ack: Cannot allocate memory\n");		goto error01;	}	p = req_buf;	append_string( p, ACK " ", ACK_LEN+1 );	append_string(p, ruri.s, ruri.len );	append_string( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);	/* insert our via */	append_string(p, via, via_len);	/*other headers*/	append_string(p, Trans->from.s, Trans->from.len);	append_string(p, Trans->callid.s, Trans->callid.len);	append_string(p, to->s, to->len);	append_string(p, Trans->cseq_n.s, Trans->cseq_n.len);	*(p++) = ' ';	append_string(p, ACK CRLF, ACK_LEN+CRLF_LEN);	/* Routeset */	p = print_rs(p, list, cont);	/* User Agent header, Content Length, EoM */	if (server_signature) {		append_string(p, user_agent_header.s, user_agent_header.len);		append_string(p, CRLF CONTENT_LENGTH "0" CRLF CRLF,			CRLF_LEN+CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);	} else {		append_string(p, CONTENT_LENGTH "0" CRLF CRLF,			CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);	}	*p = 0;	pkg_free(via);	free_rte_list(list);	return req_buf;error01:	pkg_free(via);error:	free_rte_list(list);	return 0;}/* * Convert length of body into asciiz */static inline int print_content_length(str* dest, str* body){	static char content_length[10];	int len;	char* tmp;	     /* Print Content-Length */	if (body) {		tmp = int2str(body->len, &len);		if (len >= sizeof(content_length)) {			LOG(L_ERR, "ERROR: print_content_length: content_len too big\n");			return -1;		}		memcpy(content_length, tmp, len); 		dest->s = content_length;		dest->len = len;	} else {		dest->s = 0;		dest->len = 0;	}	return 0;}/* * Convert CSeq number into asciiz */static inline int print_cseq_num(str* _s, dlg_t* _d){	static char cseq[INT2STR_MAX_LEN];	char* tmp;	int len;	tmp = int2str(_d->loc_seq.value, &len);	if (len > sizeof(cseq)) {		LOG(L_ERR, "print_cseq_num: cseq too big\n");		return -1;	}		memcpy(cseq, tmp, len);	_s->s = cseq;	_s->len = len;	return 0;}/* * Create Via header */static inline int assemble_via(str* dest, struct cell* t, struct socket_info* sock, int branch){	static char branch_buf[MAX_BRANCH_PARAM_LEN];	char* via;	int len;	unsigned int via_len;	str branch_str;	struct hostport hp;	if (!t_calc_branch(t, branch, branch_buf, &len)) {		LOG(L_ERR, "ERROR: assemble_via: branch calculation failed\n");		return -1;	}		branch_str.s = branch_buf;	branch_str.len = len;#ifdef XL_DEBUG	printf("!!!proto: %d\n", sock->proto);#endif	set_hostport(&hp, 0);	via = via_builder(&via_len, sock, &branch_str, 0, sock->proto, &hp);	if (!via) {		LOG(L_ERR, "assemble_via: via building failed\n");		return -2;	}		dest->s = via;	dest->len = via_len;	return 0;}/* * Print Request-URI */static inline char* print_request_uri(char* w, str* method, dlg_t* dialog, struct cell* t, int branch){	append_string(w, method->s, method->len); 	append_string(w, " ", 1); 	t->uac[branch].uri.s = w; 	t->uac[branch].uri.len = dialog->hooks.request_uri->len;	append_string(w, dialog->hooks.request_uri->s, dialog->hooks.request_uri->len); 	append_string(w, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);	return w;}/* * Print To header field */static inline char* print_to(char* w, dlg_t* dialog, struct cell* t){	t->to.s = w;	t->to.len = TO_LEN + dialog->rem_uri.len + CRLF_LEN;	append_string(w, TO, TO_LEN);	append_string(w, dialog->rem_uri.s, dialog->rem_uri.len);	if (dialog->id.rem_tag.len) {		t->to.len += TOTAG_LEN + dialog->id.rem_tag.len ;		append_string(w, TOTAG, TOTAG_LEN);		append_string(w, dialog->id.rem_tag.s, dialog->id.rem_tag.len);	}	append_string(w, CRLF, CRLF_LEN);	return w;}/* * Print From header field */static inline char* print_from(char* w, dlg_t* dialog, struct cell* t){	t->from.s = w;	t->from.len = FROM_LEN + dialog->loc_uri.len + CRLF_LEN;	append_string(w, FROM, FROM_LEN);	append_string(w, dialog->loc_uri.s, dialog->loc_uri.len);	if (dialog->id.loc_tag.len) {		t->from.len += FROMTAG_LEN + dialog->id.loc_tag.len;		append_string(w, FROMTAG, FROMTAG_LEN);		append_string(w, dialog->id.loc_tag.s, dialog->id.loc_tag.len);	}	append_string(w, CRLF, CRLF_LEN);	return w;}/* * Print CSeq header field */char* print_cseq_mini(char* target, str* cseq, str* method) {	append_string(target, CSEQ, CSEQ_LEN);	append_string(target, cseq->s, cseq->len);	append_string(target, " ", 1);	append_string(target, method->s, method->len);	return target;}static inline char* print_cseq(char* w, str* cseq, str* method, struct cell* t){	t->cseq_n.s = w; 	/* don't include method name and CRLF -- subsequent	 * local requests ACK/CANCEL will add their own */	t->cseq_n.len = CSEQ_LEN + cseq->len; 	w = print_cseq_mini(w, cseq, method);	return w;}/* * Print Call-ID header field * created an extra function for pure header field creation, that is used by t_cancel for  * t_uac_cancel FIFO function. */char* print_callid_mini(char* target, str callid) {	append_string(target, CALLID, CALLID_LEN);	append_string(target, callid.s, callid.len);	append_string(target, CRLF, CRLF_LEN);	return target;}static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t){	/* begins with CRLF, not included in t->callid, don`t know why...?!? */	append_string(w, CRLF, CRLF_LEN);	t->callid.s = w;	t->callid.len = CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;	w = print_callid_mini(w, dialog->id.call_id);	return w;}/* * Create a request */char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, 										int branch, struct cell *t, int* len){	char* buf, *w;	str content_length, cseq, via;	if (!method || !dialog) {		LOG(L_ERR, "build_uac_req(): Invalid parameter value\n");		return 0;	}	if (print_content_length(&content_length, body) < 0) {		LOG(L_ERR, "build_uac_req(): Error while printing content-length\n");		return 0;	}	if (print_cseq_num(&cseq, dialog) < 0) {		LOG(L_ERR, "build_uac_req(): Error while printing CSeq number\n");		return 0;	}	*len = method->len + 1 + dialog->hooks.request_uri->len + 1 + 		SIP_VERSION_LEN + CRLF_LEN;	if (assemble_via(&via, t, dialog->send_sock, branch) < 0) {		LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");		return 0;	}	*len += via.len;	/* To */	*len += TO_LEN + dialog->rem_uri.len		+ (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0)		+ CRLF_LEN;	/* From */	*len += FROM_LEN + dialog->loc_uri.len		+ (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len):0)		+ CRLF_LEN;	/* Call-ID */	*len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;	/* CSeq */	*len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN;	/* Route set */	*len += calculate_routeset_length(dialog);	/* Content-Length */	*len += (body ? (CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN) : 0);	/* Signature */	*len += (server_signature ? (user_agent_header.len + CRLF_LEN) : 0);	/* Additional headers */	*len += (headers ? headers->len : 0);	/* Message body */	*len += (body ? body->len : 0);	/* End of Header */	*len += CRLF_LEN;	buf = shm_malloc(*len + 1);	if (!buf) {		LOG(L_ERR, "build_uac_req(): no shmem\n");		goto error;	}		w = buf;	w = print_request_uri(w, method, dialog, t, branch);  /* Request-URI */	append_string(w, via.s, via.len);                     /* Top-most Via */	w = print_to(w, dialog, t);                           /* To */	w = print_from(w, dialog, t);                         /* From */	w = print_cseq(w, &cseq, method, t);                  /* CSeq */	w = print_callid(w, dialog, t);                       /* Call-ID */	w = print_routeset(w, dialog);                        /* Route set */	     /* Content-Length */	if (body) {		append_string(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN);		append_string(w, content_length.s, content_length.len);		append_string(w, CRLF, CRLF_LEN);	}		     /* Server signature */	if (server_signature) {		append_string(w, user_agent_header.s, user_agent_header.len);		append_string(w, CRLF, CRLF_LEN);	}	if (headers)		append_string(w, headers->s, headers->len);	append_string(w, CRLF, CRLF_LEN);	if (body)		append_string(w, body->s, body->len);#ifdef EXTRA_DEBUG	if (w-buf != *len ) abort();#endif	pkg_free(via.s);	return buf; error:	pkg_free(via.s);	return 0;}int t_calc_branch(struct cell *t, 	int b, char *branch, int *branch_len){	return syn_branch ?		branch_builder( t->hash_index,			t->label, 0,			b, branch, branch_len )		: branch_builder( t->hash_index,			0, t->md5,			b, branch, branch_len );}

⌨️ 快捷键说明

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