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

📄 t_msgbuilder.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
		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;	}		     /* method, separators, version: "ACK sip:p2@iptel.org SIP/2.0" */	*len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;	*len += ruri.len;			     /* via */	send_sock = uri2sock(rpl, next_hop, &to_su, PROTO_NONE);	if (!send_sock) {		LOG(L_ERR, "build_dlg_ack: no socket found\n");		goto error;	}		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);	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_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_mem_block( p, ACK, ACK_LEN );	append_mem_block( p, " ", 1 );	append_str(p, ruri);	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, ACK, ACK_LEN);	append_mem_block(p, CRLF, CRLF_LEN);		     /* Routeset */	p = print_rs(p, list, cont);		     /* 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);	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){	memapp(w, method->s, method->len); 	memapp(w, " ", 1); 	t->uac[branch].uri.s = w; 	t->uac[branch].uri.len = dialog->hooks.request_uri->len;	memapp(w, dialog->hooks.request_uri->s, dialog->hooks.request_uri->len); 	memapp(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;	memapp(w, TO, TO_LEN);	memapp(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 ;		memapp(w, TOTAG, TOTAG_LEN);		memapp(w, dialog->id.rem_tag.s, dialog->id.rem_tag.len);	}	memapp(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;	memapp(w, FROM, FROM_LEN);	memapp(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;		memapp(w, FROMTAG, FROMTAG_LEN);		memapp(w, dialog->id.loc_tag.s, dialog->id.loc_tag.len);	}	memapp(w, CRLF, CRLF_LEN);	return w;}/* * Print CSeq header field */char* print_cseq_mini(char* target, str* cseq, str* method) {	memapp(target, CSEQ, CSEQ_LEN);	memapp(target, cseq->s, cseq->len);	memapp(target, " ", 1);	memapp(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) {	memapp(target, CALLID, CALLID_LEN);	memapp(target, callid.s, callid.len);	memapp(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...?!? */	memapp(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, struct socket_info* send_sock){	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, send_sock, branch) < 0) {		LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");		return 0;	}	*len += via.len;	*len += TO_LEN + dialog->rem_uri.len		+ (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0) + CRLF_LEN;    /* To */	*len += FROM_LEN + dialog->loc_uri.len		+ (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len) : 0) + CRLF_LEN;  /* From */	*len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;                                      /* Call-ID */	*len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN;                                    /* CSeq */	*len += calculate_routeset_length(dialog);                                                   /* Route set */	*len += (body ? (CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN) : 0);                   /* Content-Length */	*len += (server_signature ? (USER_AGENT_LEN + CRLF_LEN) : 0);                                /* Signature */	*len += (headers ? headers->len : 0);                                                        /* Additional headers */	*len += (body ? body->len : 0);                                                              /* Message body */	*len += CRLF_LEN;                                                                            /* End of Header */	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 */	memapp(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) {		memapp(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN);		memapp(w, content_length.s, content_length.len);		memapp(w, CRLF, CRLF_LEN);	}		     /* Server signature */	if (server_signature) memapp(w, USER_AGENT CRLF, USER_AGENT_LEN + CRLF_LEN);	if (headers) memapp(w, headers->s, headers->len);	memapp(w, CRLF, CRLF_LEN);     	if (body) memapp(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 + -