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
sip_send_resp(sip_conn_object_t conn_obj,_sip_msg_t * sip_msg,int resp)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
sip_check_common_headers(sip_conn_object_t conn_obj,_sip_msg_t * sip_msg)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
sip_setup_header_pointers(_sip_msg_t * sip_msg)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
sip_sendmsg(sip_conn_object_t obj,sip_msg_t sip_msg,sip_dialog_t dialog,uint32_t flags)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
sip_sent_by_registered(const sip_str_t * sb_val)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
sip_valid_sent_by(sip_msg_t sip_msg)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
sip_process_new_packet(sip_conn_object_t conn_object,void * msgstr,size_t msglen)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
sip_stack_init(sip_stack_init_t * stack_val)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