uac_unixsock.c

来自「性能优秀的SIP Proxy」· C语言 代码 · 共 624 行 · 第 1/2 页

C
624
字号
					continue;				default:					     /* no valid substitution char -- keep going */					p -= frag_len + 1;					needle = d;				}			} /* possible substitute */		} /* substitution loop */		DBG("get_hfblock: one more hf processed\n");	} /* header loop */		     /* construct a single header block now */	ret = pkg_malloc(total_len);	if (!ret) {		LOG(L_ERR, "get_hfblock: no pkg mem for hf block\n");		goto error;	}	i = sl.next;	dst = ret;	while(i) {		foo = i;		i = i->next;		memcpy(dst, foo->s.s, foo->s.len);		dst += foo->s.len;		pkg_free(foo);	}	*l = total_len;	return ret;	 error:	i = sl.next;	while(i) {		foo = i;		i = i->next;		pkg_free(foo);	}	*l = 0;	return 0;}#define FIFO_ROUTE_PREFIX "Route: "#define FIFO_ROUTE_SEPARATOR ", "static void print_routes(dlg_t* _d){	rr_t* ptr;	ptr = _d->hooks.first_route;	if (ptr) {		unixsock_reply_asciiz(FIFO_ROUTE_PREFIX);	} else {		unixsock_reply_asciiz(".\n");		return;	}	while(ptr) {		unixsock_reply_printf("%.*s", ptr->len, ptr->nameaddr.name.s);		ptr = ptr->next;		if (ptr) {			unixsock_reply_asciiz(FIFO_ROUTE_SEPARATOR);		}	} 	if (_d->hooks.last_route) {		unixsock_reply_asciiz(FIFO_ROUTE_SEPARATOR "<");		unixsock_reply_printf("%.*s", _d->hooks.last_route->len, _d->hooks.last_route->s);		unixsock_reply_asciiz(">");	}	if (_d->hooks.first_route) {		unixsock_reply_asciiz(CRLF);	}}static int print_uris(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) {		unixsock_reply_asciiz(".\n.\n.\n");		free_dlg(dlg);		return 0;	}	if (dlg->hooks.request_uri->s) {			unixsock_reply_printf("%.*s\n", dlg->hooks.request_uri->len, dlg->hooks.request_uri->s);	} else {		unixsock_reply_asciiz(".\n");	}	if (dlg->hooks.next_hop->s) {		unixsock_reply_printf("%.*s\n", dlg->hooks.next_hop->len, dlg->hooks.next_hop->s);	} else {		unixsock_reply_asciiz(".\n");	}	print_routes(dlg);	free_dlg(dlg);	return 0;}static int new_uac_cb_param(struct uac_cb_param** param,			    struct sip_msg* msg,			    struct sockaddr_un* addr){	int len;	struct uac_cb_param* p_param;	if (!msg || !addr) {		param = 0;		return 0;	}	len  = msg->from->len;	len += msg->callid->len;	len += msg->cseq->len;	*param = shm_malloc( sizeof(struct uac_cb_param) + len );	if (!*param) {		unixsock_reply_asciiz("500 No shared memory");		return -1;	}	p_param = *param;	p_param->from.s = (char*)((*param)+1);	memcpy(p_param->from.s,msg->from->name.s,msg->from->len);	p_param->from.len = msg->from->len;	p_param->callid.s = p_param->from.s + p_param->from.len;	memcpy(p_param->callid.s,msg->callid->name.s,msg->callid->len);	p_param->callid.len = msg->callid->len;	p_param->cseq.s = p_param->callid.s + p_param->callid.len;	memcpy(p_param->cseq.s,msg->cseq->name.s,msg->cseq->len);	p_param->cseq.len = msg->cseq->len;	memcpy(&(p_param->addr), addr, sizeof(struct sockaddr_un));	return 0;}static void free_uac_cb_param(struct uac_cb_param* param){	shm_free(param);}static void callback(struct cell *t, int type, struct tmcb_params *ps){	struct sockaddr_un* to;	struct uac_cb_param* param=0;	str text;	if (!*ps->param) {		LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", ps->code);		return;	}	param = (struct uac_cb_param*)(*ps->param);	to = &param->addr;		unixsock_reply_reset();	if (ps->rpl == FAKED_REPLY) {		get_reply_status(&text, ps->rpl, ps->code);		if (text.s == 0) {			LOG(L_ERR, "callback: get_reply_status failed\n");			unixsock_reply_asciiz("500 callback: get_reply_status failed\n");			goto done;		}		unixsock_reply_printf("%.*s\n.\n.\n.\n", text.len, text.s);		unixsock_reply_printf("%.*s", param->from.len, param->from.s);		unixsock_reply_printf("%.*s", param->callid.len,				      param->callid.s);		unixsock_reply_printf("%.*s\n", param->cseq.len,				      param->cseq.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;		     /* FIXME: check for return values here */		unixsock_reply_printf("%d %.*s\n", ps->rpl->first_line.u.reply.statuscode, text.len, text.s);		print_uris(ps->rpl);		unixsock_reply_printf("%s\n", ps->rpl->headers->name.s);	}done:	unixsock_reply_sendto(to);	if (ps->code >= 200) {	    free_uac_cb_param(param);	    *ps->param=0; /* 0 it so the callback won't do			     anything if called for a retransmission */	}}int unixsock_uac(str* msg){	str method, ruri, nexthop, headers, body, hfb, callid;	struct sip_uri puri, pnexthop;	struct sip_msg faked_msg;	int ret, sip_error, err_ret, fromtag, cseq_is, cseq;	char err_buf[MAX_REASON_LEN];	struct uac_cb_param* shm_param;	dlg_t dlg;	if (get_method(&method, msg) < 0) return -1;	if (get_ruri(&ruri, &puri, msg) < 0) return -1;	if (get_nexthop(&nexthop, &pnexthop, msg) < 0) return -1;	if (get_headers(&headers, msg) < 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_F, 0) == -1 ) {		unixsock_reply_asciiz("400 HFs unparsable\n");		unixsock_reply_send();		goto error;	}	if (get_body_lines(&body, msg) < 0) goto error;		/* at this moment, we collected all the things we got, let's	 * verify user has not forgotten something */	if (check_msg(&faked_msg, &method, &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) {		unixsock_reply_asciiz("500 No memory for HF block");		unixsock_reply_send();		goto error;	}	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);		shm_param = 0;	if ( new_uac_cb_param(&shm_param,&faked_msg,unixsock_sender_addr())< 0) {		unixsock_reply_send();		goto error01;	}	/* we got it all, initiate transaction now! */	ret = t_uac(&method, &hfb, &body, &dlg, callback, shm_param);	if (ret <= 0) {		err_ret = err2reason_phrase(ret, &sip_error, err_buf, sizeof(err_buf), "FIFO/UAC");		if (err_ret > 0) {			unixsock_reply_printf("%d %s", sip_error, err_buf);		} else {			unixsock_reply_asciiz("500 UNIXSOCK/UAC error");		}		unixsock_reply_send();		free_uac_cb_param(shm_param);		goto error01;	}	/* Do not free shm_sockaddr here, it will be used	 * by the callback	 */	pkg_free(hfb.s);	if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);	return 0;	error01:	pkg_free(hfb.s);error:	if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);	return -1;}

⌨️ 快捷键说明

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