/* 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 #include #include #include #include #include #ifdef IPSSL #include #endif /* IPSSL */ #include #include /* **************************************************************************** * 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 **************************************************************************** */