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

📄 t_reply.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 4 页
字号:
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);			     /* FR for negative INVITES, WAIT anything else */						     /* Call to set_final_timer is embedded in relay_reply to avoid			      * race conditions when reply is sent out and an ACK to stop retransmissions			      * comes before retransmission timer is set 			      *			      * set_final_timer(t); 			      */		} 	}		if (reply_status == RPS_ERROR) goto done;		     /* update FR/RETR timers on provisional replies */	if (msg_status < 200 && (restart_fr_on_each_reply ||				 ((last_uac_status<msg_status) &&				  ((msg_status >= 180) || (last_uac_status == 0)))				 ) ) { /* provisional now */		if (is_invite(t)) {			     /* invite: change FR to longer FR_INV, do not			      * attempt to restart retransmission any more			      */			backup_list = set_avp_list(&t->user_avps);			if (!fr_inv_avp2timer(&timer)) {				DBG("reply_received: FR_INV_TIMER = %d\n", timer);				set_timer(&uac->request.fr_timer,					  FR_INV_TIMER_LIST, &timer);			} else {				set_timer(& uac->request.fr_timer, FR_INV_TIMER_LIST, 0);			}			set_avp_list(backup_list);		} else {			     /* non-invite: restart retransmissions (slow now) */			uac->request.retr_list = RT_T2;			set_timer(&uac->request.retr_timer, RT_T2, 0);		}	} /* provisional replies */	 done:	     /* don't try to relay statelessly neither on success	      * (we forwarded statefully) nor on error; on troubles, 	      * simply do nothing; that will make the other party to 	      * retransmit; hopefuly, we'll then be better off 	      */	return 0;}int t_reply_with_body( struct cell *trans, unsigned int code, 		char * text, char * body, char * new_header, char * to_tag ){	struct lump_rpl *hdr_lump;	struct lump_rpl *body_lump;	str  s_to_tag;	str  rpl;	int  ret;	struct bookmark bm;	s_to_tag.s = to_tag;	if(to_tag)		s_to_tag.len = strlen(to_tag);	/* mark the transaction as replied */	if (code>=200) set_kr(REQ_RPLD);	/* add the lumps for new_header and for body (by bogdan) */	if (new_header && strlen(new_header)) {		hdr_lump = add_lump_rpl( trans->uas.request, new_header,					 strlen(new_header), LUMP_RPL_HDR );		if ( !hdr_lump ) {			LOG(L_ERR,"ERROR:tm:t_reply_with_body: cannot add hdr lump\n");			goto error;		}	} else {		hdr_lump = 0;	}	/* body lump */	if(body && strlen(body)) {		body_lump = add_lump_rpl( trans->uas.request, body, strlen(body),			LUMP_RPL_BODY );		if (body_lump==0) {			LOG(L_ERR,"ERROR:tm:t_reply_with_body: cannot add body lump\n");			goto error_1;		}	} else {		body_lump = 0;	}	rpl.s = build_res_buf_from_sip_req(			code, text, &s_to_tag,			trans->uas.request, (unsigned int*)&rpl.len, &bm);	/* since the msg (trans->uas.request) is a clone into shm memory, to avoid	 * memory leak or crashing (lumps are create in private memory) I will	 * remove the lumps by myself here (bogdan) */	if ( hdr_lump ) {		unlink_lump_rpl( trans->uas.request, hdr_lump);		free_lump_rpl( hdr_lump );	}	if( body_lump ) {		unlink_lump_rpl( trans->uas.request, body_lump);		free_lump_rpl( body_lump );	}	if (rpl.s==0) {		LOG(L_ERR,"ERROR:tm:t_reply_with_body: failed in doing "			"build_res_buf_from_sip_req()\n");		goto error;	}	DBG("t_reply_with_body: buffer computed\n");	// frees 'res.s' ... no panic !	ret=_reply_light( trans, rpl.s, rpl.len, code, text, 		s_to_tag.s, s_to_tag.len, 1 /* lock replies */, &bm );	/* this is ugly hack -- the function caller may wish to continue with	 * transaction and I unref; however, there is now only one use from	 * vm/fifo_vm_reply and I'm currently to lazy to export UNREF; -jiri	 */	UNREF(trans);	return ret;error_1:	if ( hdr_lump ) {		unlink_lump_rpl( trans->uas.request, hdr_lump);		free_lump_rpl( hdr_lump );	}error:	return -1;}/*  Syntax:  ":vm_reply:[response file]\n  code\n  reason\n  trans_id\n  to_tag\n  [new headers]\n  \n  [Body]\n  .\n  \n" */int fifo_t_reply( FILE *stream, char *response_file ){	int ret;	struct cell *trans;	char code[16];	char reason[128];	char trans_id[128];	char new_headers[MAX_HEADER];	char body[MAX_BODY];	char to_tag[128];	str sc;       /*  code */	str sr;       /*  reason */	str sti;      /*  trans_id */	str snh;      /*  new_headers */	str sb;       /*  body */	str sttag;    /*  to-tag */	unsigned int hash_index,label,icode;	sc.s=code;	sr.s=reason;	sti.s=trans_id;	snh.s=new_headers; sb.s=body;	sttag.s=to_tag; sttag.len=0;	/*  get the infos from FIFO server */	DBG("DEBUG: fifo_t_reply: ############### begin ##############\n");	if (!read_line(sc.s, 16, stream, &sc.len)||sc.len==0) {		LOG(L_ERR, "ERROR: fifo_t_reply: code expected\n");		fifo_reply(response_file, "400 fifo_t_reply: code expected");		return -1;	}	icode = str2s(sc.s,sc.len,&ret);	if(ret){		LOG(L_ERR, "ERROR: fifo_t_reply: code(int) has wrong format\n");		fifo_reply(response_file, "400 fifo_t_reply: code(int) has"			" wrong format");		return -1;	}	if(!read_line(sr.s, 128, stream, &sr.len)||sr.len==0){		LOG(L_ERR, "ERROR: fifo_t_reply: reason expected\n");		fifo_reply(response_file, "400 fifo_t_reply: reason expected");		return -1;	}	sr.s[sr.len]='\0';	if (!read_line(sti.s, 128, stream, &sti.len)||sti.len==0) {		LOG(L_ERR, "ERROR: fifo_t_reply: trans_id expected\n");		fifo_reply(response_file, "400 fifo_t_reply: trans_id expected");		return -1;	}	sti.s[sti.len]='\0';	DBG("DEBUG: fifo_t_reply: trans_id=%.*s\n",sti.len,sti.s);	if(sscanf(sti.s,"%u:%u", &hash_index, &label) != 2){		LOG(L_ERR, "ERROR: fifo_t_reply: invalid trans_id (%s)\n",sti.s);		fifo_reply(response_file, "400 fifo_t_reply: invalid trans_id");		return -1;	}	DBG("DEBUG: fifo_t_reply: hash_index=%u label=%u\n",hash_index,label);	if( !read_line(sttag.s,64,stream,&sttag.len) || sttag.len==0 ){		LOG(L_ERR, "ERROR: fifo_t_reply: to-tag expected\n");		fifo_reply(response_file, "400 fifo_t_reply: to-ta expected");		return -1;	}	sttag.s[sttag.len]='\0';	DBG("DEBUG: fifo_t_reply: to-tag: %.*s\n",sttag.len,sttag.s);	/* read the new headers */	if (!read_line_set(snh.s, MAX_HEADER, stream, &snh.len)) {		LOG(L_ERR, "ERROR: fifo_t_reply: while reading new headers\n");		fifo_reply(response_file, "400 fifo_t_reply: while reading "			"new headers");		return -1;	}	snh.s[snh.len]='\0';	DBG("DEBUG: fifo_t_reply: new headers: %.*s\n", snh.len, snh.s);	/*  body can be empty ... */	read_body(sb.s, MAX_BODY, stream, &sb.len);	sb.s[sb.len]='\0';	DBG("DEBUG: fifo_t_reply: body: <%.*s>\n", sb.len, sb.s);	if( t_lookup_ident(&trans,hash_index,label)<0 ) {		LOG(L_ERR,"ERROR: fifo_t_reply: lookup failed\n");		fifo_reply(response_file, "481 fifo_t_reply: no such transaction");		return -1;	}	/* it's refcounted now, t_reply_with body unrefs for me -- I can 	 * continue but may not use T anymore  */	ret = t_reply_with_body(trans,icode,reason,body,new_headers,to_tag);	if (ret<0) {		LOG(L_ERR, "ERROR: fifo_t_reply: reply failed\n");		fifo_reply(response_file, "500 fifo_t_reply: reply failed");		return -1;	}	fifo_reply(response_file, "200 fifo_t_reply succeeded\n");	DBG("DEBUG: fifo_t_reply: ################ end ##############\n");	return 1;}static int parse_transid(str* s, unsigned int* index, unsigned int* label){	char* buf;	if (!s || !index || !label) {		LOG(L_ERR, "parse_transid: Invalid parameter value\n");		return -1;	}	buf = (char*)pkg_malloc(s->len + 1);	if (!buf) {		LOG(L_ERR, "parse_transid: No memory left\n");		return -1;	}	memcpy(buf, s->s, s->len + 1);	buf[s->len] = '\0';		if (sscanf(buf, "%u:%u", index, label) != 2) {		LOG(L_ERR, "parse_transid: Invalid trans_id (%s)\n", buf);		pkg_free(buf);		return -1;	}	DBG("parse_transid: hash_index=%u label=%u\n", *index, *label);	pkg_free(buf);	return 0;}static int send_reply(struct cell *trans, unsigned int code, str* text, str* body, str* headers, str* to_tag){	struct lump_rpl *hdr_lump, *body_lump;	str rpl;	int ret;	struct bookmark bm;	     /* mark the transaction as replied */	if (code >= 200) set_kr(REQ_RPLD);	     /* add the lumps for new_header and for body (by bogdan) */	if (headers && headers->len) {		hdr_lump = add_lump_rpl(trans->uas.request, headers->s, headers->len, LUMP_RPL_HDR);		if (!hdr_lump) {			LOG(L_ERR, "send_reply: cannot add hdr lump\n");			goto sr_error;		}	} else {		hdr_lump = 0;	}	     /* body lump */	if (body && body->len) {		body_lump = add_lump_rpl(trans->uas.request, body->s, body->len, LUMP_RPL_BODY);		if (body_lump == 0) {			LOG(L_ERR,"send_reply: cannot add body lump\n");			goto sr_error_1;		}	} else {		body_lump = 0;	}	     /* We can safely zero-terminate the text here, because it is followed	      * by next line in the received message	      */	text->s[text->len] = '\0';	rpl.s = build_res_buf_from_sip_req(code, text->s, to_tag, trans->uas.request, (unsigned int*)&rpl.len, &bm);	     /* since the msg (trans->uas.request) is a clone into shm memory, to avoid	      * memory leak or crashing (lumps are create in private memory) I will	      * remove the lumps by myself here (bogdan) */	if (hdr_lump) {		unlink_lump_rpl(trans->uas.request, hdr_lump);		free_lump_rpl(hdr_lump);	}	if (body_lump) {		unlink_lump_rpl(trans->uas.request, body_lump);		free_lump_rpl(body_lump);	}	if (rpl.s == 0) {		LOG(L_ERR,"send_reply: failed in build_res_buf_from_sip_req\n");		goto sr_error;	}	ret = _reply_light(trans, rpl.s, rpl.len, code, text->s,  to_tag->s, to_tag->len, 1 /* lock replies */, &bm);	     /* this is ugly hack -- the function caller may wish to continue with	      * transaction and I unref; however, there is now only one use from	      * vm/fifo_vm_reply and I'm currently to lazy to export UNREF; -jiri	      */	UNREF(trans);	return ret; sr_error_1:	if (hdr_lump) {		unlink_lump_rpl(trans->uas.request, hdr_lump);		free_lump_rpl(hdr_lump);	} sr_error:	return -1;}int unixsock_t_reply(str* msg){	int ret;	struct cell *trans;	static char new_headers[MAX_HEADER];	str code, reason, transid, headers, body, to_tag;	unsigned int hash_index, label, icode;	headers.s = new_headers;	headers.len = MAX_HEADER;	if (unixsock_read_line(&code, msg) != 0) {		unixsock_reply_asciiz("400 Reason code expected\n");		goto err;	}	icode = str2s(code.s, code.len, &ret);	if (ret) {		unixsock_reply_printf("400 Reason code has wrong format\n");		goto err;	}	if (unixsock_read_line(&reason, msg) != 0) {		unixsock_reply_asciiz("400 Reason phrase expected\n");		goto err;	}	if (unixsock_read_line(&transid, msg) != 0) {		unixsock_reply_asciiz("400 Transaction ID expected\n");		goto err;	}	if (parse_transid(&transid, &hash_index, &label) < 0) {		unixsock_reply_asciiz("400 Error while parsing transaction ID\n");		goto err;	}	if (unixsock_read_line(&to_tag, msg) != 0) {		unixsock_reply_asciiz("400 To tag expected\n");		goto err;	}	     /* read the new headers */	if (unixsock_read_lineset(&headers, msg) < 0) {		unixsock_reply_asciiz("400 Error while reading new headers\n");		goto err;	}	DBG("lineset: %.*s\n", headers.len, headers.s);	     	/*  body can be empty ... */	if (unixsock_read_body(&body, msg) < 0) {		unixsock_reply_asciiz("400 Error while reading body\n");		goto err;	}	DBG("body: %.*s\n", body.len, body.s);		if (t_lookup_ident(&trans, hash_index, label) < 0) {		LOG(L_ERR,"unixsock_t_reply: lookup failed\n");		unixsock_reply_asciiz("481 No such transaction\n");		goto err;	}	     /* it's refcounted now, t_reply_with body unrefs for me -- I can 	      * continue but may not use T anymore  	      */	ret = send_reply(trans, icode, &reason, &body, &headers, &to_tag);	if (ret < 0) {		LOG(L_ERR, "unixsock_t_reply: reply failed\n");		unixsock_reply_asciiz("500 Reply failed\n");		goto err;	}	unixsock_reply_asciiz("200 Succeeded\n");	unixsock_reply_send();	return 1; err:	unixsock_reply_send();	return -1;}

⌨️ 快捷键说明

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