417 lines
13 KiB
C
417 lines
13 KiB
C
/* ipdiameter_peer.h - IPNet Diameter peer head file */
|
|
|
|
/*
|
|
* Copyright (c) 2007 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute or otherwise make use of this software
|
|
* may be licensed only pursuant to the terms of an applicable Wind River
|
|
* license agreement. No license to Wind River intellectual property rights
|
|
* is granted herein. All rights not licensed by Wind River are reserved
|
|
* by Wind River.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01j,04feb09,tlu Remove peer R_RCV_CEA and I_RCV_CER events
|
|
01i,17apr08,tlu Add compile condition to call ipcom mutex utilities directly
|
|
for VxWorks, and call recursive semaphore for Linux
|
|
01h,07dec07,tlu Rename ipdiameter_peer_add_session_pkt() to
|
|
ipdiameter_peer_add_tx_pending_pkt() for agent handling
|
|
01g,21nov07,tlu Add realm based peer route selection
|
|
01f,09oct07,tlu Port to Linux
|
|
01e,24sep07,tlu Add function to reset a peer state to CLOSED
|
|
01d,14aug07,tlu Add peer failure handling
|
|
01c,08aug07,tlu Add TLS support
|
|
01b,27jun07,tlu Add application IDs to peer entry structure
|
|
01a,03may07,tlu Created.
|
|
*/
|
|
|
|
#ifndef IPDIAMETER_PEER_H
|
|
#define IPDIAMETER_PEER_H
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include <ipcom_tags.h>
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock6.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_tmo2.h>
|
|
|
|
#ifdef IPSSL
|
|
#include <openssl/ssl.h>
|
|
#endif /* IPSSL */
|
|
|
|
#include <ipdiameter_config.h>
|
|
#include <ipdiameter_constant.h>
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPDIAMETER_ENABLE_REENTRANT
|
|
|
|
#define IPDIAMETER_MAX_PEER_PENDING_PKTS 100
|
|
|
|
#define IPDIAMETER_DYNAMIC_PEER_EXPIRATION 30
|
|
|
|
#define IPDIAMETER_PEER_MAX_FAILS 5
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Peer state machine events
|
|
*===========================================================================
|
|
* refer to RFC 3588, section 5.6 and 5.6.2
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
DIAMETER_PEER_EV_START = 1,
|
|
DIAMETER_PEER_EV_R_CONN_CER,
|
|
DIAMETER_PEER_EV_I_RCV_CONN_ACK,
|
|
DIAMETER_PEER_EV_I_RCV_CONN_NACK,
|
|
DIAMETER_PEER_EV_TIMEOUT,
|
|
DIAMETER_PEER_EV_R_RCV_CER,
|
|
DIAMETER_PEER_EV_I_RCV_CEA,
|
|
DIAMETER_PEER_EV_I_RCV_NON_CEA,
|
|
DIAMETER_PEER_EV_I_PEER_DISC,
|
|
DIAMETER_PEER_EV_R_PEER_DISC,
|
|
DIAMETER_PEER_EV_R_RCV_DPR,
|
|
DIAMETER_PEER_EV_I_RCV_DPR,
|
|
DIAMETER_PEER_EV_R_RCV_DPA,
|
|
DIAMETER_PEER_EV_I_RCV_DPA,
|
|
DIAMETER_PEER_EV_WIN_ELECTION,
|
|
DIAMETER_PEER_EV_SEND_MESSAGE,
|
|
DIAMETER_PEER_EV_R_RCV_MESSAGE,
|
|
DIAMETER_PEER_EV_I_RCV_MESSAGE,
|
|
DIAMETER_PEER_EV_STOP,
|
|
DIAMETER_PEER_EV_R_RCV_DWR,
|
|
DIAMETER_PEER_EV_I_RCV_DWR,
|
|
DIAMETER_PEER_EV_R_RCV_DWA,
|
|
DIAMETER_PEER_EV_I_RCV_DWA
|
|
} Ipdiameter_peer_events;
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Peer states
|
|
*===========================================================================
|
|
* refer to RFC 3588, section 5.6
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
DIAMETER_PEER_STATE_FAILED = 0,
|
|
DIAMETER_PEER_STATE_CLOSED,
|
|
DIAMETER_PEER_STATE_WAIT_CONN_ACK,
|
|
DIAMETER_PEER_STATE_WAIT_I_CEA,
|
|
DIAMETER_PEER_STATE_WAIT_CONN_ACK_ELECT,
|
|
DIAMETER_PEER_STATE_WAIT_RETURNS,
|
|
DIAMETER_PEER_STATE_R_OPEN,
|
|
DIAMETER_PEER_STATE_I_OPEN,
|
|
DIAMETER_PEER_STATE_CLOSING
|
|
} Ipdiameter_peer_state;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Peer types
|
|
*===========================================================================
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
DIAMETER_PEER_UNKNOWN = 0,
|
|
DIAMETER_PEER_ACCESS_SERVER,
|
|
DIAMETER_PEER_ACCOUNTING_SERVER,
|
|
DIAMETER_PEER_FULL_SERVER,
|
|
DIAMETER_PEER_CLIENT,
|
|
DIAMETER_PEER_RELAY_AGENT,
|
|
DIAMETER_PEER_REDIRECT_AGENT,
|
|
DIAMETER_PEER_PROXY_AGENT,
|
|
DIAMETER_PEER_TRANSLATION_AGENT
|
|
} Ipdiameter_peer_type;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Peer disconnect causes
|
|
*===========================================================================
|
|
* refer to RFC 3588, section 5.4.3
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
DIAMETER_PEER_REBOOTING = 0,
|
|
DIAMETER_PEER_BUSY,
|
|
DIAMETER_PEER_DO_NOT_WANT_TO_TALK_TO_YOU
|
|
} Ipdiameter_peer_disconnect_cause;
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipdiameter_peer
|
|
*===========================================================================
|
|
* This is user interface structure to add/delete the peers
|
|
*/
|
|
|
|
typedef struct Ipdiameter_peer_struct
|
|
{
|
|
union Ip_sockaddr_union peer_addr; /* Peer IPv4/v6 socket address union. */
|
|
|
|
/* Peer node information */
|
|
Ipdiameter_peer_type node_type;
|
|
char realm[IPDIAMETER_MAX_FQDN_SIZE];
|
|
|
|
/* This parameter is optional */
|
|
char hostname[IPDIAMETER_MAX_FQDN_SIZE];
|
|
|
|
/* static or dynamic, IP_TRUE if a dynamic entry */
|
|
Ip_bool dynamic;
|
|
|
|
/* tls enabled */
|
|
Ip_bool tls;
|
|
|
|
/* the socket used to send/receive data with the peer */
|
|
#ifdef IPCOM_USE_INET
|
|
/* Diameter peer IPv4 TCP socket descriptor.
|
|
* Set to IP_INVALID_SOCKET if shall not talk to IPv4 peer. */
|
|
Ip_fd fd;
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
/* Diameter peer IPv6 TCP socket descriptor.
|
|
* Set to IP_INVALID_SOCKET if shall not talk to IPv6 peer. */
|
|
Ip_fd fd6;
|
|
#endif
|
|
|
|
/* peer state */
|
|
Ipdiameter_peer_state state;
|
|
|
|
/* security parameters */
|
|
|
|
Ip_tag conf[1]; /* None available, included for future compability. */
|
|
}
|
|
Ipdiameter_peer;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipdiameter_peer_entry
|
|
*===========================================================================
|
|
* refer to RFC 3588, section 5
|
|
*/
|
|
|
|
struct Ipdiameter_header;
|
|
|
|
typedef struct Ipdiameter_peer_entry_struct
|
|
{
|
|
Ipcom_list peer_list;
|
|
|
|
/* seconds since this peer was added */
|
|
Ip_time_t start_time;
|
|
|
|
/* timeout handler for reconnection attempt */
|
|
Ipcom_tmo2 reconn_tmo;
|
|
Ip_u16 num_reconn;
|
|
|
|
/* timeout handler for watchdog timeout */
|
|
Ipcom_tmo2 watchdog_tmo;
|
|
Ip_bool wd_responded;
|
|
Ip_u16 num_fail;
|
|
|
|
/* timeout handler for dynamic peer expiration */
|
|
Ipcom_tmo2 expire_tmo;
|
|
|
|
union Ip_sockaddr_union peer_addr; /* Peer IPv4/v6 socket address union. */
|
|
|
|
/* the socket used to send/receive data with the peer */
|
|
#ifdef IPCOM_USE_INET
|
|
/* Diameter peer IPv4 TCP socket descriptor.
|
|
* Set to IP_INVALID_SOCKET if shall not talk to IPv4 peer. */
|
|
Ip_fd fd;
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
/* Diameter peer IPv6 TCP socket descriptor.
|
|
* Set to IP_INVALID_SOCKET if shall not talk to IPv6 peer. */
|
|
Ip_fd fd6;
|
|
#endif
|
|
|
|
Ipdiameter_peer_type node_type;
|
|
char realm[IPDIAMETER_MAX_FQDN_SIZE];
|
|
char hostname[IPDIAMETER_MAX_FQDN_SIZE];
|
|
|
|
/* peer state */
|
|
Ipdiameter_peer_state state;
|
|
|
|
/* failure counter */
|
|
Ip_u16 fail_counter;
|
|
|
|
/* static or dynamic, IP_TRUE if a dynamic entry */
|
|
Ip_bool dynamic;
|
|
|
|
/* expiration time, valid only for a dynamic entry */
|
|
Ip_time_t expiration_time;
|
|
|
|
/* connection initiator or responder */
|
|
Ip_bool initiator;
|
|
|
|
/* tls enabled */
|
|
Ip_bool tls;
|
|
SSL *ssl;
|
|
|
|
/* peer capabilities */
|
|
Ip_u32 appl_ids[IPDIAMETER_MAX_APPL_IDS];
|
|
Ip_u32 num_appls;
|
|
|
|
/* the process that currently holds the semaphore and taken counter */
|
|
Ip_pid_t pid;
|
|
Ip_u8 s_counter;
|
|
|
|
/* security parameters */
|
|
|
|
|
|
#ifdef IPDIAMETER_ENABLE_REENTRANT
|
|
Ipcom_mutex code_mutex; /* Mutex to protect IPDIAMETER peer data. */
|
|
#endif
|
|
|
|
/* requests associated with this peer: of type CER, DPR, and DWR */
|
|
Ip_u32 request_num; /* number of requests. */
|
|
Ipcom_list request_head;
|
|
|
|
/* pending session packages to be transmitted */
|
|
Ip_u32 package_num;
|
|
struct Ipdiameter_header *packages[IPDIAMETER_MAX_PEER_PENDING_PKTS];
|
|
}
|
|
Ipdiameter_peer_entry;
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
struct Ipdiameter_request_entry;
|
|
|
|
IP_PUBLIC Ip_err ipdiameter_peer_fsm(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *hdr, int event);
|
|
|
|
IP_PUBLIC Ipdiameter_peer_entry *ipdiameter_create_peer(Ipdiameter_peer *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_delete_peer(union Ip_sockaddr_union *peer_addr);
|
|
IP_PUBLIC Ip_err ipdiameter_mod_peer(union Ip_sockaddr_union *peer_addr);
|
|
IP_PUBLIC Ipdiameter_peer_entry *
|
|
ipdiameter_find_peer(union Ip_sockaddr_union *peer_addr);
|
|
IP_PUBLIC Ipdiameter_peer_entry *
|
|
ipdiameter_find_peer_host(Ip_u8 *host_id);
|
|
IP_PUBLIC void ipdiameter_peer_add_req(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *request);
|
|
IP_PUBLIC void ipdiameter_peer_remove_req(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_request_entry *reqent);
|
|
IP_PUBLIC struct Ipdiameter_request_entry *
|
|
ipdiameter_peer_find_req(Ipdiameter_peer_entry *peer, Ip_u32 hbh_id);
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
IP_PUBLIC Ip_fd ipdiameter_peer_tcp4socket(void);
|
|
#endif
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
IP_PUBLIC Ip_fd ipdiameter_peer_tcp6socket(void);
|
|
#endif
|
|
|
|
IP_PUBLIC Ip_err ipdiameter_peer_init_conn_req(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_cleanup(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_error(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_bool ipdiameter_peer_elect(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_disc(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_reject(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_send_msg(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_process_msg(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_resp_accept(Ipdiameter_peer_entry *peer);
|
|
|
|
IP_PUBLIC void ipdiameter_peer_set_state(Ipdiameter_peer_entry *peer,
|
|
Ipdiameter_peer_state state);
|
|
|
|
IP_PUBLIC Ip_u32 ipdiameter_peer_process_CER(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *hdr);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_process_CEA(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *hdr);
|
|
IP_PUBLIC Ip_u32 ipdiameter_peer_process_DWR(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *hdr);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_process_DWA(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *hdr);
|
|
|
|
IP_PUBLIC Ip_err ipdiameter_peer_start_reconn_timer(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_reconn_timeout(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC Ip_err ipdiameter_peer_start_wd_timer(Ipdiameter_peer_entry *peer);
|
|
|
|
IP_PUBLIC char *ipdiameter_peer_type(Ipdiameter_peer_type type);
|
|
IP_PUBLIC char *ipdiameter_peer_state(Ipdiameter_peer_state state);
|
|
IP_PUBLIC char *ipdiameter_peer_appl(Ip_u32 appl_id);
|
|
|
|
IP_PUBLIC Ip_err ipdiameter_peer_add_tx_pending_pkt(Ipdiameter_peer_entry *peer,
|
|
struct Ipdiameter_header *package);
|
|
|
|
IP_PUBLIC Ipdiameter_peer_entry *
|
|
ipdiameter_peer_realm_route(char *realm);
|
|
IP_PUBLIC Ipdiameter_peer_entry *
|
|
ipdiameter_peer_proxy_route(void);
|
|
|
|
|
|
IP_PUBLIC void ipdiameter_peer_lck(Ipdiameter_peer_entry *peer);
|
|
IP_PUBLIC void ipdiameter_peer_unlck(Ipdiameter_peer_entry *peer);
|
|
|
|
|
|
#ifdef IPDIAMETER_ENABLE_REENTRANT
|
|
|
|
#ifdef IP_PORT_VXWORKS
|
|
#define IPDIAMETER_PEER_LOCK(peer) ipcom_mutex_lock(peer->code_mutex)
|
|
#define IPDIAMETER_PEER_UNLOCK(peer) ipcom_mutex_unlock(peer->code_mutex)
|
|
#else /* !IP_PORT_VXWORKS, Linux recursive semaphore */
|
|
#define IPDIAMETER_PEER_LOCK(peer) ipdiameter_peer_lck(peer)
|
|
#define IPDIAMETER_PEER_UNLOCK(peer) ipdiameter_peer_unlck(peer)
|
|
#endif /* IP_PORT_VXWORKS */
|
|
|
|
#else
|
|
#define IPDIAMETER_PEER_LOCK(peer) IP_NOOP
|
|
#define IPDIAMETER_PEER_UNLOCK(peer) IP_NOOP
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* #ifndef IPDIAMETER_PEER_H */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|