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