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

📄 sip_itf.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END *//* * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. * Use is subject to license terms. */#pragma ident	"@(#)sip_itf.c	1.19	06/08/16 SMI"#ifdef	__linux__#include <stdarg.h>#else#include <sys/varargs.h>#endif#include "sip_miscdefs.h"#include "sip_xaction.h"#include "sip_hash.h"#include "sip_dialog.h"#include "sip_msg.h"#define	SIP_MSG_BUF_SZ	100void		(*sip_ulp_recv)(const sip_conn_object_t, sip_msg_t,		    const sip_dialog_t) = NULL;uint_t		(*sip_stack_timeout)(void *, void (*func)(void *),		    struct timeval *) = NULL;boolean_t	(*sip_stack_untimeout)(uint_t) = NULL;void		(*sip_ulp_dlg_del)(sip_dialog_t, sip_msg_t, void *) = NULL;int		(*sip_stack_send)(sip_conn_object_t xonn_object, char *, int) =		    NULL;void		(*sip_refhold_conn)(sip_conn_object_t) = NULL;void		(*sip_refrele_conn)(sip_conn_object_t) = NULL;boolean_t	(*sip_is_conn_stream)(sip_conn_object_t) = NULL;boolean_t	(*sip_is_conn_reliable)(sip_conn_object_t) = NULL;int 		(*sip_conn_rem_addr)(sip_conn_object_t, struct sockaddr *,		    socklen_t *) = NULL;int		(*sip_conn_local_addr)(sip_conn_object_t, struct sockaddr *,		    socklen_t *) = NULL;int		(*sip_conn_transport)(sip_conn_object_t) = NULL;int		(*sip_conn_timer1)(sip_conn_object_t) = NULL;int		(*sip_conn_timer2)(sip_conn_object_t) = NULL;int		(*sip_conn_timer4)(sip_conn_object_t) = NULL;int		(*sip_conn_timerd)(sip_conn_object_t) = NULL;boolean_t	sip_manage_dialog = B_FALSE;uint64_t	sip_hash_salt = 0;/* Defaults, overridden by configured values, if any */int		sip_timer_T1 = SIP_TIMER_T1;int		sip_timer_T2 = SIP_TIMER_T2;int		sip_timer_T4 = SIP_TIMER_T4;int		sip_timer_TD = 32 * SIP_SECONDS;/* Create and send an error response */voidsip_send_resp_err(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg, int resp){	_sip_msg_t		*sip_msg_resp;	sip_msg_resp = (_sip_msg_t *)sip_create_response((sip_msg_t)sip_msg,	    resp, sip_get_resp_desc(resp), NULL, NULL);	if (sip_msg_resp == NULL) {		/*		 * Message was too bad to even create a		 * response. Just drop the messge.		 */		return;	}	/*	 * We directly send it to the transport here.	 */	if (sip_adjust_msgbuf(sip_msg_resp) != 0) {		sip_free_msg((sip_msg_t)sip_msg_resp);		return;	}	(void) sip_stack_send(conn_obj, sip_msg_resp->sip_msg_buf,	    sip_msg_resp->sip_msg_len);}/* Validate some of the common headers */boolean_tsip_check_common_headers(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg){	int	err;	if (sip_get_to_uri_str((sip_msg_t)sip_msg, &err) == NULL)		goto error;	if (sip_get_from_uri_str((sip_msg_t)sip_msg, &err) == NULL)		goto error;	if (sip_get_callseq_num((sip_msg_t)sip_msg, &err) < 0)		goto error;	if (sip_get_callid((sip_msg_t)sip_msg, &err) == NULL)		goto error;	return (B_FALSE);error:	sip_send_resp_err(conn_obj, sip_msg, SIP_BAD_REQUEST);	return (B_TRUE);}/* * setup pointers to where the headers are. */static intsip_setup_header_pointers(_sip_msg_t *sip_msg){	char		*msg;	_sip_header_t	*sip_msg_header;	char		*end;	msg = sip_msg->sip_msg_buf;	end = sip_msg->sip_msg_buf + sip_msg->sip_msg_len;	/*	 * Skip while space.	 */	while (isspace(*msg)) {		if (msg < end)			msg++;		else			return (EINVAL);	}	/*	 * We consider Request and Response line as a header	 */	for (;;) {		/*		 * Skip CRLF		 */		if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {			if (sip_msg->sip_msg_headers_end != NULL) {				SKIP_CRLF(msg);				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;			}			/*			 * Start of a header.			 * Check for empty line.			 */			if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {				/*				 * empty line, start of content.				 */				SKIP_CRLF(msg);				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;				break;			}			/*			 * store start of header.			 */			sip_msg_header = calloc(1, sizeof (_sip_header_t));			if (sip_msg_header == NULL)				return (EINVAL);			sip_msg_header->sip_hdr_start = msg;			sip_msg_header->sip_hdr_current = msg;			sip_msg_header->sip_hdr_allocated = B_FALSE;			sip_msg_header->sip_hdr_prev =			    sip_msg->sip_msg_headers_end;			sip_msg_header->sip_hdr_next = NULL;			sip_msg_header->sip_hdr_sipmsg = sip_msg;			sip_msg->sip_msg_headers_end->sip_hdr_next =			    sip_msg_header;			sip_msg->sip_msg_headers_end = sip_msg_header;		} else {			if (sip_msg->sip_msg_headers_start == NULL) {				/*				 * Allocate first header structure.				 */				sip_msg_header = calloc(1,				    sizeof (_sip_header_t));				if (sip_msg_header == NULL)					return (EINVAL);				sip_msg_header->sip_hdr_allocated = B_FALSE;				sip_msg_header->sip_hdr_start = msg;				sip_msg_header->sip_hdr_current = msg;				sip_msg_header->sip_hdr_sipmsg = sip_msg;				sip_msg->sip_msg_headers_start = sip_msg_header;				sip_msg->sip_msg_headers_end = sip_msg_header;			}			msg++;		}		/*		 * We have reached the end without hitting the empty line.		 */		if (msg - sip_msg->sip_msg_buf >= sip_msg->sip_msg_len)			return (EINVAL);	}	if (sip_msg->sip_msg_headers_start == NULL)		return (EPROTO);	/*	 * Move start line to be a separate line.	 */	sip_msg->sip_msg_start_line = sip_msg->sip_msg_headers_start;	sip_msg->sip_msg_headers_start =	    sip_msg->sip_msg_headers_start->sip_hdr_next;	sip_msg->sip_msg_start_line->sip_hdr_prev = NULL;	sip_msg->sip_msg_start_line->sip_hdr_next = NULL;	if (sip_msg->sip_msg_headers_start == NULL)		return (EINVAL);	sip_msg->sip_msg_headers_start->sip_hdr_prev = NULL;	/*	 * Deal with content.	 */	sip_msg->sip_msg_content = calloc(1, sizeof (sip_content_t));	sip_msg->sip_msg_content->sip_content_start = msg;	sip_msg->sip_msg_content->sip_content_end = sip_msg->sip_msg_buf +	    sip_msg->sip_msg_len;	sip_msg->sip_msg_content->sip_content_allocated = B_FALSE;	sip_msg->sip_msg_content_len =	    sip_msg->sip_msg_content->sip_content_end -	    sip_msg->sip_msg_content->sip_content_start;	return (0);}/* * The send interface to the sip stack. Used by upper layers. */intsip_sendmsg(sip_conn_object_t obj, sip_msg_t sip_msg, sip_dialog_t dialog,    uint32_t flags){	sip_xaction_t		*sip_trans = NULL;	int			ret = 0;	sip_message_type_t	*sip_msg_info;	_sip_msg_t 		*_sip_msg;	boolean_t		stateful = flags & SIP_SEND_STATEFUL;	boolean_t		dlg_on_fork = flags & SIP_DIALOG_ON_FORK;	sip_refhold_conn(obj);	_sip_msg = (_sip_msg_t *)sip_msg;	if ((ret = sip_adjust_msgbuf(_sip_msg)) != 0) {		sip_refrele_conn(obj);		return (ret);	}	assert(_sip_msg->sip_msg_req_res != NULL);	sip_msg_info = _sip_msg->sip_msg_req_res;	/*	 * Send it statefully if:	 * if stateful is set in 'flags' AND	 * this is not an ACK request, if it is a request (should the upper	 * layer set stateful in the latter case?, i.e is the check	 * necessary here?)	 */	if (stateful && (!sip_msg_info->is_request ||	    sip_msg_info->sip_req_method != ACK)) {		sip_trans = (sip_xaction_t *)sip_xaction_get(obj, sip_msg,		    B_TRUE, sip_msg_info->is_request ? SIP_CLIENT_TRANSACTION :		    SIP_SERVER_TRANSACTION, &ret);		if (sip_trans == NULL) {			sip_refrele_conn(obj);			return (ret);		}		ret = sip_xaction_output(obj, sip_trans, _sip_msg);		SIP_XACTION_REFCNT_DECR(sip_trans);		if (ret != 0) {			sip_refrele_conn(obj);			return (ret);		}	}	/*	 * If the appln wants us to create the dialog, create a partial	 * dialog at this stage, when we get the response, we will	 * complete it.	 */	if (sip_manage_dialog) {

⌨️ 快捷键说明

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