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