xref: /onnv-gate/usr/src/lib/libsip/common/sip_itf.c (revision 5842:e93f793783f6)
12882Svi117747 /*
22882Svi117747  * CDDL HEADER START
32882Svi117747  *
42882Svi117747  * The contents of this file are subject to the terms of the
52882Svi117747  * Common Development and Distribution License (the "License").
62882Svi117747  * You may not use this file except in compliance with the License.
72882Svi117747  *
82882Svi117747  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92882Svi117747  * or http://www.opensolaris.org/os/licensing.
102882Svi117747  * See the License for the specific language governing permissions
112882Svi117747  * and limitations under the License.
122882Svi117747  *
132882Svi117747  * When distributing Covered Code, include this CDDL HEADER in each
142882Svi117747  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152882Svi117747  * If applicable, add the following below this CDDL HEADER, with the
162882Svi117747  * fields enclosed by brackets "[]" replaced with your own identifying
172882Svi117747  * information: Portions Copyright [yyyy] [name of copyright owner]
182882Svi117747  *
192882Svi117747  * CDDL HEADER END
202882Svi117747  */
212882Svi117747 
222882Svi117747 /*
23*5842Sgm209912  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
242882Svi117747  * Use is subject to license terms.
252882Svi117747  */
262882Svi117747 
272882Svi117747 #pragma ident	"%Z%%M%	%I%	%E% SMI"
282882Svi117747 
293439Svi117747 #include <string.h>
30*5842Sgm209912 #include <strings.h>
313439Svi117747 #include <stdlib.h>
323439Svi117747 #include <assert.h>
333439Svi117747 #include <ctype.h>
343439Svi117747 #include <errno.h>
353439Svi117747 #include <pthread.h>
363439Svi117747 #include <sip.h>
373439Svi117747 
382882Svi117747 #include "sip_msg.h"
392882Svi117747 #include "sip_miscdefs.h"
402882Svi117747 #include "sip_xaction.h"
412882Svi117747 #include "sip_dialog.h"
422882Svi117747 #include "sip_parse_generic.h"
432882Svi117747 
442882Svi117747 void		(*sip_ulp_recv)(const sip_conn_object_t, sip_msg_t,
452882Svi117747 		    const sip_dialog_t) = NULL;
462882Svi117747 uint_t		(*sip_stack_timeout)(void *, void (*func)(void *),
472882Svi117747 		    struct timeval *) = NULL;
482882Svi117747 boolean_t	(*sip_stack_untimeout)(uint_t) = NULL;
492882Svi117747 int		(*sip_stack_send)(sip_conn_object_t xonn_object, char *, int) =
502882Svi117747 		    NULL;
512882Svi117747 void		(*sip_refhold_conn)(sip_conn_object_t) = NULL;
522882Svi117747 void		(*sip_refrele_conn)(sip_conn_object_t) = NULL;
532882Svi117747 boolean_t	(*sip_is_conn_stream)(sip_conn_object_t) = NULL;
542882Svi117747 boolean_t	(*sip_is_conn_reliable)(sip_conn_object_t) = NULL;
552882Svi117747 int 		(*sip_conn_rem_addr)(sip_conn_object_t, struct sockaddr *,
562882Svi117747 		    socklen_t *) = NULL;
572882Svi117747 int		(*sip_conn_local_addr)(sip_conn_object_t, struct sockaddr *,
582882Svi117747 		    socklen_t *) = NULL;
592882Svi117747 int		(*sip_conn_transport)(sip_conn_object_t) = NULL;
602882Svi117747 int		(*sip_conn_timer1)(sip_conn_object_t) = NULL;
612882Svi117747 int		(*sip_conn_timer2)(sip_conn_object_t) = NULL;
622882Svi117747 int		(*sip_conn_timer4)(sip_conn_object_t) = NULL;
632882Svi117747 int		(*sip_conn_timerd)(sip_conn_object_t) = NULL;
642882Svi117747 
652882Svi117747 boolean_t	sip_manage_dialog = B_FALSE;
662882Svi117747 
672882Svi117747 uint64_t	sip_hash_salt = 0;
682882Svi117747 
692882Svi117747 /*
702882Svi117747  * Defaults, overridden by configured values, if any
712882Svi117747  */
722882Svi117747 int		sip_timer_T1 = SIP_TIMER_T1;
732882Svi117747 int		sip_timer_T2 = SIP_TIMER_T2;
742882Svi117747 int		sip_timer_T4 = SIP_TIMER_T4;
752882Svi117747 int		sip_timer_TD = 32 * SIP_SECONDS;
762882Svi117747 
772882Svi117747 /*
782882Svi117747  * list of sent-by values registered by the UA
792882Svi117747  */
802882Svi117747 sent_by_list_t	*sip_sent_by = NULL;
812882Svi117747 int		sip_sent_by_count = 0;
822882Svi117747 pthread_mutex_t	sip_sent_by_lock;
832882Svi117747 
842882Svi117747 /*
852882Svi117747  * Create and send an error response
862882Svi117747  */
872882Svi117747 static void
sip_send_resp(sip_conn_object_t conn_obj,_sip_msg_t * sip_msg,int resp)882882Svi117747 sip_send_resp(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg, int resp)
892882Svi117747 {
902882Svi117747 	_sip_msg_t		*sip_msg_resp;
912882Svi117747 
922882Svi117747 	sip_msg_resp = (_sip_msg_t *)sip_create_response((sip_msg_t)sip_msg,
932882Svi117747 	    resp, sip_get_resp_desc(resp), NULL, NULL);
942882Svi117747 	if (sip_msg_resp == NULL) {
952882Svi117747 		/*
962882Svi117747 		 * Message was too bad to even create a
972882Svi117747 		 * response. Just drop the messge.
982882Svi117747 		 */
992882Svi117747 		return;
1002882Svi117747 	}
1012882Svi117747 	/*
1022882Svi117747 	 * We directly send it to the transport here.
1032882Svi117747 	 */
1042882Svi117747 	if (sip_adjust_msgbuf(sip_msg_resp) != 0) {
1052882Svi117747 		sip_free_msg((sip_msg_t)sip_msg_resp);
1062882Svi117747 		return;
1072882Svi117747 	}
108*5842Sgm209912 
109*5842Sgm209912 	SIP_UPDATE_COUNTERS(B_FALSE, 0, resp, B_TRUE, sip_msg_resp->
110*5842Sgm209912 	    sip_msg_len);
1112882Svi117747 	(void) sip_stack_send(conn_obj, sip_msg_resp->sip_msg_buf,
1122882Svi117747 	    sip_msg_resp->sip_msg_len);
1132882Svi117747 	sip_free_msg((sip_msg_t)sip_msg_resp);
1142882Svi117747 }
1152882Svi117747 
1162882Svi117747 /*
1172882Svi117747  * Validate some of the common headers
1182882Svi117747  */
1192882Svi117747 boolean_t
sip_check_common_headers(sip_conn_object_t conn_obj,_sip_msg_t * sip_msg)1202882Svi117747 sip_check_common_headers(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg)
1212882Svi117747 {
1222882Svi117747 	int	err;
1232882Svi117747 
1242882Svi117747 	if (sip_get_to_uri_str((sip_msg_t)sip_msg, &err) == NULL)
1252882Svi117747 		goto error;
1262882Svi117747 	if (sip_get_from_uri_str((sip_msg_t)sip_msg, &err) == NULL)
1272882Svi117747 		goto error;
1282882Svi117747 	if (sip_get_callseq_num((sip_msg_t)sip_msg, &err) < 0)
1292882Svi117747 		goto error;
1302882Svi117747 	if (sip_get_callid((sip_msg_t)sip_msg, &err) == NULL)
1312882Svi117747 		goto error;
1322882Svi117747 	return (B_FALSE);
1332882Svi117747 error:
1342882Svi117747 	sip_send_resp(conn_obj, sip_msg, SIP_BAD_REQUEST);
1352882Svi117747 	return (B_TRUE);
1362882Svi117747 }
1372882Svi117747 
1382882Svi117747 /*
1392882Svi117747  * setup pointers to where the headers are.
1402882Svi117747  */
1412882Svi117747 static int
sip_setup_header_pointers(_sip_msg_t * sip_msg)1422882Svi117747 sip_setup_header_pointers(_sip_msg_t *sip_msg)
1432882Svi117747 {
1442882Svi117747 	char		*msg;
1452882Svi117747 	_sip_header_t	*sip_msg_header;
1462882Svi117747 	char		*end;
1472882Svi117747 
1482882Svi117747 	msg = sip_msg->sip_msg_buf;
1492882Svi117747 	end = sip_msg->sip_msg_buf + sip_msg->sip_msg_len;
1502882Svi117747 	/*
1512882Svi117747 	 * Skip while space.
1522882Svi117747 	 */
1532882Svi117747 	while (isspace(*msg)) {
1542882Svi117747 		if (msg < end)
1552882Svi117747 			msg++;
1562882Svi117747 		else
1572882Svi117747 			return (EINVAL);
1582882Svi117747 	}
1592882Svi117747 
1602882Svi117747 	/*
1612882Svi117747 	 * We consider Request and Response line as a header
1622882Svi117747 	 */
1632882Svi117747 	for (;;) {
1642882Svi117747 		/*
1652882Svi117747 		 * Skip CRLF
1662882Svi117747 		 */
1672882Svi117747 		if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {
1682882Svi117747 			if (sip_msg->sip_msg_headers_end != NULL) {
1692882Svi117747 				SKIP_CRLF(msg);
1702882Svi117747 				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;
1712882Svi117747 			}
1722882Svi117747 			/*
1732882Svi117747 			 * Start of a header.
1742882Svi117747 			 * Check for empty line.
1752882Svi117747 			 */
1762882Svi117747 			if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {
1772882Svi117747 				/*
1782882Svi117747 				 * empty line, start of content.
1792882Svi117747 				 */
1802882Svi117747 				SKIP_CRLF(msg);
1812882Svi117747 				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;
1822882Svi117747 				break;
1832882Svi117747 			}
1842882Svi117747 			/*
1852882Svi117747 			 * store start of header.
1862882Svi117747 			 */
1872882Svi117747 			sip_msg_header = calloc(1, sizeof (_sip_header_t));
1882882Svi117747 			if (sip_msg_header == NULL)
1892882Svi117747 				return (EINVAL);
1902882Svi117747 			sip_msg_header->sip_hdr_start = msg;
1912882Svi117747 			sip_msg_header->sip_hdr_current = msg;
1922882Svi117747 			sip_msg_header->sip_hdr_allocated = B_FALSE;
1932882Svi117747 			sip_msg_header->sip_hdr_prev =
1942882Svi117747 			    sip_msg->sip_msg_headers_end;
1952882Svi117747 			sip_msg_header->sip_hdr_next = NULL;
1962882Svi117747 			sip_msg_header->sip_hdr_sipmsg = sip_msg;
1972882Svi117747 			sip_msg->sip_msg_headers_end->sip_hdr_next =
1982882Svi117747 			    sip_msg_header;
1992882Svi117747 			sip_msg->sip_msg_headers_end = sip_msg_header;
2002882Svi117747 		} else {
2012882Svi117747 			if (sip_msg->sip_msg_headers_start == NULL) {
2022882Svi117747 				/*
2032882Svi117747 				 * Allocate first header structure.
2042882Svi117747 				 */
2052882Svi117747 				sip_msg_header = calloc(1,
2062882Svi117747 				    sizeof (_sip_header_t));
2072882Svi117747 				if (sip_msg_header == NULL)
2082882Svi117747 					return (EINVAL);
2092882Svi117747 				sip_msg_header->sip_hdr_allocated = B_FALSE;
2102882Svi117747 				sip_msg_header->sip_hdr_start = msg;
2112882Svi117747 				sip_msg_header->sip_hdr_current = msg;
2122882Svi117747 				sip_msg_header->sip_hdr_sipmsg = sip_msg;
2132882Svi117747 				sip_msg->sip_msg_headers_start = sip_msg_header;
2142882Svi117747 				sip_msg->sip_msg_headers_end = sip_msg_header;
2152882Svi117747 			}
2162882Svi117747 			msg++;
2172882Svi117747 		}
2182882Svi117747 		/*
2192882Svi117747 		 * We have reached the end without hitting the empty line.
2202882Svi117747 		 */
2212882Svi117747 		if (msg - sip_msg->sip_msg_buf >= sip_msg->sip_msg_len)
2222882Svi117747 			return (EINVAL);
2232882Svi117747 	}
2242882Svi117747 
2252882Svi117747 	if (sip_msg->sip_msg_headers_start == NULL)
2262882Svi117747 		return (EPROTO);
2272882Svi117747 
2282882Svi117747 	/*
2292882Svi117747 	 * Move start line to be a separate line.
2302882Svi117747 	 */
2312882Svi117747 	sip_msg->sip_msg_start_line = sip_msg->sip_msg_headers_start;
2322882Svi117747 	sip_msg->sip_msg_headers_start =
2332882Svi117747 	    sip_msg->sip_msg_headers_start->sip_hdr_next;
2342882Svi117747 	sip_msg->sip_msg_start_line->sip_hdr_prev = NULL;
2352882Svi117747 	sip_msg->sip_msg_start_line->sip_hdr_next = NULL;
2362882Svi117747 
2372882Svi117747 	if (sip_msg->sip_msg_headers_start == NULL)
2382882Svi117747 		return (EINVAL);
2392882Svi117747 	sip_msg->sip_msg_headers_start->sip_hdr_prev = NULL;
2402882Svi117747 
2412882Svi117747 
2422882Svi117747 	/*
2432882Svi117747 	 * Deal with content.
2442882Svi117747 	 */
2452882Svi117747 	sip_msg->sip_msg_content = calloc(1, sizeof (sip_content_t));
2462882Svi117747 	sip_msg->sip_msg_content->sip_content_start = msg;
2472882Svi117747 	sip_msg->sip_msg_content->sip_content_end = sip_msg->sip_msg_buf +
2482882Svi117747 	    sip_msg->sip_msg_len;
2492882Svi117747 	sip_msg->sip_msg_content->sip_content_allocated = B_FALSE;
2502882Svi117747 	sip_msg->sip_msg_content_len =
2512882Svi117747 	    sip_msg->sip_msg_content->sip_content_end -
2522882Svi117747 	    sip_msg->sip_msg_content->sip_content_start;
2532882Svi117747 	return (0);
2542882Svi117747 }
2552882Svi117747 
2562882Svi117747 /*
2572882Svi117747  * The send interface to the sip stack. Used by upper layers.
2582882Svi117747  */
2592882Svi117747 int
sip_sendmsg(sip_conn_object_t obj,sip_msg_t sip_msg,sip_dialog_t dialog,uint32_t flags)2602882Svi117747 sip_sendmsg(sip_conn_object_t obj, sip_msg_t sip_msg, sip_dialog_t dialog,
2612882Svi117747     uint32_t flags)
2622882Svi117747 {
2632882Svi117747 	sip_xaction_t		*sip_trans = NULL;
2642882Svi117747 	int			ret = 0;
2652882Svi117747 	sip_message_type_t	*sip_msg_info;
2662882Svi117747 	_sip_msg_t 		*_sip_msg;
2672882Svi117747 	boolean_t		stateful = flags & SIP_SEND_STATEFUL;
2682882Svi117747 	boolean_t		dlg_on_fork = flags & SIP_DIALOG_ON_FORK;
2692882Svi117747 
2702882Svi117747 	sip_refhold_conn(obj);
2712882Svi117747 
2722882Svi117747 	_sip_msg = (_sip_msg_t *)sip_msg;
2732882Svi117747 	if ((ret = sip_adjust_msgbuf(_sip_msg)) != 0) {
2742882Svi117747 		sip_refrele_conn(obj);
2752882Svi117747 		return (ret);
2762882Svi117747 	}
2772882Svi117747 
2782882Svi117747 	assert(_sip_msg->sip_msg_req_res != NULL);
2792882Svi117747 	sip_msg_info = _sip_msg->sip_msg_req_res;
2802882Svi117747 	/*
2812882Svi117747 	 * Send it statefully if:
2822882Svi117747 	 * if stateful is set in 'flags' AND
2832882Svi117747 	 * this is not an ACK request, if it is a request (should the upper
2842882Svi117747 	 * layer set stateful in the latter case?, i.e is the check
2852882Svi117747 	 * necessary here?)
2862882Svi117747 	 */
2872882Svi117747 	if (stateful && (!sip_msg_info->is_request ||
2882882Svi117747 	    sip_msg_info->sip_req_method != ACK)) {
2892882Svi117747 		sip_trans = (sip_xaction_t *)sip_xaction_get(obj, sip_msg,
2902882Svi117747 		    B_TRUE, sip_msg_info->is_request ? SIP_CLIENT_TRANSACTION :
2912882Svi117747 		    SIP_SERVER_TRANSACTION, &ret);
2922882Svi117747 		if (sip_trans == NULL) {
2932882Svi117747 			sip_refrele_conn(obj);
2942882Svi117747 			return (ret);
2952882Svi117747 		}
2962882Svi117747 		ret = sip_xaction_output(obj, sip_trans, _sip_msg);
2972882Svi117747 		SIP_XACTION_REFCNT_DECR(sip_trans);
2982882Svi117747 		if (ret != 0) {
2992882Svi117747 			sip_refrele_conn(obj);
3002882Svi117747 			return (ret);
3012882Svi117747 		}
3022882Svi117747 	}
3032882Svi117747 	/*
3042882Svi117747 	 * If the appln wants us to create the dialog, create a partial
3052882Svi117747 	 * dialog at this stage, when we get the response, we will
3062882Svi117747 	 * complete it.
3072882Svi117747 	 */
3082882Svi117747 	if (sip_manage_dialog) {
3092882Svi117747 		if (sip_msg_info->is_request && dialog == NULL) {
3102882Svi117747 			dialog = (sip_dialog_t)sip_seed_dialog(obj, sip_msg,
3112882Svi117747 			    dlg_on_fork, SIP_UAC_DIALOG);
3122882Svi117747 		} else if (dialog != NULL && (!sip_msg_info->is_request ||
3132882Svi117747 		    sip_msg_info->sip_req_method == NOTIFY)) {
3142882Svi117747 			(void) sip_update_dialog(dialog, _sip_msg);
315*5842Sgm209912 		} else if (dialog != NULL) {
316*5842Sgm209912 			/*
317*5842Sgm209912 			 * Dialog is in CONFIRMED state. If logging is enabled
318*5842Sgm209912 			 * track the SIP message sent within a dialog.
319*5842Sgm209912 			 */
320*5842Sgm209912 			(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
321*5842Sgm209912 			dialog->sip_dlg_msgcnt++;
322*5842Sgm209912 			sip_add_log(&dialog->sip_dlg_log[dialog->sip_dlg_state],
323*5842Sgm209912 			    (sip_msg_t)sip_msg, dialog->sip_dlg_msgcnt,
324*5842Sgm209912 			    SIP_DIALOG_LOG);
325*5842Sgm209912 			(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
326*5842Sgm209912 
327*5842Sgm209912 			if (sip_msg_info->is_request && sip_msg_info->
328*5842Sgm209912 			    sip_req_method == INVITE) {
329*5842Sgm209912 				(void) sip_dialog_add_new_contact(dialog,
330*5842Sgm209912 				    _sip_msg);
331*5842Sgm209912 			}
3322882Svi117747 		}
3332882Svi117747 	}
334*5842Sgm209912 	/*
335*5842Sgm209912 	 * if measure sip traffic is enabled, capture the measurements
336*5842Sgm209912 	 * Is this the right place to measure or should I put this after
337*5842Sgm209912 	 * the call to sip_stack_send()
338*5842Sgm209912 	 */
339*5842Sgm209912 	if (sip_msg_info->is_request) {
340*5842Sgm209912 		SIP_UPDATE_COUNTERS(B_TRUE, sip_msg_info->sip_req_method, 0,
341*5842Sgm209912 		    B_TRUE, _sip_msg->sip_msg_len);
342*5842Sgm209912 	} else {
343*5842Sgm209912 		SIP_UPDATE_COUNTERS(B_FALSE, 0, sip_msg_info->sip_resp_code,
344*5842Sgm209912 		    B_TRUE, _sip_msg->sip_msg_len);
345*5842Sgm209912 	}
3462882Svi117747 	if ((ret = sip_stack_send(obj, _sip_msg->sip_msg_buf,
3472882Svi117747 	    _sip_msg->sip_msg_len)) != 0) {
3482882Svi117747 		if (sip_trans != NULL) {
3492882Svi117747 			sip_xaction_terminate(sip_trans, _sip_msg,
3502882Svi117747 			    sip_conn_transport(obj));
3512882Svi117747 		}
3522882Svi117747 		sip_refrele_conn(obj);
3532882Svi117747 		return (ret);
3542882Svi117747 	}
3552882Svi117747 	sip_refrele_conn(obj);
3562882Svi117747 	return (ret);
3572882Svi117747 }
3582882Svi117747 
3592882Svi117747 /*
3602882Svi117747  * Given a sent-by value check if it is in the registered list. If no values
3612882Svi117747  * have been registered, the check passes.
3622882Svi117747  */
3632882Svi117747 static boolean_t
sip_sent_by_registered(const sip_str_t * sb_val)3642882Svi117747 sip_sent_by_registered(const sip_str_t *sb_val)
3652882Svi117747 {
3662882Svi117747 	sent_by_list_t	*sb;
3672882Svi117747 	int		count = 0;
3682882Svi117747 
3692882Svi117747 	(void) pthread_mutex_lock(&sip_sent_by_lock);
3702882Svi117747 	if (sip_sent_by == NULL) {
3712882Svi117747 		(void) pthread_mutex_unlock(&sip_sent_by_lock);
3722882Svi117747 		return (B_TRUE);
3732882Svi117747 	}
3742882Svi117747 	sb = sip_sent_by;
3752882Svi117747 	for (count = 0; count < sip_sent_by_count; count++) {
3762882Svi117747 		if (strncasecmp(sb->sb_val, sb_val->sip_str_ptr,
3772882Svi117747 		    sb_val->sip_str_len) == 0) {
3782882Svi117747 			(void) pthread_mutex_unlock(&sip_sent_by_lock);
3792882Svi117747 			return (B_TRUE);
3802882Svi117747 		}
3812882Svi117747 		sb = sb->sb_next;
3822882Svi117747 	}
3832882Svi117747 	(void) pthread_mutex_unlock(&sip_sent_by_lock);
3842882Svi117747 	return (B_FALSE);
3852882Svi117747 }
3862882Svi117747 
3872882Svi117747 /*
3882882Svi117747  * Given a response, check if the sent-by in the VIA header is valid.
3892882Svi117747  */
3902882Svi117747 boolean_t
sip_valid_sent_by(sip_msg_t sip_msg)3912882Svi117747 sip_valid_sent_by(sip_msg_t sip_msg)
3922882Svi117747 {
3932882Svi117747 	sip_header_t		via;
3942882Svi117747 	sip_header_value_t	value = NULL;
3952882Svi117747 	int			error;
3962882Svi117747 	const sip_str_t		*sent_by = NULL;
3972882Svi117747 
3982882Svi117747 	via = (sip_header_t)sip_get_header(sip_msg, SIP_VIA,  NULL, &error);
3992882Svi117747 	if (via == NULL || error != 0)
4002882Svi117747 		return (B_TRUE);
4012882Svi117747 	value = (sip_header_value_t)sip_get_header_value(via, &error);
4022882Svi117747 	if (value == NULL || error != 0)
4032882Svi117747 		return (B_TRUE);
4042882Svi117747 	sent_by = sip_get_via_sent_by_host(value, &error);
4052882Svi117747 	if (sent_by == NULL || error != 0)
4062882Svi117747 		return (B_TRUE);
4072882Svi117747 	if (sip_sent_by_registered(sent_by))
4082882Svi117747 		return (B_TRUE);
4092882Svi117747 	return (B_FALSE);
4102882Svi117747 }
4112882Svi117747 
4122882Svi117747 
4132882Svi117747 /*
4142882Svi117747  * The receive interface to the transport layer.
4152882Svi117747  */
4162882Svi117747 void
sip_process_new_packet(sip_conn_object_t conn_object,void * msgstr,size_t msglen)4172882Svi117747 sip_process_new_packet(sip_conn_object_t conn_object, void *msgstr,
4182882Svi117747     size_t msglen)
4192882Svi117747 {
4202882Svi117747 	_sip_msg_t		*sip_msg;
4212882Svi117747 	sip_message_type_t	*sip_msg_info;
4222882Svi117747 	sip_xaction_t		*sip_trans;
4232882Svi117747 	sip_dialog_t		dialog = NULL;
4242882Svi117747 	boolean_t		dialog_created = B_FALSE;
4252882Svi117747 	int			transport;
4262882Svi117747 	char			*msgbuf = NULL;
4272882Svi117747 
4282882Svi117747 	sip_refhold_conn(conn_object);
4292882Svi117747 	transport = sip_conn_transport(conn_object);
4302882Svi117747 	if (transport == IPPROTO_TCP) {
4312882Svi117747 next_msg:
4322882Svi117747 		msgstr = (char *)sip_get_tcp_msg(conn_object, (char *)msgstr,
4332882Svi117747 		    &msglen);
4342882Svi117747 		if (msgstr == NULL) {
4352882Svi117747 			sip_refrele_conn(conn_object);
4362882Svi117747 			return;
4372882Svi117747 		}
4382882Svi117747 	} else {
4392882Svi117747 		msgbuf = (char *)malloc(msglen + 1);
4402882Svi117747 		if (msgbuf == NULL) {
4412882Svi117747 			sip_refrele_conn(conn_object);
4422882Svi117747 			return;
4432882Svi117747 		}
4442882Svi117747 		(void) strncpy(msgbuf, msgstr, msglen);
4452882Svi117747 		msgbuf[msglen] = '\0';
4462882Svi117747 		msgstr = msgbuf;
4472882Svi117747 	}
4482882Svi117747 	sip_msg = (_sip_msg_t *)sip_new_msg();
4492882Svi117747 	if (sip_msg == NULL) {
4502882Svi117747 		if (msgbuf != NULL)
4512882Svi117747 			free(msgbuf);
4522882Svi117747 		sip_refrele_conn(conn_object);
4532882Svi117747 		return;
4542882Svi117747 	}
4552882Svi117747 	sip_msg->sip_msg_buf = (char *)msgstr;
4562882Svi117747 	sip_msg->sip_msg_len = msglen;
4572882Svi117747 	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
4582882Svi117747 	if (sip_setup_header_pointers(sip_msg) != 0) {
4592882Svi117747 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
4602882Svi117747 		sip_refrele_conn(conn_object);
4612882Svi117747 		sip_free_msg((sip_msg_t)sip_msg);
4622882Svi117747 		return;
4632882Svi117747 	}
4642882Svi117747 	if (sip_parse_first_line(sip_msg->sip_msg_start_line,
4652882Svi117747 	    &sip_msg->sip_msg_req_res)) {
4662882Svi117747 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
4672882Svi117747 		sip_refrele_conn(conn_object);
4682882Svi117747 		sip_free_msg((sip_msg_t)sip_msg);
4692882Svi117747 		return;
4702882Svi117747 	}
4712882Svi117747 	sip_msg_info = sip_msg->sip_msg_req_res;
4722882Svi117747 	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
4732882Svi117747 
4742882Svi117747 	if (sip_check_common_headers(conn_object, sip_msg)) {
4752882Svi117747 		sip_refrele_conn(conn_object);
4762882Svi117747 		sip_free_msg((sip_msg_t)sip_msg);
4772882Svi117747 		return;
4782882Svi117747 	}
4792882Svi117747 
4802882Svi117747 	/*
4812882Svi117747 	 * Silently discard the response if the top VIA has a sent-by value AND
4822882Svi117747 	 * the UA has registered sent-by values AND the one in the VIA is
4832882Svi117747 	 * not part of the registerd sent-by values.
4842882Svi117747 	 */
4852882Svi117747 	if (!sip_msg_info->is_request && !sip_valid_sent_by(sip_msg)) {
4862882Svi117747 		sip_refrele_conn(conn_object);
4872882Svi117747 		sip_free_msg((sip_msg_t)sip_msg);
4882882Svi117747 		return;
4892882Svi117747 
4902882Svi117747 	}
4912882Svi117747 	sip_trans = (sip_xaction_t *)sip_xaction_get(conn_object,
4922882Svi117747 	    (sip_msg_t)sip_msg,
4932882Svi117747 	    B_FALSE, sip_msg_info->is_request ? SIP_SERVER_TRANSACTION :
4942882Svi117747 	    SIP_CLIENT_TRANSACTION, NULL);
4952882Svi117747 	if (sip_trans != NULL) {
4962882Svi117747 		if (sip_xaction_input(conn_object, sip_trans, &sip_msg) != 0) {
4972882Svi117747 			SIP_XACTION_REFCNT_DECR(sip_trans);
4982882Svi117747 			sip_refrele_conn(conn_object);
4992882Svi117747 			sip_free_msg((sip_msg_t)sip_msg);
5002882Svi117747 			return;
5012882Svi117747 		}
5022882Svi117747 		SIP_XACTION_REFCNT_DECR(sip_trans);
5032882Svi117747 
5042882Svi117747 		/*
5052882Svi117747 		 * msg was retransmission - handled by the transaction
5062882Svi117747 		 */
5072882Svi117747 		if (sip_msg == NULL)
5082882Svi117747 			goto check_next;
5092882Svi117747 	} else {
5102882Svi117747 		/*
5112882Svi117747 		 * If we are getting an INVITE request, let us send a
5122882Svi117747 		 * 100 TRYING response here, as in 17.2.1:
5132882Svi117747 		 * "The server transaction MUST generate a 100 (Trying)
5142882Svi117747 		 * response unless it knows that the TU will generate a
5152882Svi117747 		 * provisional or final response within 200 ms".
5162882Svi117747 		 */
5172882Svi117747 		if (sip_msg_info->is_request &&
5182882Svi117747 		    sip_msg_info->sip_req_method == INVITE) {
5192882Svi117747 			sip_send_resp(conn_object, sip_msg, SIP_TRYING);
5202882Svi117747 		}
5212882Svi117747 	}
5222882Svi117747 	if (sip_manage_dialog) {
5232882Svi117747 		dialog = sip_dialog_find(sip_msg);
5242882Svi117747 		if (dialog == NULL) {
5252882Svi117747 			if (sip_msg_info->is_request) {
5262882Svi117747 				/*
5272882Svi117747 				 * sip_seed_dialog will check for the
5282882Svi117747 				 * method in the request
5292882Svi117747 				 */
5302882Svi117747 				dialog = (sip_dialog_t)sip_seed_dialog(
5312882Svi117747 				    conn_object, sip_msg,
5322882Svi117747 				    B_FALSE, SIP_UAS_DIALOG);
5332882Svi117747 				dialog_created = B_TRUE;
5342882Svi117747 			}
5352882Svi117747 		} else if (sip_incomplete_dialog(dialog)) {
5362882Svi117747 			if (!sip_msg_info->is_request ||
5372882Svi117747 			    sip_msg_info->sip_req_method == NOTIFY) {
5382882Svi117747 				dialog = sip_update_dialog(dialog, sip_msg);
5392882Svi117747 			}
5402882Svi117747 		} else if (sip_dialog_process(sip_msg, &dialog) != 0) {
5412882Svi117747 			if (dialog != NULL)
5422882Svi117747 				sip_release_dialog(dialog);
5432882Svi117747 			/*
5442882Svi117747 			 * cseq number in error, send a
5452882Svi117747 			 * SIP_SERVER_INTERNAL_ERROR response.
5462882Svi117747 			 */
5472882Svi117747 			if (sip_msg_info->is_request) {
5482882Svi117747 				sip_send_resp(conn_object, sip_msg,
5492882Svi117747 				    SIP_SERVER_INTERNAL_ERROR);
5502882Svi117747 			}
5512882Svi117747 			sip_refrele_conn(conn_object);
5522882Svi117747 			sip_free_msg((sip_msg_t)sip_msg);
5532882Svi117747 			return;
5542882Svi117747 		}
5552882Svi117747 	}
556*5842Sgm209912 	if (sip_msg_info->is_request) {
557*5842Sgm209912 		SIP_UPDATE_COUNTERS(B_TRUE, sip_msg_info->sip_req_method, 0,
558*5842Sgm209912 		    B_FALSE, sip_msg->sip_msg_len);
559*5842Sgm209912 	} else {
560*5842Sgm209912 		SIP_UPDATE_COUNTERS(B_FALSE, 0, sip_msg_info->sip_resp_code,
561*5842Sgm209912 		    B_FALSE, sip_msg->sip_msg_len);
562*5842Sgm209912 	}
5632882Svi117747 	sip_ulp_recv(conn_object, (sip_msg_t)sip_msg, dialog);
5642882Svi117747 	sip_free_msg((sip_msg_t)sip_msg);
5652882Svi117747 	if (dialog != NULL && !dialog_created)
5662882Svi117747 		sip_release_dialog(dialog);
5672882Svi117747 check_next:
5682882Svi117747 	/*
5692882Svi117747 	 * Check if there are more complete messages in the TCP fragment list
5702882Svi117747 	 * to be consumed
5712882Svi117747 	 */
5722882Svi117747 	if (transport == IPPROTO_TCP) {
5732882Svi117747 		msgstr = NULL;
5742882Svi117747 		msglen = 0;
5752882Svi117747 		goto next_msg;
5762882Svi117747 	}
5772882Svi117747 	sip_refrele_conn(conn_object);
5782882Svi117747 }
5792882Svi117747 
5802882Svi117747 /*
5812882Svi117747  * Initialize the stack. The connection manager functions, upper layer
5822882Svi117747  * receive functions are mandatory.
5832882Svi117747  */
5842882Svi117747 int
sip_stack_init(sip_stack_init_t * stack_val)5852882Svi117747 sip_stack_init(sip_stack_init_t *stack_val)
5862882Svi117747 {
5872882Svi117747 #ifdef	__linux__
5882882Svi117747 	struct timespec	tspec;
5892882Svi117747 #endif
5902882Svi117747 
5912882Svi117747 	/*
5922882Svi117747 	 * If the stack has already been configured, return error
5932882Svi117747 	 */
5942882Svi117747 	if (sip_stack_send != NULL ||
5952882Svi117747 	    stack_val->sip_version != SIP_STACK_VERSION) {
5962882Svi117747 		return (EINVAL);
5972882Svi117747 	}
5982882Svi117747 	if (stack_val->sip_io_pointers == NULL ||
5992882Svi117747 	    stack_val->sip_ulp_pointers == NULL) {
6002882Svi117747 		return (EINVAL);
6012882Svi117747 	}
6022882Svi117747 	sip_ulp_recv = stack_val->sip_ulp_pointers->sip_ulp_recv;
6032882Svi117747 	sip_manage_dialog = stack_val->sip_stack_flags & SIP_STACK_DIALOGS;
6042882Svi117747 
6052882Svi117747 	sip_stack_send = stack_val->sip_io_pointers->sip_conn_send;
6062882Svi117747 	sip_refhold_conn = stack_val->sip_io_pointers->sip_hold_conn_object;
6072882Svi117747 	sip_refrele_conn = stack_val->sip_io_pointers->sip_rel_conn_object;
6082882Svi117747 	sip_is_conn_stream = stack_val->sip_io_pointers->sip_conn_is_stream;
6092882Svi117747 	sip_is_conn_reliable = stack_val->sip_io_pointers->sip_conn_is_reliable;
6102882Svi117747 	sip_conn_rem_addr = stack_val->sip_io_pointers->sip_conn_remote_address;
6112882Svi117747 	sip_conn_local_addr =
6122882Svi117747 	    stack_val->sip_io_pointers->sip_conn_local_address;
6132882Svi117747 	sip_conn_transport = stack_val->sip_io_pointers->sip_conn_transport;
6142882Svi117747 	sip_header_function_table_external = stack_val->sip_function_table;
6152882Svi117747 
6162882Svi117747 	if (sip_ulp_recv == NULL || sip_stack_send == NULL ||
6172882Svi117747 	    sip_refhold_conn == NULL || sip_refrele_conn == NULL ||
6182882Svi117747 	    sip_is_conn_stream == NULL || sip_is_conn_reliable == NULL ||
6192882Svi117747 	    sip_conn_rem_addr == NULL || sip_conn_local_addr == NULL ||
6202882Svi117747 	    sip_conn_transport == NULL) {
6212882Svi117747 	err_ret:
6222882Svi117747 		sip_ulp_recv = NULL;
6232882Svi117747 		sip_stack_send = NULL;
6242882Svi117747 		sip_refhold_conn = NULL;
6252882Svi117747 		sip_refrele_conn = NULL;
6262882Svi117747 		sip_is_conn_stream = NULL;
6272882Svi117747 		sip_is_conn_reliable = NULL;
6282882Svi117747 		sip_conn_rem_addr = NULL;
6292882Svi117747 		sip_conn_local_addr = NULL;
6302882Svi117747 		sip_conn_transport = NULL;
6312882Svi117747 		sip_header_function_table_external = NULL;
6322882Svi117747 		sip_stack_timeout = NULL;
6332882Svi117747 		sip_stack_untimeout = NULL;
6342882Svi117747 		return (EINVAL);
6352882Svi117747 	}
6362882Svi117747 
6372882Svi117747 	sip_conn_timer1 = stack_val->sip_io_pointers->sip_conn_timer1;
6382882Svi117747 	sip_conn_timer2 = stack_val->sip_io_pointers->sip_conn_timer2;
6392882Svi117747 	sip_conn_timer4 = stack_val->sip_io_pointers->sip_conn_timer4;
6402882Svi117747 	sip_conn_timerd = stack_val->sip_io_pointers->sip_conn_timerd;
6412882Svi117747 
6422882Svi117747 	/*
6432882Svi117747 	 * Use Appln timeout routines, if provided
6442882Svi117747 	 */
6452882Svi117747 	if (stack_val->sip_ulp_pointers->sip_ulp_timeout != NULL) {
6462882Svi117747 		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout == NULL)
6472882Svi117747 			goto err_ret;
6482882Svi117747 		sip_stack_timeout =
6492882Svi117747 		    stack_val->sip_ulp_pointers->sip_ulp_timeout;
6502882Svi117747 		sip_stack_untimeout =
6512882Svi117747 		    stack_val->sip_ulp_pointers->sip_ulp_untimeout;
6522882Svi117747 	} else {
6532882Svi117747 		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout != NULL)
6542882Svi117747 			goto err_ret;
6552882Svi117747 		sip_timeout_init();
6562882Svi117747 		sip_stack_timeout = sip_timeout;
6572882Svi117747 		sip_stack_untimeout = sip_untimeout;
6582882Svi117747 	}
6592882Svi117747 
6602882Svi117747 	/*
6612882Svi117747 	 * Manage Dialogs?
6622882Svi117747 	 */
6632882Svi117747 	if (sip_manage_dialog) {
6642882Svi117747 		sip_dialog_init(stack_val->sip_ulp_pointers->sip_ulp_dlg_del,
6652882Svi117747 		    stack_val->sip_ulp_pointers->sip_ulp_dlg_state_cb);
6662882Svi117747 	}
6672882Svi117747 	sip_xaction_init(stack_val->sip_ulp_pointers->sip_ulp_trans_error,
6682882Svi117747 	    stack_val->sip_ulp_pointers->sip_ulp_trans_state_cb);
6692882Svi117747 
670*5842Sgm209912 	/*
671*5842Sgm209912 	 * Initialize SIP traffic counter mutex
672*5842Sgm209912 	 */
673*5842Sgm209912 	(void) pthread_mutex_init(&sip_counters.sip_counter_mutex, NULL);
674*5842Sgm209912 
675*5842Sgm209912 	/*
676*5842Sgm209912 	 * Initialize SIP logfile structures mutex
677*5842Sgm209912 	 */
678*5842Sgm209912 	(void) pthread_mutex_init(&trans_log.sip_logfile_mutex, NULL);
679*5842Sgm209912 	(void) pthread_mutex_init(&dialog_log.sip_logfile_mutex, NULL);
680*5842Sgm209912 
6812882Svi117747 #ifdef	__linux__
6822882Svi117747 	if (clock_gettime(CLOCK_REALTIME, &tspec) != 0)
6832882Svi117747 		goto err_ret;
6842882Svi117747 	sip_hash_salt = tspec.tv_nsec;
6852882Svi117747 #else
6862882Svi117747 	sip_hash_salt = gethrtime();
6872882Svi117747 #endif
6882882Svi117747 	(void) pthread_mutex_init(&sip_sent_by_lock, NULL);
6892882Svi117747 	return (0);
6902882Svi117747 }
691