/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <strings.h>
#include "sip_parse_uri.h"
#include "sip_msg.h"
#include "sip_miscdefs.h"
#include "sip_xaction.h"
#include "sip_hash.h"
/*
* The transaction hash table
*/
/*
* Get the md5 hash of the required fields
*/
int
{
return (EINVAL);
if (is_2543) {
int cseq;
int error = 0;
/*
* Since the response might contain parameters not in the
* request, just use the to URI.
*/
return (EINVAL);
return (EINVAL);
return (EINVAL);
(char *)&cseq, sizeof (int),
(char *)&method, sizeof (sip_method_t),
} else {
}
return (0);
}
/*
* Add object to the connection cache object. Not checking for duplicates!!
*/
int
{
void **obj_val;
/*
* Is already cached
*/
(void *)sip_trans)) {
return (0);
}
/*
* Transaction has cached a different conn_obj, release it
*/
(void *)sip_trans);
}
if (xaction_list == NULL)
return (ENOMEM);
return (EINVAL);
}
} else {
}
return (0);
}
/*
* Walk thru the list of transactions that have cached this obj and
* and return true if 'cobj' is one of them.
*/
static boolean_t
{
void **obj_val;
return (B_FALSE);
while (xaction_list != NULL) {
continue;
}
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Walk thru the list of transactions that have cached this obj and
* refrele the objs.
*/
void
{
void **obj_val;
}
return;
}
while (xaction_list != NULL) {
continue;
}
/*
* Take the obj out of the list
*/
if (xaction_list == NULL) {
} else {
}
} else if (xaction_list == NULL) {
} else {
}
}
}
/*
* Check for a transaction match. Passed to sip_hash_find().
*/
{
return (B_FALSE);
sizeof (tmp->sip_xaction_hash_digest)) == 0) {
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Find a transaction
*/
static sip_xaction_t *
{
int hindex;
int error;
if (error != 0)
return (NULL);
/*
* corresponding INVITE, if any.
*/
}
return (NULL);
return (tmp);
}
/*
* create a transaction.
*/
static sip_xaction_t *
int *error)
{
int state = 0;
int prev_state = 0;
int ret;
*error = 0;
/*
* Make sure we are not creating a transaction for
* an ACK request.
*/
return (NULL);
}
return (NULL);
}
} else {
+ 1);
return (NULL);
}
}
if (sip_msg_info->is_request) {
} else {
if (ret != 0) {
return (NULL);
}
else
}
/*
* Get connection object specific timeouts, if present
*/
if (sip_conn_timer1 != NULL)
if (sip_conn_timer4 != NULL)
if (sip_conn_timerd != NULL)
return (NULL);
}
if (sip_xaction_ulp_state_cb != NULL &&
}
return (trans);
}
/*
* Find a transaction, create if asked for
*/
{
char *branchid;
*error = 0;
/*
* If we are sending a request, must be conformant to RFC 3261.
*/
if (sip_msg_info->is_request &&
return (NULL);
}
}
return (sip_trans);
}
/*
* Delete a transaction if the reference count is 0. Passed to
* sip_hash_delete().
*/
{
int count = 0;
*found = 0;
sizeof (tmp->sip_xaction_hash_digest)) == 0) {
*found = 1;
if (tmp->sip_xaction_ref_cnt != 0) {
return (B_FALSE);
}
}
}
(void *)tmp);
}
/*
* If the transaction logging is disabled before we could
* write the captured messages into the transaction log, then
* we need to free those captured messsages
*/
}
}
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Delete a SIP transaction
*/
void
{
int hindex;
if (trans->sip_xaction_ref_cnt != 0) {
return;
}
}
/*
* Add a SIP transaction into the hash list.
*/
int
{
return (EINVAL);
/*
* trans is not in the list as yet, so no need to hold the lock
*/
SIP_DIGEST_TO_HASH(hash_index)) != 0) {
return (ENOMEM);
}
return (0);
}
/*
* Given a state, return the string - This is mostly for debug purposes
*/
char *
{
switch (state) {
case SIP_NEW_TRANSACTION:
return ("SIP_NEW_TRANSACTION");
case SIP_CLNT_CALLING:
return ("SIP_CLNT_CALLING");
case SIP_CLNT_INV_PROCEEDING:
return ("SIP_CLNT_INV_PROCEEDING");
case SIP_CLNT_INV_TERMINATED:
return ("SIP_CLNT_INV_TERMINATED");
case SIP_CLNT_INV_COMPLETED:
return ("SIP_CLNT_INV_COMPLETED");
case SIP_CLNT_TRYING:
return ("SIP_CLNT_TRYING");
return ("SIP_CLNT_NONINV_PROCEEDING");
return ("SIP_CLNT_NONINV_TERMINATED");
return ("SIP_CLNT_NONINV_COMPLETED");
case SIP_SRV_INV_PROCEEDING:
return ("SIP_SRV_INV_PROCEEDING");
case SIP_SRV_INV_COMPLETED:
return ("SIP_SRV_INV_COMPLETED");
case SIP_SRV_CONFIRMED:
return ("SIP_SRV_CONFIRMED");
case SIP_SRV_INV_TERMINATED:
return ("SIP_SRV_INV_TERMINATED");
case SIP_SRV_TRYING:
return ("SIP_SRV_TRYING");
return ("SIP_SRV_NONINV_PROCEEDING");
case SIP_SRV_NONINV_COMPLETED:
return ("SIP_SRV_NONINV_COMPLETED");
return ("SIP_SRV_NONINV_TERMINATED");
default :
return ("UNKNOWN");
}
}
/*
* Initialize the hash table etc.
*/
void
{
int cnt;
(void) pthread_mutex_init(
}
if (ulp_trans_err != NULL)
if (ulp_state_cb != NULL)
}