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