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 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 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 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 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 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 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 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 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