xref: /illumos-gate/usr/src/lib/libsip/common/sip_itf.c (revision bb9b6b3f59b8820022416cea99b49c50fef6e391)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <string.h>
30 #include <strings.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include <pthread.h>
36 #include <sip.h>
37 
38 #include "sip_msg.h"
39 #include "sip_miscdefs.h"
40 #include "sip_xaction.h"
41 #include "sip_dialog.h"
42 #include "sip_parse_generic.h"
43 
44 void		(*sip_ulp_recv)(const sip_conn_object_t, sip_msg_t,
45 		    const sip_dialog_t) = NULL;
46 uint_t		(*sip_stack_timeout)(void *, void (*func)(void *),
47 		    struct timeval *) = NULL;
48 boolean_t	(*sip_stack_untimeout)(uint_t) = NULL;
49 int		(*sip_stack_send)(sip_conn_object_t xonn_object, char *, int) =
50 		    NULL;
51 void		(*sip_refhold_conn)(sip_conn_object_t) = NULL;
52 void		(*sip_refrele_conn)(sip_conn_object_t) = NULL;
53 boolean_t	(*sip_is_conn_stream)(sip_conn_object_t) = NULL;
54 boolean_t	(*sip_is_conn_reliable)(sip_conn_object_t) = NULL;
55 int 		(*sip_conn_rem_addr)(sip_conn_object_t, struct sockaddr *,
56 		    socklen_t *) = NULL;
57 int		(*sip_conn_local_addr)(sip_conn_object_t, struct sockaddr *,
58 		    socklen_t *) = NULL;
59 int		(*sip_conn_transport)(sip_conn_object_t) = NULL;
60 int		(*sip_conn_timer1)(sip_conn_object_t) = NULL;
61 int		(*sip_conn_timer2)(sip_conn_object_t) = NULL;
62 int		(*sip_conn_timer4)(sip_conn_object_t) = NULL;
63 int		(*sip_conn_timerd)(sip_conn_object_t) = NULL;
64 
65 boolean_t	sip_manage_dialog = B_FALSE;
66 
67 uint64_t	sip_hash_salt = 0;
68 
69 /*
70  * Defaults, overridden by configured values, if any
71  */
72 int		sip_timer_T1 = SIP_TIMER_T1;
73 int		sip_timer_T2 = SIP_TIMER_T2;
74 int		sip_timer_T4 = SIP_TIMER_T4;
75 int		sip_timer_TD = 32 * SIP_SECONDS;
76 
77 /*
78  * list of sent-by values registered by the UA
79  */
80 sent_by_list_t	*sip_sent_by = NULL;
81 int		sip_sent_by_count = 0;
82 pthread_mutex_t	sip_sent_by_lock;
83 
84 /*
85  * Create and send an error response
86  */
87 static void
88 sip_send_resp(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg, int resp)
89 {
90 	_sip_msg_t		*sip_msg_resp;
91 
92 	sip_msg_resp = (_sip_msg_t *)sip_create_response((sip_msg_t)sip_msg,
93 	    resp, sip_get_resp_desc(resp), NULL, NULL);
94 	if (sip_msg_resp == NULL) {
95 		/*
96 		 * Message was too bad to even create a
97 		 * response. Just drop the messge.
98 		 */
99 		return;
100 	}
101 	/*
102 	 * We directly send it to the transport here.
103 	 */
104 	if (sip_adjust_msgbuf(sip_msg_resp) != 0) {
105 		sip_free_msg((sip_msg_t)sip_msg_resp);
106 		return;
107 	}
108 
109 	SIP_UPDATE_COUNTERS(B_FALSE, 0, resp, B_TRUE, sip_msg_resp->
110 	    sip_msg_len);
111 	(void) sip_stack_send(conn_obj, sip_msg_resp->sip_msg_buf,
112 	    sip_msg_resp->sip_msg_len);
113 	sip_free_msg((sip_msg_t)sip_msg_resp);
114 }
115 
116 /*
117  * Validate some of the common headers
118  */
119 boolean_t
120 sip_check_common_headers(sip_conn_object_t conn_obj, _sip_msg_t *sip_msg)
121 {
122 	int	err;
123 
124 	if (sip_get_to_uri_str((sip_msg_t)sip_msg, &err) == NULL)
125 		goto error;
126 	if (sip_get_from_uri_str((sip_msg_t)sip_msg, &err) == NULL)
127 		goto error;
128 	if (sip_get_callseq_num((sip_msg_t)sip_msg, &err) < 0)
129 		goto error;
130 	if (sip_get_callid((sip_msg_t)sip_msg, &err) == NULL)
131 		goto error;
132 	return (B_FALSE);
133 error:
134 	sip_send_resp(conn_obj, sip_msg, SIP_BAD_REQUEST);
135 	return (B_TRUE);
136 }
137 
138 /*
139  * setup pointers to where the headers are.
140  */
141 static int
142 sip_setup_header_pointers(_sip_msg_t *sip_msg)
143 {
144 	char		*msg;
145 	_sip_header_t	*sip_msg_header;
146 	char		*end;
147 
148 	msg = sip_msg->sip_msg_buf;
149 	end = sip_msg->sip_msg_buf + sip_msg->sip_msg_len;
150 	/*
151 	 * Skip while space.
152 	 */
153 	while (isspace(*msg)) {
154 		if (msg < end)
155 			msg++;
156 		else
157 			return (EINVAL);
158 	}
159 
160 	/*
161 	 * We consider Request and Response line as a header
162 	 */
163 	for (;;) {
164 		/*
165 		 * Skip CRLF
166 		 */
167 		if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {
168 			if (sip_msg->sip_msg_headers_end != NULL) {
169 				SKIP_CRLF(msg);
170 				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;
171 			}
172 			/*
173 			 * Start of a header.
174 			 * Check for empty line.
175 			 */
176 			if (strncmp(SIP_CRLF, msg, strlen(SIP_CRLF)) == 0) {
177 				/*
178 				 * empty line, start of content.
179 				 */
180 				SKIP_CRLF(msg);
181 				sip_msg->sip_msg_headers_end->sip_hdr_end = msg;
182 				break;
183 			}
184 			/*
185 			 * store start of header.
186 			 */
187 			sip_msg_header = calloc(1, sizeof (_sip_header_t));
188 			if (sip_msg_header == NULL)
189 				return (EINVAL);
190 			sip_msg_header->sip_hdr_start = msg;
191 			sip_msg_header->sip_hdr_current = msg;
192 			sip_msg_header->sip_hdr_allocated = B_FALSE;
193 			sip_msg_header->sip_hdr_prev =
194 			    sip_msg->sip_msg_headers_end;
195 			sip_msg_header->sip_hdr_next = NULL;
196 			sip_msg_header->sip_hdr_sipmsg = sip_msg;
197 			sip_msg->sip_msg_headers_end->sip_hdr_next =
198 			    sip_msg_header;
199 			sip_msg->sip_msg_headers_end = sip_msg_header;
200 		} else {
201 			if (sip_msg->sip_msg_headers_start == NULL) {
202 				/*
203 				 * Allocate first header structure.
204 				 */
205 				sip_msg_header = calloc(1,
206 				    sizeof (_sip_header_t));
207 				if (sip_msg_header == NULL)
208 					return (EINVAL);
209 				sip_msg_header->sip_hdr_allocated = B_FALSE;
210 				sip_msg_header->sip_hdr_start = msg;
211 				sip_msg_header->sip_hdr_current = msg;
212 				sip_msg_header->sip_hdr_sipmsg = sip_msg;
213 				sip_msg->sip_msg_headers_start = sip_msg_header;
214 				sip_msg->sip_msg_headers_end = sip_msg_header;
215 			}
216 			msg++;
217 		}
218 		/*
219 		 * We have reached the end without hitting the empty line.
220 		 */
221 		if (msg - sip_msg->sip_msg_buf >= sip_msg->sip_msg_len)
222 			return (EINVAL);
223 	}
224 
225 	if (sip_msg->sip_msg_headers_start == NULL)
226 		return (EPROTO);
227 
228 	/*
229 	 * Move start line to be a separate line.
230 	 */
231 	sip_msg->sip_msg_start_line = sip_msg->sip_msg_headers_start;
232 	sip_msg->sip_msg_headers_start =
233 	    sip_msg->sip_msg_headers_start->sip_hdr_next;
234 	sip_msg->sip_msg_start_line->sip_hdr_prev = NULL;
235 	sip_msg->sip_msg_start_line->sip_hdr_next = NULL;
236 
237 	if (sip_msg->sip_msg_headers_start == NULL)
238 		return (EINVAL);
239 	sip_msg->sip_msg_headers_start->sip_hdr_prev = NULL;
240 
241 
242 	/*
243 	 * Deal with content.
244 	 */
245 	sip_msg->sip_msg_content = calloc(1, sizeof (sip_content_t));
246 	sip_msg->sip_msg_content->sip_content_start = msg;
247 	sip_msg->sip_msg_content->sip_content_end = sip_msg->sip_msg_buf +
248 	    sip_msg->sip_msg_len;
249 	sip_msg->sip_msg_content->sip_content_allocated = B_FALSE;
250 	sip_msg->sip_msg_content_len =
251 	    sip_msg->sip_msg_content->sip_content_end -
252 	    sip_msg->sip_msg_content->sip_content_start;
253 	return (0);
254 }
255 
256 /*
257  * The send interface to the sip stack. Used by upper layers.
258  */
259 int
260 sip_sendmsg(sip_conn_object_t obj, sip_msg_t sip_msg, sip_dialog_t dialog,
261     uint32_t flags)
262 {
263 	sip_xaction_t		*sip_trans = NULL;
264 	int			ret = 0;
265 	sip_message_type_t	*sip_msg_info;
266 	_sip_msg_t 		*_sip_msg;
267 	boolean_t		stateful = flags & SIP_SEND_STATEFUL;
268 	boolean_t		dlg_on_fork = flags & SIP_DIALOG_ON_FORK;
269 
270 	sip_refhold_conn(obj);
271 
272 	_sip_msg = (_sip_msg_t *)sip_msg;
273 	if ((ret = sip_adjust_msgbuf(_sip_msg)) != 0) {
274 		sip_refrele_conn(obj);
275 		return (ret);
276 	}
277 
278 	assert(_sip_msg->sip_msg_req_res != NULL);
279 	sip_msg_info = _sip_msg->sip_msg_req_res;
280 	/*
281 	 * Send it statefully if:
282 	 * if stateful is set in 'flags' AND
283 	 * this is not an ACK request, if it is a request (should the upper
284 	 * layer set stateful in the latter case?, i.e is the check
285 	 * necessary here?)
286 	 */
287 	if (stateful && (!sip_msg_info->is_request ||
288 	    sip_msg_info->sip_req_method != ACK)) {
289 		sip_trans = (sip_xaction_t *)sip_xaction_get(obj, sip_msg,
290 		    B_TRUE, sip_msg_info->is_request ? SIP_CLIENT_TRANSACTION :
291 		    SIP_SERVER_TRANSACTION, &ret);
292 		if (sip_trans == NULL) {
293 			sip_refrele_conn(obj);
294 			return (ret);
295 		}
296 		ret = sip_xaction_output(obj, sip_trans, _sip_msg);
297 		SIP_XACTION_REFCNT_DECR(sip_trans);
298 		if (ret != 0) {
299 			sip_refrele_conn(obj);
300 			return (ret);
301 		}
302 	}
303 	/*
304 	 * If the appln wants us to create the dialog, create a partial
305 	 * dialog at this stage, when we get the response, we will
306 	 * complete it.
307 	 */
308 	if (sip_manage_dialog) {
309 		if (sip_msg_info->is_request && dialog == NULL) {
310 			dialog = (sip_dialog_t)sip_seed_dialog(obj, sip_msg,
311 			    dlg_on_fork, SIP_UAC_DIALOG);
312 		} else if (dialog != NULL && (!sip_msg_info->is_request ||
313 		    sip_msg_info->sip_req_method == NOTIFY)) {
314 			(void) sip_update_dialog(dialog, _sip_msg);
315 		} else if (dialog != NULL) {
316 			/*
317 			 * Dialog is in CONFIRMED state. If logging is enabled
318 			 * track the SIP message sent within a dialog.
319 			 */
320 			(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
321 			dialog->sip_dlg_msgcnt++;
322 			sip_add_log(&dialog->sip_dlg_log[dialog->sip_dlg_state],
323 			    (sip_msg_t)sip_msg, dialog->sip_dlg_msgcnt,
324 			    SIP_DIALOG_LOG);
325 			(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
326 
327 			if (sip_msg_info->is_request && sip_msg_info->
328 			    sip_req_method == INVITE) {
329 				(void) sip_dialog_add_new_contact(dialog,
330 				    _sip_msg);
331 			}
332 		}
333 	}
334 	/*
335 	 * if measure sip traffic is enabled, capture the measurements
336 	 * Is this the right place to measure or should I put this after
337 	 * the call to sip_stack_send()
338 	 */
339 	if (sip_msg_info->is_request) {
340 		SIP_UPDATE_COUNTERS(B_TRUE, sip_msg_info->sip_req_method, 0,
341 		    B_TRUE, _sip_msg->sip_msg_len);
342 	} else {
343 		SIP_UPDATE_COUNTERS(B_FALSE, 0, sip_msg_info->sip_resp_code,
344 		    B_TRUE, _sip_msg->sip_msg_len);
345 	}
346 	if ((ret = sip_stack_send(obj, _sip_msg->sip_msg_buf,
347 	    _sip_msg->sip_msg_len)) != 0) {
348 		if (sip_trans != NULL) {
349 			sip_xaction_terminate(sip_trans, _sip_msg,
350 			    sip_conn_transport(obj));
351 		}
352 		sip_refrele_conn(obj);
353 		return (ret);
354 	}
355 	sip_refrele_conn(obj);
356 	return (ret);
357 }
358 
359 /*
360  * Given a sent-by value check if it is in the registered list. If no values
361  * have been registered, the check passes.
362  */
363 static boolean_t
364 sip_sent_by_registered(const sip_str_t *sb_val)
365 {
366 	sent_by_list_t	*sb;
367 	int		count = 0;
368 
369 	(void) pthread_mutex_lock(&sip_sent_by_lock);
370 	if (sip_sent_by == NULL) {
371 		(void) pthread_mutex_unlock(&sip_sent_by_lock);
372 		return (B_TRUE);
373 	}
374 	sb = sip_sent_by;
375 	for (count = 0; count < sip_sent_by_count; count++) {
376 		if (strncasecmp(sb->sb_val, sb_val->sip_str_ptr,
377 		    sb_val->sip_str_len) == 0) {
378 			(void) pthread_mutex_unlock(&sip_sent_by_lock);
379 			return (B_TRUE);
380 		}
381 		sb = sb->sb_next;
382 	}
383 	(void) pthread_mutex_unlock(&sip_sent_by_lock);
384 	return (B_FALSE);
385 }
386 
387 /*
388  * Given a response, check if the sent-by in the VIA header is valid.
389  */
390 boolean_t
391 sip_valid_sent_by(sip_msg_t sip_msg)
392 {
393 	sip_header_t		via;
394 	sip_header_value_t	value = NULL;
395 	int			error;
396 	const sip_str_t		*sent_by = NULL;
397 
398 	via = (sip_header_t)sip_get_header(sip_msg, SIP_VIA,  NULL, &error);
399 	if (via == NULL || error != 0)
400 		return (B_TRUE);
401 	value = (sip_header_value_t)sip_get_header_value(via, &error);
402 	if (value == NULL || error != 0)
403 		return (B_TRUE);
404 	sent_by = sip_get_via_sent_by_host(value, &error);
405 	if (sent_by == NULL || error != 0)
406 		return (B_TRUE);
407 	if (sip_sent_by_registered(sent_by))
408 		return (B_TRUE);
409 	return (B_FALSE);
410 }
411 
412 
413 /*
414  * The receive interface to the transport layer.
415  */
416 void
417 sip_process_new_packet(sip_conn_object_t conn_object, void *msgstr,
418     size_t msglen)
419 {
420 	_sip_msg_t		*sip_msg;
421 	sip_message_type_t	*sip_msg_info;
422 	sip_xaction_t		*sip_trans;
423 	sip_dialog_t		dialog = NULL;
424 	boolean_t		dialog_created = B_FALSE;
425 	int			transport;
426 	char			*msgbuf = NULL;
427 
428 	sip_refhold_conn(conn_object);
429 	transport = sip_conn_transport(conn_object);
430 	if (transport == IPPROTO_TCP) {
431 next_msg:
432 		msgstr = (char *)sip_get_tcp_msg(conn_object, (char *)msgstr,
433 		    &msglen);
434 		if (msgstr == NULL) {
435 			sip_refrele_conn(conn_object);
436 			return;
437 		}
438 	} else {
439 		msgbuf = (char *)malloc(msglen + 1);
440 		if (msgbuf == NULL) {
441 			sip_refrele_conn(conn_object);
442 			return;
443 		}
444 		(void) strncpy(msgbuf, msgstr, msglen);
445 		msgbuf[msglen] = '\0';
446 		msgstr = msgbuf;
447 	}
448 	sip_msg = (_sip_msg_t *)sip_new_msg();
449 	if (sip_msg == NULL) {
450 		if (msgbuf != NULL)
451 			free(msgbuf);
452 		sip_refrele_conn(conn_object);
453 		return;
454 	}
455 	sip_msg->sip_msg_buf = (char *)msgstr;
456 	sip_msg->sip_msg_len = msglen;
457 	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
458 	if (sip_setup_header_pointers(sip_msg) != 0) {
459 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
460 		sip_refrele_conn(conn_object);
461 		sip_free_msg((sip_msg_t)sip_msg);
462 		return;
463 	}
464 	if (sip_parse_first_line(sip_msg->sip_msg_start_line,
465 	    &sip_msg->sip_msg_req_res)) {
466 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
467 		sip_refrele_conn(conn_object);
468 		sip_free_msg((sip_msg_t)sip_msg);
469 		return;
470 	}
471 	sip_msg_info = sip_msg->sip_msg_req_res;
472 	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
473 
474 	if (sip_check_common_headers(conn_object, sip_msg)) {
475 		sip_refrele_conn(conn_object);
476 		sip_free_msg((sip_msg_t)sip_msg);
477 		return;
478 	}
479 
480 	/*
481 	 * Silently discard the response if the top VIA has a sent-by value AND
482 	 * the UA has registered sent-by values AND the one in the VIA is
483 	 * not part of the registerd sent-by values.
484 	 */
485 	if (!sip_msg_info->is_request && !sip_valid_sent_by(sip_msg)) {
486 		sip_refrele_conn(conn_object);
487 		sip_free_msg((sip_msg_t)sip_msg);
488 		return;
489 
490 	}
491 	sip_trans = (sip_xaction_t *)sip_xaction_get(conn_object,
492 	    (sip_msg_t)sip_msg,
493 	    B_FALSE, sip_msg_info->is_request ? SIP_SERVER_TRANSACTION :
494 	    SIP_CLIENT_TRANSACTION, NULL);
495 	if (sip_trans != NULL) {
496 		if (sip_xaction_input(conn_object, sip_trans, &sip_msg) != 0) {
497 			SIP_XACTION_REFCNT_DECR(sip_trans);
498 			sip_refrele_conn(conn_object);
499 			sip_free_msg((sip_msg_t)sip_msg);
500 			return;
501 		}
502 		SIP_XACTION_REFCNT_DECR(sip_trans);
503 
504 		/*
505 		 * msg was retransmission - handled by the transaction
506 		 */
507 		if (sip_msg == NULL)
508 			goto check_next;
509 	} else {
510 		/*
511 		 * If we are getting an INVITE request, let us send a
512 		 * 100 TRYING response here, as in 17.2.1:
513 		 * "The server transaction MUST generate a 100 (Trying)
514 		 * response unless it knows that the TU will generate a
515 		 * provisional or final response within 200 ms".
516 		 */
517 		if (sip_msg_info->is_request &&
518 		    sip_msg_info->sip_req_method == INVITE) {
519 			sip_send_resp(conn_object, sip_msg, SIP_TRYING);
520 		}
521 	}
522 	if (sip_manage_dialog) {
523 		dialog = sip_dialog_find(sip_msg);
524 		if (dialog == NULL) {
525 			if (sip_msg_info->is_request) {
526 				/*
527 				 * sip_seed_dialog will check for the
528 				 * method in the request
529 				 */
530 				dialog = (sip_dialog_t)sip_seed_dialog(
531 				    conn_object, sip_msg,
532 				    B_FALSE, SIP_UAS_DIALOG);
533 				dialog_created = B_TRUE;
534 			}
535 		} else if (sip_incomplete_dialog(dialog)) {
536 			if (!sip_msg_info->is_request ||
537 			    sip_msg_info->sip_req_method == NOTIFY) {
538 				dialog = sip_update_dialog(dialog, sip_msg);
539 			}
540 		} else if (sip_dialog_process(sip_msg, &dialog) != 0) {
541 			if (dialog != NULL)
542 				sip_release_dialog(dialog);
543 			/*
544 			 * cseq number in error, send a
545 			 * SIP_SERVER_INTERNAL_ERROR response.
546 			 */
547 			if (sip_msg_info->is_request) {
548 				sip_send_resp(conn_object, sip_msg,
549 				    SIP_SERVER_INTERNAL_ERROR);
550 			}
551 			sip_refrele_conn(conn_object);
552 			sip_free_msg((sip_msg_t)sip_msg);
553 			return;
554 		}
555 	}
556 	if (sip_msg_info->is_request) {
557 		SIP_UPDATE_COUNTERS(B_TRUE, sip_msg_info->sip_req_method, 0,
558 		    B_FALSE, sip_msg->sip_msg_len);
559 	} else {
560 		SIP_UPDATE_COUNTERS(B_FALSE, 0, sip_msg_info->sip_resp_code,
561 		    B_FALSE, sip_msg->sip_msg_len);
562 	}
563 	sip_ulp_recv(conn_object, (sip_msg_t)sip_msg, dialog);
564 	sip_free_msg((sip_msg_t)sip_msg);
565 	if (dialog != NULL && !dialog_created)
566 		sip_release_dialog(dialog);
567 check_next:
568 	/*
569 	 * Check if there are more complete messages in the TCP fragment list
570 	 * to be consumed
571 	 */
572 	if (transport == IPPROTO_TCP) {
573 		msgstr = NULL;
574 		msglen = 0;
575 		goto next_msg;
576 	}
577 	sip_refrele_conn(conn_object);
578 }
579 
580 /*
581  * Initialize the stack. The connection manager functions, upper layer
582  * receive functions are mandatory.
583  */
584 int
585 sip_stack_init(sip_stack_init_t *stack_val)
586 {
587 #ifdef	__linux__
588 	struct timespec	tspec;
589 #endif
590 
591 	/*
592 	 * If the stack has already been configured, return error
593 	 */
594 	if (sip_stack_send != NULL ||
595 	    stack_val->sip_version != SIP_STACK_VERSION) {
596 		return (EINVAL);
597 	}
598 	if (stack_val->sip_io_pointers == NULL ||
599 	    stack_val->sip_ulp_pointers == NULL) {
600 		return (EINVAL);
601 	}
602 	sip_ulp_recv = stack_val->sip_ulp_pointers->sip_ulp_recv;
603 	sip_manage_dialog = stack_val->sip_stack_flags & SIP_STACK_DIALOGS;
604 
605 	sip_stack_send = stack_val->sip_io_pointers->sip_conn_send;
606 	sip_refhold_conn = stack_val->sip_io_pointers->sip_hold_conn_object;
607 	sip_refrele_conn = stack_val->sip_io_pointers->sip_rel_conn_object;
608 	sip_is_conn_stream = stack_val->sip_io_pointers->sip_conn_is_stream;
609 	sip_is_conn_reliable = stack_val->sip_io_pointers->sip_conn_is_reliable;
610 	sip_conn_rem_addr = stack_val->sip_io_pointers->sip_conn_remote_address;
611 	sip_conn_local_addr =
612 	    stack_val->sip_io_pointers->sip_conn_local_address;
613 	sip_conn_transport = stack_val->sip_io_pointers->sip_conn_transport;
614 	sip_header_function_table_external = stack_val->sip_function_table;
615 
616 	if (sip_ulp_recv == NULL || sip_stack_send == NULL ||
617 	    sip_refhold_conn == NULL || sip_refrele_conn == NULL ||
618 	    sip_is_conn_stream == NULL || sip_is_conn_reliable == NULL ||
619 	    sip_conn_rem_addr == NULL || sip_conn_local_addr == NULL ||
620 	    sip_conn_transport == NULL) {
621 	err_ret:
622 		sip_ulp_recv = NULL;
623 		sip_stack_send = NULL;
624 		sip_refhold_conn = NULL;
625 		sip_refrele_conn = NULL;
626 		sip_is_conn_stream = NULL;
627 		sip_is_conn_reliable = NULL;
628 		sip_conn_rem_addr = NULL;
629 		sip_conn_local_addr = NULL;
630 		sip_conn_transport = NULL;
631 		sip_header_function_table_external = NULL;
632 		sip_stack_timeout = NULL;
633 		sip_stack_untimeout = NULL;
634 		return (EINVAL);
635 	}
636 
637 	sip_conn_timer1 = stack_val->sip_io_pointers->sip_conn_timer1;
638 	sip_conn_timer2 = stack_val->sip_io_pointers->sip_conn_timer2;
639 	sip_conn_timer4 = stack_val->sip_io_pointers->sip_conn_timer4;
640 	sip_conn_timerd = stack_val->sip_io_pointers->sip_conn_timerd;
641 
642 	/*
643 	 * Use Appln timeout routines, if provided
644 	 */
645 	if (stack_val->sip_ulp_pointers->sip_ulp_timeout != NULL) {
646 		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout == NULL)
647 			goto err_ret;
648 		sip_stack_timeout =
649 		    stack_val->sip_ulp_pointers->sip_ulp_timeout;
650 		sip_stack_untimeout =
651 		    stack_val->sip_ulp_pointers->sip_ulp_untimeout;
652 	} else {
653 		if (stack_val->sip_ulp_pointers->sip_ulp_untimeout != NULL)
654 			goto err_ret;
655 		sip_timeout_init();
656 		sip_stack_timeout = sip_timeout;
657 		sip_stack_untimeout = sip_untimeout;
658 	}
659 
660 	/*
661 	 * Manage Dialogs?
662 	 */
663 	if (sip_manage_dialog) {
664 		sip_dialog_init(stack_val->sip_ulp_pointers->sip_ulp_dlg_del,
665 		    stack_val->sip_ulp_pointers->sip_ulp_dlg_state_cb);
666 	}
667 	sip_xaction_init(stack_val->sip_ulp_pointers->sip_ulp_trans_error,
668 	    stack_val->sip_ulp_pointers->sip_ulp_trans_state_cb);
669 
670 	/*
671 	 * Initialize SIP traffic counter mutex
672 	 */
673 	(void) pthread_mutex_init(&sip_counters.sip_counter_mutex, NULL);
674 
675 	/*
676 	 * Initialize SIP logfile structures mutex
677 	 */
678 	(void) pthread_mutex_init(&trans_log.sip_logfile_mutex, NULL);
679 	(void) pthread_mutex_init(&dialog_log.sip_logfile_mutex, NULL);
680 
681 #ifdef	__linux__
682 	if (clock_gettime(CLOCK_REALTIME, &tspec) != 0)
683 		goto err_ret;
684 	sip_hash_salt = tspec.tv_nsec;
685 #else
686 	sip_hash_salt = gethrtime();
687 #endif
688 	(void) pthread_mutex_init(&sip_sent_by_lock, NULL);
689 	return (0);
690 }
691