original files of m241
This commit is contained in:
@@ -0,0 +1,779 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipsctp_mib.c,v $ $Revision: 1.11 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipsctp/src/ipsctp_mib.c,v $
|
||||
* $Author: kenneth $ $Date: 2010-09-22 18:57:04 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Jiangang Yang <jiangang.yang@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipsctp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_mib2_api.h>
|
||||
|
||||
#include "ipnet_usr_sock.h"
|
||||
#include "ipsctp.h"
|
||||
#include "ipsctp_h.h"
|
||||
|
||||
#ifdef IPSCTP_MIB
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_stats_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP global statistics
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipsctp_mib_stats_lookup(Ipsctp_mib_stats **stats)
|
||||
{
|
||||
void *suspend_handle;
|
||||
|
||||
if (stats == IP_NULL)
|
||||
return -1;
|
||||
|
||||
*stats = ipcom_malloc(sizeof(Ipsctp_mib_stats));
|
||||
if (*stats == IP_NULL)
|
||||
return -1;
|
||||
|
||||
suspend_handle = ipnet_suspend_stack();
|
||||
if (suspend_handle == IP_NULL)
|
||||
{
|
||||
ipcom_free(*stats);
|
||||
*stats = IP_NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
**stats = ipsctp->mib_stats;
|
||||
|
||||
ipnet_resume_stack(suspend_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_stats_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP global statistics
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC void
|
||||
ipsctp_mib_stats_get(Ipsctp_mib_stats **stats)
|
||||
{
|
||||
|
||||
if (stats == IP_NULL)
|
||||
return;
|
||||
|
||||
*stats = &ipsctp->mib_stats;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_params_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP global parameters
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipsctp_mib_params_lookup(Ipsctp_params **params)
|
||||
{
|
||||
void *suspend_handle;
|
||||
|
||||
if (params == IP_NULL)
|
||||
return -1;
|
||||
*params = ipcom_malloc(sizeof(Ipsctp_params));
|
||||
if (*params == IP_NULL)
|
||||
return -1;
|
||||
|
||||
suspend_handle = ipnet_suspend_stack();
|
||||
if (suspend_handle == IP_NULL)
|
||||
{
|
||||
ipcom_free(*params);
|
||||
*params = IP_NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*params)->sctpRtoInitial = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Initial", IPSCTP_RTO_INITIAL_DEFAULT);
|
||||
(*params)->sctpRtoMax = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Max", IPSCTP_RTO_MAX_DEFAULT);
|
||||
(*params)->sctpRtoMin = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Min", IPSCTP_RTO_MIN_DEFAULT);
|
||||
(*params)->sctpRtoAlgorithm = (Ip_s32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Algorithm", IPSCTP_RTO_ALGORITHM_DEFAULT);
|
||||
(*params)->sctpMaxAssocs = (Ip_s32)ipcom_sysvar_get_as_int0("ipsctp.Max.Associations", IPSCTP_MAX_ASSOCIATIONS_DEFAULT);
|
||||
(*params)->sctpValCookieLife = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Valid.Cookie.Life", IPSCTP_VALID_COOKIE_LIFE_DEFAULT);
|
||||
(*params)->sctpMaxInitRetr = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Max.Init.Retransmits", IPSCTP_MAX_INIT_RETRANSMITS_DEFAULT);
|
||||
|
||||
ipnet_resume_stack(suspend_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_assoc_entry_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP Association entry.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipsctp_assoc_entry *
|
||||
ipsctp_mib_assoc_entry_lookup(Ip_u32 vtag,
|
||||
int /*boolean_t*/ getnext)
|
||||
{
|
||||
Ipsctp_tcb *tcb;
|
||||
Ipsctp_assoc_entry *assoc_entry;
|
||||
void *suspend_handle;
|
||||
|
||||
assoc_entry = ipcom_calloc(1, sizeof(Ipsctp_assoc_entry));
|
||||
if (assoc_entry == IP_NULL)
|
||||
return IP_NULL;
|
||||
|
||||
ipcom_memset(assoc_entry, 0, sizeof(*assoc_entry));
|
||||
|
||||
suspend_handle = ipnet_suspend_stack();
|
||||
if (suspend_handle == IP_NULL)
|
||||
{
|
||||
ipcom_free(assoc_entry);
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
/* find matching TCB from SCTP HashTable */
|
||||
|
||||
if (vtag != 0)
|
||||
{
|
||||
/* get next tcb from hashtable */
|
||||
unsigned hash_index;
|
||||
void *obj = IP_NULL;
|
||||
Ipsctp_tcb_lookup_key key;
|
||||
Ipsctp_hash *head = ipsctp->tcb_hashtable;
|
||||
|
||||
ipcom_memset(&key, 0, sizeof(key));
|
||||
key.vtag = vtag;
|
||||
key.strict_match = 0;
|
||||
|
||||
/* find the current one */
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
|
||||
#else
|
||||
hash_index = head->key_hash_func(&key) % head->size;
|
||||
#endif
|
||||
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
|
||||
{
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
|
||||
#else
|
||||
if (head->obj_key_cmp(obj, &key))
|
||||
#endif
|
||||
break;
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
|
||||
if (getnext)
|
||||
{
|
||||
/* find the next one */
|
||||
hash_index = hash_index + 1;
|
||||
obj = IP_NULL;
|
||||
while ((hash_index < head->size) && ((obj = head->table[hash_index]) == IP_NULL))
|
||||
{
|
||||
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
}
|
||||
tcb = obj;
|
||||
}
|
||||
else if(getnext)
|
||||
{
|
||||
/* get first tcb from hashtable */
|
||||
unsigned hash_index = 0;
|
||||
void *obj = IP_NULL;
|
||||
Ipsctp_hash *head = ipsctp->tcb_hashtable;
|
||||
|
||||
while ((hash_index < head->size) && ((obj = head->table[hash_index]) == IP_NULL))
|
||||
{
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
|
||||
tcb = obj;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb = IP_NULL;
|
||||
}
|
||||
|
||||
if (tcb == IP_NULL)
|
||||
{
|
||||
ipcom_free(assoc_entry);
|
||||
assoc_entry = IP_NULL;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
assoc_entry->sctpAssocId = tcb->my_vtag;
|
||||
assoc_entry->sctpAssocRemHostName[0] = '\0';
|
||||
assoc_entry->sctpAssocHeartBeatInterval = tcb->hb_interval;
|
||||
assoc_entry->sctpAssocLocalPort = tcb->instance->lport;
|
||||
assoc_entry->sctpAssocRemPort = tcb->rport;
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (tcb->primary_transport->paddr.sa.sa_family == IP_AF_INET)
|
||||
{
|
||||
assoc_entry->sctpAssocRemPrimAddrType = 1 ;
|
||||
*(Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr = tcb->primary_transport->paddr.sin.sin_addr.s_addr;
|
||||
}
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (tcb->primary_transport->paddr.sa.sa_family == IP_AF_INET6)
|
||||
{
|
||||
assoc_entry->sctpAssocRemPrimAddrType = 2 ;
|
||||
|
||||
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[0] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[0];
|
||||
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[1] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[1];
|
||||
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[2] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[2];
|
||||
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[3] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[3];
|
||||
|
||||
}
|
||||
#endif
|
||||
assoc_entry->sctpAssocHeartBeatInterval = tcb->hb_interval;
|
||||
assoc_entry->sctpAssocState = tcb->state;
|
||||
assoc_entry->sctpAssocInStreams = tcb->streamincnt;
|
||||
assoc_entry->sctpAssocOutStreams = tcb->streamoutcnt;
|
||||
assoc_entry->sctpAssocMaxRetr = tcb->max_send_times;
|
||||
assoc_entry->sctpAssocPrimProcess = 0;
|
||||
assoc_entry->sctpAssocT1expireds = tcb->cnt_timo_init + tcb->cnt_timo_cookie;
|
||||
assoc_entry->sctpAssocT2expireds = tcb->cnt_timo_shutdown + tcb->cnt_timo_shutdownack;
|
||||
assoc_entry->sctpAssocRtxChunks = tcb->marked_retrans;
|
||||
assoc_entry->sctpAssocStartTime = tcb->start_time;
|
||||
assoc_entry->sctpAssocDiscontinuityTime = tcb->discontinuity_time;
|
||||
|
||||
exit_func:
|
||||
ipnet_resume_stack(suspend_handle);
|
||||
|
||||
return assoc_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_set_assoc_state
|
||||
*===========================================================================
|
||||
* Description: set SCTP Association entry state.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC void
|
||||
ipsctp_mib_set_assoc_state(Ipsctp_assoc_entry *assoc_entry,
|
||||
Ip_s32 state)
|
||||
{
|
||||
Ipnet_sig *sig;
|
||||
Ipcom_pipe *pipe;
|
||||
|
||||
if (assoc_entry == IP_NULL
|
||||
|| (state >= IPSCTP_STATE_CLOSED && state < IPSCTP_STATE_MAX))
|
||||
return;
|
||||
|
||||
sig = ipcom_slab_alloc(ipnet->slabs.poll);
|
||||
if (sig == IP_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipnet_usr_sock_init_sig(sig, IPNET_SIG_SCTP_SET_STATE);
|
||||
sig->d.sctp_set_state.vtag = assoc_entry->sctpAssocId;
|
||||
sig->d.sctp_set_state.state = state;
|
||||
|
||||
pipe = ipnet_usr_sock_get_pipe();
|
||||
ipcom_pipe_send(pipe, sig);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_assoc_local_addr_entry_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP Association entry.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipsctp_assoc_local_addr_entry *
|
||||
ipsctp_mib_assoc_local_addr_entry_lookup(Ip_u32 vtag,
|
||||
Ip_s32 addrType,
|
||||
Ip_u8 *addr,
|
||||
int get_next)
|
||||
{
|
||||
Ipsctp_tcb *tcb = IP_NULL;
|
||||
Ipsctp_assoc_local_addr_entry *assoc_addr = IP_NULL;
|
||||
void *suspend_handle;
|
||||
unsigned hash_index = 0;
|
||||
Ipsctp_hash *head = ipsctp->tcb_hashtable;
|
||||
|
||||
suspend_handle = ipnet_suspend_stack();
|
||||
if (suspend_handle == IP_NULL)
|
||||
return IP_NULL;
|
||||
|
||||
if (vtag != 0)
|
||||
{
|
||||
void *obj = IP_NULL;
|
||||
Ipsctp_tcb_lookup_key key;
|
||||
|
||||
ipcom_memset(&key, 0, sizeof(key));
|
||||
key.vtag = vtag;
|
||||
key.strict_match = 0;
|
||||
|
||||
/* find the current one */
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
|
||||
#else
|
||||
hash_index = head->key_hash_func(&key) % head->size;
|
||||
#endif
|
||||
|
||||
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
|
||||
{
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
|
||||
#else
|
||||
if (head->obj_key_cmp(obj, &key))
|
||||
#endif
|
||||
{
|
||||
tcb = obj;
|
||||
break;
|
||||
}
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (get_next)
|
||||
{
|
||||
/* get first tcb from hashtable */
|
||||
goto next_tcb_first_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb = IP_NULL;
|
||||
}
|
||||
|
||||
if (tcb == IP_NULL)
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
find_address_entry:
|
||||
|
||||
/* get local address entry */
|
||||
{
|
||||
Ipsctp_addr *local_addr;
|
||||
Ipsctp_laddr_entry *laddr_entry;
|
||||
|
||||
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_first(&tcb->instance->laddr_list);
|
||||
while (laddr_entry)
|
||||
{
|
||||
local_addr = &laddr_entry->laddr;
|
||||
if (addr == IP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (addrType == 1 && local_addr->sa.sa_family == IP_AF_INET
|
||||
&& (*(Ip_u32 *)addr) == local_addr->sin.sin_addr.s_addr
|
||||
)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (addrType == 2 && local_addr->sa.sa_family == IP_AF_INET6
|
||||
&& IP_IN6_ARE_ADDR_EQUAL(addr, &local_addr->sin6.sin6_addr))
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_next(&laddr_entry->next);
|
||||
}
|
||||
|
||||
/*found_addr_entry:*/
|
||||
|
||||
if (laddr_entry)
|
||||
{
|
||||
if (get_next)
|
||||
{
|
||||
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_next(&laddr_entry->next);
|
||||
if (laddr_entry != IP_NULL)
|
||||
{
|
||||
local_addr = &laddr_entry->laddr;
|
||||
get_next = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
if (laddr_entry && local_addr)
|
||||
{
|
||||
assoc_addr = ipcom_calloc(1, sizeof(*assoc_addr));
|
||||
|
||||
if (assoc_addr == IP_NULL)
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (local_addr->sa.sa_family == IP_AF_INET)
|
||||
{
|
||||
assoc_addr->sctpAssocLocalAddrType = 1;
|
||||
*(Ip_u32 *)assoc_addr->sctpAssocLocalAddr = local_addr->sin.sin_addr.s_addr;
|
||||
}
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (local_addr->sa.sa_family == IP_AF_INET6)
|
||||
{
|
||||
assoc_addr->sctpAssocLocalAddrType = 2;
|
||||
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[0] = local_addr->sin6.sin6_addr.in6.addr32[0];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[1] = local_addr->sin6.sin6_addr.in6.addr32[1];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[2] = local_addr->sin6.sin6_addr.in6.addr32[2];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[3] = local_addr->sin6.sin6_addr.in6.addr32[3];
|
||||
}
|
||||
#endif
|
||||
assoc_addr->sctpAssocLocalAddrStartTime = laddr_entry->start_time;
|
||||
assoc_addr->sctpAssocId = tcb->my_vtag;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!get_next)
|
||||
goto exit_func;
|
||||
|
||||
/* get next tcb from hashtable */
|
||||
hash_index = hash_index + 1;
|
||||
|
||||
next_tcb_first_addr:
|
||||
tcb = IP_NULL;
|
||||
while ((hash_index < head->size) && ((tcb = head->table[hash_index]) == IP_NULL))
|
||||
{
|
||||
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
/* find the first address entry of this TCB */
|
||||
if (tcb)
|
||||
{
|
||||
addr = IP_NULL;
|
||||
get_next = 0;
|
||||
addrType = 0;
|
||||
goto find_address_entry;
|
||||
}
|
||||
|
||||
exit_func:
|
||||
|
||||
ipnet_resume_stack(suspend_handle);
|
||||
|
||||
return assoc_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipsctp_mib_assoc_rem_addr_entry_lookup
|
||||
*===========================================================================
|
||||
* Description: get SCTP Association entry.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipsctp_assoc_rem_addr_entry *
|
||||
ipsctp_mib_assoc_rem_addr_entry_lookup(Ip_u32 vtag,
|
||||
Ip_s32 addrType,
|
||||
Ip_u8 *addr,
|
||||
int get_next)
|
||||
{
|
||||
Ipsctp_tcb *tcb = IP_NULL;
|
||||
Ipsctp_assoc_rem_addr_entry *assoc_addr = IP_NULL;
|
||||
void *suspend_handle;
|
||||
unsigned hash_index = 0;
|
||||
Ipsctp_hash *head = ipsctp->tcb_hashtable;
|
||||
|
||||
suspend_handle = ipnet_suspend_stack();
|
||||
if (suspend_handle == IP_NULL)
|
||||
return IP_NULL;
|
||||
|
||||
if (vtag != 0)
|
||||
{
|
||||
void *obj = IP_NULL;
|
||||
Ipsctp_tcb_lookup_key key;
|
||||
|
||||
ipcom_memset(&key, 0, sizeof(key));
|
||||
key.vtag = vtag;
|
||||
key.strict_match = 0;
|
||||
|
||||
/* find the current one */
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
|
||||
#else
|
||||
hash_index = head->key_hash_func(&key) % head->size;
|
||||
#endif
|
||||
|
||||
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
|
||||
{
|
||||
#ifdef IPCOM_FORWARDER_NAE
|
||||
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
|
||||
#else
|
||||
if (head->obj_key_cmp(obj, &key))
|
||||
#endif
|
||||
{
|
||||
tcb = obj;
|
||||
break;
|
||||
}
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (get_next)
|
||||
{
|
||||
/* get first tcb from hashtable */
|
||||
goto next_tcb_first_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb = IP_NULL;
|
||||
}
|
||||
|
||||
if (tcb == IP_NULL)
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
find_address_entry:
|
||||
|
||||
/* get remote address entry */
|
||||
{
|
||||
Ipsctp_addr *rem_addr;
|
||||
Ipsctp_transport *transport_entry;
|
||||
|
||||
transport_entry = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list);
|
||||
|
||||
while (transport_entry)
|
||||
{
|
||||
rem_addr = &transport_entry->paddr;
|
||||
if (addr == IP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (addrType == 1 && rem_addr->sa.sa_family == IP_AF_INET
|
||||
&& (*(Ip_u32 *)addr) == rem_addr->sin.sin_addr.s_addr
|
||||
)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (addrType == 2 && rem_addr->sa.sa_family == IP_AF_INET6
|
||||
&& IP_IN6_ARE_ADDR_EQUAL(addr, &rem_addr->sin6.sin6_addr))
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
transport_entry = (Ipsctp_transport *)ipcom_list_next(&transport_entry->trans_next);
|
||||
}
|
||||
|
||||
/*found_addr_entry:*/
|
||||
if (transport_entry)
|
||||
{
|
||||
if (get_next)
|
||||
{
|
||||
transport_entry = (Ipsctp_transport *)ipcom_list_next(&transport_entry->trans_next);
|
||||
if (transport_entry != IP_NULL)
|
||||
{
|
||||
rem_addr = &transport_entry->paddr;
|
||||
get_next = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
|
||||
if (transport_entry && rem_addr)
|
||||
{
|
||||
assoc_addr = ipcom_calloc(1, sizeof(*assoc_addr));
|
||||
|
||||
if (assoc_addr == IP_NULL)
|
||||
{
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (rem_addr->sa.sa_family == IP_AF_INET)
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrType = 1;
|
||||
*(Ip_u32 *)assoc_addr->sctpAssocRemAddr = rem_addr->sin.sin_addr.s_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (rem_addr->sa.sa_family == IP_AF_INET6)
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrType = 2;
|
||||
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[0] = rem_addr->sin6.sin6_addr.in6.addr32[0];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[1] = rem_addr->sin6.sin6_addr.in6.addr32[1];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[2] = rem_addr->sin6.sin6_addr.in6.addr32[2];
|
||||
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[3] = rem_addr->sin6.sin6_addr.in6.addr32[3];
|
||||
}
|
||||
#endif
|
||||
if (IP_BIT_ISSET(transport_entry->state, IPSCTP_ADDR_REACHABLE))
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrActive = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrActive = 2;
|
||||
}
|
||||
|
||||
if (IP_BIT_ISSET(transport_entry->state, IPSCTP_ADDR_NOHB))
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrHBActive = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
assoc_addr->sctpAssocRemAddrHBActive = 1;
|
||||
}
|
||||
|
||||
assoc_addr->sctpAssocRemAddrRTO = transport_entry->rto;
|
||||
assoc_addr->sctpAssocRemAddrMaxPathRtx = transport_entry->err_thresh;
|
||||
assoc_addr->sctpAssocRemAddrRtx = transport_entry->marked_retrans;
|
||||
assoc_addr->sctpAssocRemAddrStartTime = transport_entry->start_time;
|
||||
assoc_addr->sctpAssocId = tcb->my_vtag;
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!get_next)
|
||||
goto exit_func;
|
||||
|
||||
/* get next tcb from hashtable */
|
||||
hash_index = hash_index + 1;
|
||||
|
||||
next_tcb_first_addr:
|
||||
tcb = IP_NULL;
|
||||
while ((hash_index < head->size) && ((tcb = head->table[hash_index]) == IP_NULL))
|
||||
{
|
||||
|
||||
hash_index = hash_index + 1;
|
||||
}
|
||||
/* find the first address entry of this TCB */
|
||||
if (tcb)
|
||||
{
|
||||
addr = IP_NULL;
|
||||
get_next = 0;
|
||||
addrType = 0;
|
||||
goto find_address_entry;
|
||||
}
|
||||
|
||||
exit_func:
|
||||
|
||||
ipnet_resume_stack(suspend_handle);
|
||||
|
||||
return assoc_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user