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

📄 uac_fifo.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
	dst EOL 				// ("." if no outbound server used)							// must be used with dialogs/lr	<EOL separated HFs>+	// From and To must be present at least;							// dialog-apps must include tag in From 							// (an ephemeral is appended otherwise)							// and supply CSeq/CallId	.[EOL]	[body] 	.EOL	there is also the possibility to have server placed its    hostname:portnumber in header fields -- just put double	exclamation mark in any of the optional header fields	(i.e., any but From/To/CallID,CSeq), they will be 	substituted hn:pnExample:sc fifo t_uac_dlg MESSAGE sip:joe@192.168.2.1 \	. \ # no outbound proxy	'From:sender@iptel.org;tagd=123'  \ # no to-tag -> ephemeral	'To:sender@iptel.org' \	'Foo: sip:user@!! '  \ # expansion here	'CSEQ: 11 MESSAGE   ' \	. \ # EoH	.	# empty body---U 192.168.2.16:5060 -> 192.168.2.1:5060MESSAGE sip:joe@192.168.2.1 SIP/2.0..Via: SIP/2.0/UDP 192.168.2.16;branch=z9hG4bK760c.922ea6a1.0..To: sender@iptel.org..From: sender@iptel.org;tagd=123;tag=5405e669bc2980663aed2624dc31396f-fa77..CSeq: 11 MESSAGE..Call-ID: e863bf56-22255@192.168.2.16..Content-Length: 0..User-Agent: Sip EXpress router (0.8.11pre4-tcp1-locking (i386/linux))..Foo: sip:user@192.168.2.16:5060....*//* * Make sure that the FIFO user created the message * correctly */static inline int fifo_check_msg(struct sip_msg* msg, str* method, char* resp, str* body, 				 int* fromtag, int *cseq_is, int* cseq, str* callid){	struct to_body* parsed_from;	struct cseq_body *parsed_cseq;	int i;	char c;	if (body->len && !msg->content_type) {		fifo_uac_error(resp, 400, "Content-Type missing");		return -1;	}	if (body->len && msg->content_length) {		fifo_uac_error(resp, 400, "Content-Length disallowed");		return -2;	}	if (!msg->to) {		fifo_uac_error(resp, 400, "To missing");		return -3;	}	if (!msg->from) {		fifo_uac_error(resp, 400, "From missing");		return -4;	}	     /* we also need to know if there is from-tag and add it otherwise */	if (parse_from_header(msg) < 0) {		fifo_uac_error(resp, 400, "Error in From");		return -5;	}	parsed_from = (struct to_body*)msg->from->parsed;	*fromtag = parsed_from->tag_value.s && parsed_from->tag_value.len;	*cseq = 0;	if (msg->cseq && (parsed_cseq = get_cseq(msg))) {		*cseq_is = 1;		for (i = 0; i < parsed_cseq->number.len; i++) {			c = parsed_cseq->number.s[i];			if (c >= '0' && c <= '9' ) *cseq = (*cseq) * 10 + c - '0';			else {			        DBG("found non-numerical in CSeq: <%i>='%c'\n",(unsigned int)c,c);				fifo_uac_error(resp, 400, "non-numerical CSeq");				return -6;			}		}				if (parsed_cseq->method.len != method->len 		    || memcmp(parsed_cseq->method.s, method->s, method->len) !=0 ) {			fifo_uac_error(resp, 400, "CSeq method mismatch");			return -7;		}	} else {		*cseq_is = 0;	}	if (msg->callid) {		callid->s = msg->callid->body.s;		callid->len = msg->callid->body.len;	} else {		callid->s = 0;		callid->len = 0;	}	return 0;}#define FIFO_ROUTE_PREFIX "Route: "#define FIFO_ROUTE_SEPARATOR ", "static inline void print_routes(FILE* out, dlg_t* _d){	rr_t* ptr;	ptr = _d->hooks.first_route;	if (ptr) {		fprintf(out, FIFO_ROUTE_PREFIX);	} else {		fprintf(out, ".\n");		return;	}	while(ptr) {		fprintf(out, "%.*s", ptr->len, ptr->nameaddr.name.s);		ptr = ptr->next;		if (ptr) {			fprintf(out, FIFO_ROUTE_SEPARATOR);		}	} 	if (_d->hooks.last_route) {		fprintf(out, FIFO_ROUTE_SEPARATOR "<");		fprintf(out, "%.*s", _d->hooks.last_route->len, _d->hooks.last_route->s);		fprintf(out, ">");	}	if (_d->hooks.first_route) {		fprintf(out, CRLF);	}}static inline int print_uris(FILE* out, struct sip_msg* reply){	dlg_t* dlg;		dlg = (dlg_t*)shm_malloc(sizeof(dlg_t));	if (!dlg) {		LOG(L_ERR, "print_uris(): No memory left\n");		return -1;	}	memset(dlg, 0, sizeof(dlg_t));	if (dlg_response_uac(dlg, reply) < 0) {		LOG(L_ERR, "print_uris(): Error while creating dialog structure\n");		free_dlg(dlg);		return -2;	}	if (dlg->state != DLG_CONFIRMED) {		fprintf(out, ".\n.\n.\n");		free_dlg(dlg);		return 0;	}	if (dlg->hooks.request_uri->s) {			fprintf(out, "%.*s\n", dlg->hooks.request_uri->len, dlg->hooks.request_uri->s);	} else {		fprintf(out, ".\n");	}	if (dlg->hooks.next_hop->s) {		fprintf(out, "%.*s\n", dlg->hooks.next_hop->len, dlg->hooks.next_hop->s);	} else {		fprintf(out, ".\n");	}	print_routes(out, dlg);	free_dlg(dlg);	return 0;}static void fifo_callback( struct cell *t, int type, struct tmcb_params *ps ){		char *filename;	FILE* f;	str text;	DBG("!!!!! ref_counter: %d\n", t->ref_count);	DBG("DEBUG: fifo UAC completed with status %d\n", ps->code);	if (!*ps->param) {		LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", ps->code);		return;	}	filename=(char *)(*ps->param);	if (ps->rpl==FAKED_REPLY) {		get_reply_status( &text, ps->rpl, ps->code);		if (text.s==0) {			LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");			fifo_reply( filename,				"500 fifo_callback: get_reply_status failed\n");			goto done;		}		fifo_reply(filename, "%.*s\n", text.len, text.s );		pkg_free(text.s);	} else {		text.s = ps->rpl->first_line.u.reply.reason.s;		text.len = ps->rpl->first_line.u.reply.reason.len;		f = open_reply_pipe(filename);		if (!f) return;		fprintf(f, "%d %.*s\n", ps->rpl->first_line.u.reply.statuscode, text.len, text.s);		print_uris(f, ps->rpl);		fprintf(f, "%s\n", ps->rpl->headers->name.s);		fclose(f);	}	DBG("DEBUG: fifo_callback successfully completed\n");done:	shm_free(filename);}int fifo_uac(FILE *stream, char *response_file){	str method, ruri, nexthop, headers, body, hfb, callid;	struct sip_uri puri, pnexthop;	struct sip_msg faked_msg;	int ret, sip_error, err_ret;	int fromtag, cseq_is, cseq;	struct cb_data;	char err_buf[MAX_REASON_LEN];	char* shm_file;	dlg_t dlg;	if (fifo_get_method(stream, response_file, &method) < 0) return 1;	if (fifo_get_ruri(stream, response_file, &ruri, &puri) < 0) return 1;	if (fifo_get_nexthop(stream, response_file, &nexthop, &pnexthop) < 0) return 1;	if (fifo_get_headers(stream, response_file, &headers) < 0) return 1;	/* use SIP parser to look at what is in the FIFO request */	memset(&faked_msg, 0, sizeof(struct sip_msg));	faked_msg.len = headers.len; 	faked_msg.buf = faked_msg.unparsed = headers.s;	if (parse_headers(&faked_msg, HDR_EOH, 0) == -1 ) {		DBG("DEBUG: fifo_uac: parse_headers failed\n");		fifo_uac_error(response_file, 400, "HFs unparseable");		goto error;	}	DBG("DEBUG: fifo_uac: parse_headers succeeded\n");	if (fifo_get_body(stream, response_file, &body) < 0) goto error;		     /* at this moment, we collected all the things we got, let's	      * verify user has not forgotten something */	if (fifo_check_msg(&faked_msg, &method, response_file, &body, &fromtag, 			   &cseq_is, &cseq, &callid) < 0) goto error;	hfb.s = get_hfblock(nexthop.len ? &nexthop : &ruri, 			    faked_msg.headers, &hfb.len, PROTO_UDP);	if (!hfb.s) {		fifo_uac_error(response_file, 500, "no mem for hf block");		goto error;	}	DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");	memset(&dlg, 0, sizeof(dlg_t));	     /* Fill in Call-ID, use given Call-ID if	      * present and generate it if not present	      */	if (callid.s && callid.len) dlg.id.call_id = callid;	else generate_callid(&dlg.id.call_id);		     /* We will not fill in dlg->id.rem_tag because	      * if present it will be printed within To HF	      */		     /* Generate fromtag if not present */	if (!fromtag) {		generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id);	}	     /* Fill in CSeq */	if (cseq_is) dlg.loc_seq.value = cseq;	else dlg.loc_seq.value = DEFAULT_CSEQ;	dlg.loc_seq.is_set = 1;	dlg.loc_uri = faked_msg.from->body;	dlg.rem_uri = faked_msg.to->body;	dlg.hooks.request_uri = &ruri;	dlg.hooks.next_hop = (nexthop.len ? &nexthop : &ruri);#ifdef XL_DEBUG	print_dlg(stderr, &dlg);#endif	/* we got it all, initiate transaction now! */	if (fifo_cbp(&shm_file, response_file) < 0) goto error01;	ret = t_uac(&method, &hfb, &body, &dlg, fifo_callback, shm_file);	if (ret <= 0) {		err_ret = err2reason_phrase(ret, &sip_error, err_buf,			sizeof(err_buf), "FIFO/UAC") ;		if (err_ret > 0 )		{			fifo_uac_error(response_file, sip_error, err_buf);		} else {			fifo_uac_error(response_file, 500, "FIFO/UAC error");		}	}	 error01:	pkg_free(hfb.s);	 error:	     /* free_sip_msg(&faked_msg); */	if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);	return 1;}

⌨️ 快捷键说明

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