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

📄 sip_itf.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (sip_msg_info->is_request && dialog == NULL) {			dialog = (sip_dialog_t)sip_seed_dialog(obj, sip_msg,			    sip_ulp_dlg_del, dlg_on_fork, SIP_UAC_DIALOG);		} else if (dialog != NULL && (!sip_msg_info->is_request ||		    sip_msg_info->sip_req_method == NOTIFY)) {			(void) sip_update_dialog(dialog, _sip_msg,			    sip_ulp_dlg_del);		}	}	if ((ret = sip_stack_send(obj, _sip_msg->sip_msg_buf,	    _sip_msg->sip_msg_len)) != 0) {		if (sip_trans != NULL) {			sip_xaction_terminate(sip_trans, _sip_msg,			    sip_conn_transport(obj));		}		sip_refrele_conn(obj);		return (ret);	}	sip_refrele_conn(obj);	return (ret);}/* * Given a response, check if the sent-by in the VIA header is valid. */boolean_tsip_valid_sent_by(sip_msg_t sip_msg){	sip_header_t		via;	sip_header_value_t	value = NULL;	int			error;	const sip_str_t		*sent_by = NULL;	via = (sip_header_t)sip_get_header(sip_msg, SIP_VIA,  NULL, &error);	if (via == NULL || error != 0)		return (B_TRUE);	value = (sip_header_value_t)sip_get_header_value(via, &error);	if (value == NULL || error != 0)		return (B_TRUE);	sent_by = sip_get_via_sent_by_host(value, &error);	if (sent_by == NULL || error != 0)		return (B_TRUE);	if (sip_sent_by_registered(sent_by))		return (B_TRUE);	return (B_FALSE);}/* * The receive interface to the transport layer. */voidsip_process_new_packet(sip_conn_object_t conn_object, void *msgstr,    size_t msglen){	_sip_msg_t		*sip_msg;	sip_message_type_t	*sip_msg_info;	sip_xaction_t		*sip_trans;	sip_dialog_t		dialog = NULL;	boolean_t		dialog_created = B_FALSE;	int			transport;	char			*msgbuf = NULL;	sip_refhold_conn(conn_object);	transport = sip_conn_transport(conn_object);	if (transport == IPPROTO_TCP) {next_msg:		msgstr = (char *)sip_get_tcp_msg(conn_object, (char *)msgstr,		    &msglen);		if (msgstr == NULL) {			sip_refrele_conn(conn_object);			return;		}	} else {		msgbuf = (char *)malloc(msglen + 1);		if (msgbuf == NULL) {			sip_refrele_conn(conn_object);			return;		}		(void) strncpy(msgbuf, msgstr, msglen);		msgbuf[msglen] = '\0';		msgstr = msgbuf;	}	sip_msg = (_sip_msg_t *)sip_new_msg();	if (sip_msg == NULL) {		if (msgbuf != NULL)			free(msgbuf);		sip_refrele_conn(conn_object);		return;	}	sip_msg->sip_msg_buf = (char *)msgstr;	sip_msg->sip_msg_len = msglen;	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);	if (sip_setup_header_pointers(sip_msg) != 0) {		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);		sip_refrele_conn(conn_object);		sip_free_msg((sip_msg_t)sip_msg);		return;	}	if (sip_parse_first_line(sip_msg->sip_msg_start_line,	    &sip_msg->sip_msg_req_res)) {		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);		sip_refrele_conn(conn_object);		sip_free_msg((sip_msg_t)sip_msg);		return;	}	sip_msg_info = sip_msg->sip_msg_req_res;	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);	if (sip_check_common_headers(conn_object, sip_msg)) {		sip_refrele_conn(conn_object);		sip_free_msg((sip_msg_t)sip_msg);		return;	}	/*	 * Silently discard the response if the top VIA has a sent-by value AND	 * the UA has registered sent-by values AND the one in the VIA is	 * not part of the registerd sent-by values.	 */	if (!sip_msg_info->is_request && !sip_valid_sent_by(sip_msg)) {		sip_refrele_conn(conn_object);		sip_free_msg((sip_msg_t)sip_msg);		return;	}	sip_trans = (sip_xaction_t *)sip_xaction_get(conn_object,	    (sip_msg_t)sip_msg,	    B_FALSE, sip_msg_info->is_request ? SIP_SERVER_TRANSACTION :	    SIP_CLIENT_TRANSACTION, NULL);	if (sip_trans != NULL) {		if (sip_xaction_input(conn_object, sip_trans, &sip_msg) != 0) {			SIP_XACTION_REFCNT_DECR(sip_trans);			sip_refrele_conn(conn_object);			sip_free_msg((sip_msg_t)sip_msg);			return;		}		SIP_XACTION_REFCNT_DECR(sip_trans);		/* msg was retransmission - handled by the transaction */		if (sip_msg == NULL)			goto check_next;	}	if (sip_manage_dialog) {		dialog = sip_dialog_find(sip_msg);		if (dialog == NULL) {			if (sip_msg_info->is_request) {				/*				 * sip_seed_dialog will check for the				 * method in the request				 */				dialog = (sip_dialog_t)sip_seed_dialog(				    conn_object, sip_msg, sip_ulp_dlg_del,				    B_FALSE, SIP_UAS_DIALOG);			} else {				dialog = sip_dialog_create(sip_msg, NULL,				    SIP_UAC_DIALOG);			}			dialog_created = B_TRUE;		} else if (sip_incomplete_dialog(dialog) &&		    (!sip_msg_info->is_request ||		    sip_msg_info->sip_req_method == NOTIFY)) {			dialog = sip_update_dialog(dialog, sip_msg,			    sip_ulp_dlg_del);		} else if (sip_dialog_process(sip_msg, &dialog,		    sip_ulp_dlg_del) != 0) {			if (dialog != NULL)				sip_release_dialog(dialog);			sip_refrele_conn(conn_object);			sip_free_msg((sip_msg_t)sip_msg);			return;		}	}	sip_ulp_recv(conn_object, (sip_msg_t)sip_msg, dialog);	sip_free_msg((sip_msg_t)sip_msg);	if (dialog != NULL && !dialog_created)		sip_release_dialog(dialog);check_next:	/*	 * Check if there are more complete messages in the TCP fragment list	 * to be consumed	 */	if (transport == IPPROTO_TCP) {		msgstr = NULL;		msglen = 0;		goto next_msg;	}	sip_refrele_conn(conn_object);}/* * Initialize the stack. The connection manager functions, upper layer * receive functions are mandatory. */intsip_stack_init(sip_stack_init_t *stack_val){#ifdef	__linux__	struct timespec	tspec;#endif	/* If the stack has already been configured, return error */	if (sip_stack_send != NULL ||	    stack_val->sip_version != SIP_STACK_VERSION) {		return (EINVAL);	}	if (stack_val->sip_io_pointers == NULL ||	    stack_val->sip_ulp_pointers == NULL) {		return (EINVAL);	}	sip_ulp_recv = stack_val->sip_ulp_pointers->sip_ulp_recv;	sip_manage_dialog = stack_val->sip_stack_flags & SIP_STACK_DIALOGS;	sip_stack_send = stack_val->sip_io_pointers->sip_conn_send;	sip_refhold_conn = stack_val->sip_io_pointers->sip_hold_conn_object;	sip_refrele_conn = stack_val->sip_io_pointers->sip_rel_conn_object;	sip_is_conn_stream = stack_val->sip_io_pointers->sip_conn_is_stream;	sip_is_conn_reliable = stack_val->sip_io_pointers->sip_conn_is_reliable;	sip_conn_rem_addr = stack_val->sip_io_pointers->sip_conn_remote_address;	sip_conn_local_addr =	    stack_val->sip_io_pointers->sip_conn_local_address;	sip_conn_transport = stack_val->sip_io_pointers->sip_conn_transport;	sip_header_function_table_external = stack_val->sip_function_table;	if (sip_ulp_recv == NULL || sip_stack_send == NULL ||	    sip_refhold_conn == NULL || sip_refrele_conn == NULL ||	    sip_is_conn_stream == NULL || sip_is_conn_reliable == NULL ||	    sip_conn_rem_addr == NULL || sip_conn_local_addr == NULL ||	    sip_conn_transport == NULL) {	err_ret:		sip_ulp_recv = NULL;		sip_stack_send = NULL;		sip_refhold_conn = NULL;		sip_refrele_conn = NULL;		sip_is_conn_stream = NULL;		sip_is_conn_reliable = NULL;		sip_conn_rem_addr = NULL;		sip_conn_local_addr = NULL;		sip_conn_transport = NULL;		sip_header_function_table_external = NULL;		sip_stack_timeout = NULL;		sip_stack_untimeout = NULL;		return (EINVAL);	}	sip_conn_timer1 = stack_val->sip_io_pointers->sip_conn_timer1;	sip_conn_timer2 = stack_val->sip_io_pointers->sip_conn_timer2;	sip_conn_timer4 = stack_val->sip_io_pointers->sip_conn_timer4;	sip_conn_timerd = stack_val->sip_io_pointers->sip_conn_timerd;	/* Use Appln timeout routines, if provided */	if (stack_val->sip_ulp_pointers->sip_ulp_timeout != NULL) {		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout == NULL)			goto err_ret;		sip_stack_timeout =		    stack_val->sip_ulp_pointers->sip_ulp_timeout;		sip_stack_untimeout =		    stack_val->sip_ulp_pointers->sip_ulp_untimeout;	} else {		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout != NULL)			goto err_ret;		sip_timeout_init();		sip_stack_timeout = sip_timeout;		sip_stack_untimeout = sip_untimeout;	}	/* Manage Dialogs? */	if (sip_manage_dialog) {		if (stack_val->sip_ulp_pointers->sip_ulp_dlg_del != NULL) {			sip_ulp_dlg_del =			    stack_val->sip_ulp_pointers->sip_ulp_dlg_del;		}		sip_dialog_init(		    stack_val->sip_ulp_pointers->sip_ulp_dlg_state_cb);	}	sip_xaction_init(stack_val->sip_ulp_pointers->sip_ulp_trans_error,	    stack_val->sip_ulp_pointers->sip_ulp_trans_state_cb);#ifdef	__linux__	if (clock_gettime(CLOCK_REALTIME, &tspec) != 0)		goto err_ret;	sip_hash_salt = tspec.tv_nsec;#else	sip_hash_salt = gethrtime();#endif	(void) pthread_mutex_init(&sip_sent_by_lock, NULL);	return (0);}

⌨️ 快捷键说明

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