/* ****************************************************************************** * HEADER FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iplite_tcp.h,v $ $Revision: 1.2 $ * $Source: /home/interpeak/CVSRoot/iplite2/src/iplite_tcp.h,v $ * $Author: kenneth $ $Date: 2009-10-21 07:53:36 $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Kenneth Jonsson ****************************************************************************** */ #ifndef IPLITE_TCP_H #define IPLITE_TCP_H /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "iplite_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #include "iplite.h" #include "iplite_sock.h" #ifdef __cplusplus extern "C" { #endif /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* TCP control flags */ #define IPLITE_TCPC_FLAG_PASSIVE_OPEN (1 << 0) /* This is a listen socket */ #define IPLITE_TCPC_FLAG_SOCK_CLOSED (1 << 1) /* The TCP module has closed the socket */ #define IPLITE_TCPC_FLAG_CONNABORTED (1 << 2) /* User process has called close, but data was present */ #define IPLITE_TCPC_FLAG_SMALL_PKT_OUT (1 << 3) /* 1 small (less that MSS) packet outstanding */ #define IPLITE_TCPC_FLAG_NO_SMDE (1 << 6) /* No Smooth mean deviation estimator calculated yet */ #define IPLITE_TCPC_FLAG_RTT (1 << 7) /* Round Trip Time mesurement in progress */ #define IPLITE_TCPC_FLAG_ACK_PENDING (1 << 8) /* An immediate ack pending */ #define IPLITE_TCPC_FLAG_DACK_PENDING (1 << 9) /* A delayed acknowledge is pending */ #define IPLITE_TCPC_FLAG_PERS_PENDING (1 << 10) /* A persist timer is running */ #define IPLITE_TCPC_FLAG_KEEP_PENDING (1 << 11) /* A keep alive timer is running */ #define IPLITE_TCPC_FLAG_FIN_PENDING (1 << 12) /* User process has called close, but data was present */ #define IPLITE_TCPC_FLAG_TIMESTAMP_OPT (1 << 13) /* Include timestamp option */ #define IPLITE_TCPC_FLAG_WND_SCALE_OPT (1 << 14) /* Include window scaling option */ #define IPLITE_TCPC_FLAG_RESENDING (1 << 15) /* A resend timer has expired, send packets from the resend queue instead of the send queue */ #define IPLITE_TCPC_FLAG_FAST_RETRANS (1 << 16) /* The oldest non-acked segment has been fast retransmitted */ #define IPLITE_TCPC_FLAG_SENDER_URG (1 << 18) /* The this socket is in sender urgent mode */ #define IPLITE_TCPC_FLAG_RECEIVER_URG (1 << 19) /* The this socket is in receiver urgent mode */ #define IPLITE_TCPC_FLAG_CORK (1 << 21) /* Do not send any frames less than a MSS if this is set */ #define IPLITE_TCPC_FLAG_RFC_1122_URG (1 << 24) /* Use the definition of urgen data described in RFC 1122, else use RFC 793*/ #define IPLITE_TCPC_FLAG_KCLOSE_PENDING (1 << 25) /* iplite_sock_kclose() function must be called when user closes socket */ #define IPLITE_TCPC_FLAG_USER_REF (1 << 26) /* This socket has been given to a user via socket() or accept() */ #define IPLITE_TCPC_USER_CLOSED (1 << 27) /* A user task has called close() on this socket. The TCB will is on the user_closed_sock list. */ /* Size of a TCP header without options */ #define IPLITE_TCP_HDR_SIZE 20 /* Default/minimum TCP header is 20 octets long */ #define IP_SHUT_EX (IP_SHUT_RDWR + 10) /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* TCP states (numeric values match those in RFC2452) */ typedef enum Iplite_tcp_state_enum { IPLITE_TCPS_CLOSED = 1, IPLITE_TCPS_LISTEN = 2, IPLITE_TCPS_SYN_SENT = 3, IPLITE_TCPS_SYN_RCVD = 4, IPLITE_TCPS_ESTABLISHED = 5, IPLITE_TCPS_CLOSE_WAIT = 6, IPLITE_TCPS_FIN_WAIT_1 = 7, IPLITE_TCPS_CLOSING = 8, IPLITE_TCPS_LAST_ACK = 9, IPLITE_TCPS_FIN_WAIT_2 = 10, IPLITE_TCPS_TIME_WAIT = 11, IPLITE_TCPS_DELETE_TCB = 12 } Iplite_tcp_state_t; /* Timeout type */ typedef enum Iplite_tcp_timo_enum { IPLITE_TCP_TIMO_NONE = 0, /* Placeholder that means: do not add a timer */ IPLITE_TCP_TIMO_CONN = 1, /* Connection Establishment */ IPLITE_TCP_TIMO_RETR = 2, /* Retransmission */ IPLITE_TCP_TIMO_DACK = 3, /* Delayed Acknowledge */ IPLITE_TCP_TIMO_PERS = 4, /* Persist */ IPLITE_TCP_TIMO_LOPE = 5, /* Lost peer (used during shutdown to avoid dead sockets) */ IPLITE_TCP_TIMO_TIWA = 6, /* TIME_WAIT */ IPLITE_TCP_TIMO_KEEP = 7, /* Keep-alive */ IPLITE_TCP_TIMO_LNGR = 8, /* Linger timer */ IPLITE_TCP_TIMO_RSRT = 9, /* Restart the 'send-FIN' call */ IPLITE_TCP_TIMO_ACK = 10, /* Immediate ACK pending */ IPLITE_TCP_TIMO_RCON = 11 /* Retry connect */ } Iplite_tcp_timo_t; /* *=========================================================================== * Parameters for one TCP segment *=========================================================================== */ typedef struct Iplite_tcp_segment_struct { struct Iplite_tcp_segment_struct *next; /* Next packet in resend list for outgoing and next out-of-order package for incoming */ Ipcom_pkt *pkt; /* Pointer to the packet that holds the TCP segment data */ Ip_u32 seq_start; /* First sequence number for segment */ Ip_u32 seq_end; /* Last sequence number for segment */ int app_start; /* (Only send) Start of application data */ int app_end; /* (Only send) End of application data */ Ip_u16 flags_n; /* The TCP flags for this segment */ Ip_u32 last_msec; /* Last timestamp this segment was processed */ } Iplite_tcp_segment; /* *=========================================================================== * Iplite_tcp_notifycb *=========================================================================== * Description: Is called when an event happens that can affect any of * socket parameters * Parameters: sock - The affected socket. * event - One of the IPNET_SOCKET_EVENT_xxx constants * Returns: * */ typedef void (*Iplite_tcp_notifycb)(Iplite_socket *sock, int event); /* Possible socket events */ #define IPLITE_SOCKET_EVENT_PATH_MTU 1 /* The path MTU has changed */ #define IPLITE_SOCKET_EVENT_KICKSTART 2 /* Try 'kickstart' this particular socket */ typedef Iplite_socket * (*Iplite_tcp_socklookup)(int proto, IP_CONST void *local_addr, Ip_u16 local_port, IP_CONST void *peer_addr, Ip_u16 peer_port, int rtab_index, int *first); /* *=========================================================================== * TCB sending parameters *=========================================================================== */ struct Iplite_tcp_send { Ip_u32 seq_next; /* The sequence number of next byte to send */ Ip_u32 seq_small; /* The last +1 sequence number in the last packet sent smaller than MSS */ Ip_u32 uack_bytes; /* Number of unacknowledged data bytes outstanding */ Ip_u32 peerwnd; /* Maximum number of bytes that the peer is ready to receive */ Ip_u32 cwnd; /* Congestion windows in bytes */ Ip_u32 ssthresh; /* Slow Start Threshold size (in bytes) */ Ip_u32 lowat; /* The low water mark for sending */ Ip_u32 urg_ptr; /* Urgent pointer, only valid if in send urgent mode () */ Ip_u16 last_wnd; /* Value of the last sent recv window size */ Ip_u8 wnd_scale; /* RFC1323 window scale shift, == 0 on means to not use window scaling option */ Ipcom_pkt *head; /* The send buffer, can contain multiple unsent packets, pkt->start is the offset to the application layer data. Head of send queue */ Ipcom_pkt *tail; /* Tail of send queue */ Ipcom_pkt *partial; /* Last sent packet that does not contain a full MSS of data */ struct Iplite_tcp_segment_struct *resend_head; /* List of sent segments for which an ack has not been received. */ struct Iplite_tcp_segment_struct *resend_tail; /* The list is sorted on increasing sequence number */ }; /* *=========================================================================== * TCB receiving parameters *=========================================================================== */ struct Iplite_tcp_recv { Ip_u32 seq_next; /* The start sequence number of the next expected TCP segment sent from the peer */ Ip_u32 last_ack_sent; /* The last received sequence number that an ACK has been sent for */ Ip_u32 lowat; /* The low water mark for receiving */ Ip_u32 urg_ptr; /* Urgent pointer, only valid if in receive urgent mode () */ Ip_u8 wnd_scale; /* RFC1323 window scale shift, == 0 on means to not use window scaling option */ struct Iplite_tcp_segment_struct *out_of_order_seg; /* Segments received, but was out of order. Will be moved to the received queue when the missing segment(s) are received */ }; /* *=========================================================================== * TCB (Transmission Control Block) *=========================================================================== */ typedef struct Iplite_tcp_tcb_struct { Iplite_socket *sock; /* The socket associated with this TCB */ Ipcom_list transient; /* List of TCB:s in transient states */ Ipcom_list closed; /* List of TCP sockets for which the user application has called close() */ Ip_u32 flags; /* IPLITE_TCPC_FLAG_xxx flags */ Iplite_tcp_state_t state; /* The current state of the TCP connection */ Ip_u8 duplicate_ack;/* Number of duplicate acks received */ Ip_u8 retr_count; /* Number of retransmission timeouts */ Ip_u8 peer_responded_to_pers; /* The peer has responded at least one time since the presist timer was last reset */ Ip_u16 mss; /* Maximum Segment Size for the connection */ Ip_u16 peer_mss; /* Maximum Segment Size presented by the peer */ Ip_u16 max_mss; /* User set maximum mss or 0 to use the largest possible MSS */ Ip_u32 sec_to_linger;/* Time this socket will linger after close */ int keepidle; /* Number of seconds an TCP connection must be idle before the first keep-alive probe is sent */ Ip_u16 keepintvl; /* Interval between keep-alive probes */ Ip_u16 keepcnt; /* Number of keep-alive probes before dropping connection */ Iplite_timeout *tmo_pers; Iplite_timeout *tmo_keep; Iplite_timeout *tmo_lngr; Iplite_timeout *tmo_rsrt; Iplite_timeout *tmo_dack; Iplite_timeout *tmo_retr; Iplite_timeout *tmo; Ip_s32 srtt; /* Smoothed Round Trip Time in microseconds */ Ip_s32 smde; /* Smooth mean deviation estimator in ticks (scaled as srtt) */ Ip_s32 rto; /* Retransmission timeout (scaled as srtt) */ Ip_u32 msec_sent; /* Absolute time when a timed data segment was sent */ Ip_u32 seq_timed; /* A sequence number of the first data byte in the timed segment */ struct Iplite_tcp_send send; struct Iplite_tcp_recv recv; int soft_error; /* Error code to use if this connections timeout */ Iplite_socket *parent; /* The listen socket that was used to create this socket */ Ip_u16 backlog_len; /* Maximum number of entries in the backlog */ Ip_u16 backlog_used; /* Number of used entries (pending + done) in the backlog */ int *backlog_pending;/* Connections that are doing the three-way handshake */ int *backlog_done; /* Connections that have finished the three-way handshake */ Ip_u32 (*get_mss)(Iplite_socket *sock); #ifdef IPLITE_DEBUG /* The last tick when the calculated roundtrip time was printed */ Ip_u32 rtt_last_printed; #endif /* IPLITE_DEBUG */ } Iplite_tcp_tcb; /* **************************************************************************** * 6 PROTOTYPES **************************************************************************** */ IP_PUBLIC int iplite_tcp_create(void); IP_PUBLIC int iplite_tcp_start(void); IP_PUBLIC const char *iplite_tcp_version(void); IP_PUBLIC Iplite_tcp_state_t iplite_tcp_get_state(Iplite_socket *sock); IP_PUBLIC int iplite_tcp_input(Ipcom_pkt *pkt, IP_CONST void *src_addr, IP_CONST void *dst_addr, Iplite_socklookup socklookup); IP_PUBLIC void iplite_tcp_sock_init(Iplite_socket *sock); IP_PUBLIC int iplite_tcp_connect(Iplite_socket *sock); IP_PUBLIC void iplite_tcp_shutdown(Iplite_socket *sock, int how); IP_PUBLIC int iplite_tcp_close(Iplite_socket *sock); IP_PUBLIC void iplite_tcp_sock_free(Iplite_socket *sock); IP_PUBLIC int iplite_tcp_usr_send(Iplite_socket *sock, IP_CONST void *buf, Ip_size_t len, int flags); IP_PUBLIC int iplite_tcp_usr_recv(Iplite_socket *sock, void *buf, Ip_size_t len, int flags); IP_PUBLIC int iplite_tcp_listen(Iplite_socket *sock, int backlog); IP_PUBLIC int iplite_tcp_accept(Iplite_socket *sock, struct Ip_sockaddr *name, Ip_socklen_t *addrlen); IP_PUBLIC int iplite_tcp_getsockopt(Iplite_socket *sock, int level, int optname, void *optval, Ip_socklen_t *optlen); IP_PUBLIC int iplite_tcp_setsockopt(Iplite_socket *sock, int level, int optname, IP_CONST void *optval, Ip_socklen_t optlen); IP_PUBLIC int iplite_tcp_drop_connection(Iplite_socket *sock, int error_code); IP_PUBLIC void iplite_tcp_pkt_drain(void); #ifdef IPCOM_USE_INET IP_PUBLIC void iplite_tcp_icmp4_report(Iplite_socket *sock, int type, int code, void *tcp_hdr); #endif #ifdef IPCOM_USE_INET6 IP_PUBLIC void iplite_tcp_icmp6_report(Iplite_socket *sock, int type, int code, void *tcp_hdr); #endif IP_PUBLIC int iplite_tcp_ioctl(Iplite_socket *sock, unsigned long request, void *argp); #ifdef IPCOM_USE_MIB2 IP_PUBLIC int iplite_tcp_get_rto(Ip_bool min); IP_PUBLIC int iplite_tcp_change_state_global(Iplite_socket *sock, int new_state); #endif /* IPCOM_USE_MIB2 */ #ifdef IPLITE_DEBUG IP_PUBLIC void iplite_tcp_pkt_freecheck(Ipcom_pkt *pkt); IP_PUBLIC Ip_fd iplite_tcp_ctrl_verify_retransq(Ipcom_pkt *pkt); IP_PUBLIC Ip_fd iplite_tcp_ctrl_verify_sockrecvq(Ipcom_pkt *pkt); IP_PUBLIC Ip_fd iplite_tcp_ctrl_verify_sockooorecvq(Ipcom_pkt *pkt); #endif IP_GLOBAL int iplite_tcp_send_reset(IP_CONST void *peer_addr, IP_CONST void *local_addr, Iplite_socket *sock, Iplite_tcp_segment *seg); IP_GLOBAL IP_CONST char *iplite_tcp_state_to_str(Iplite_tcp_state_t state); IP_GLOBAL IP_CONST char *iplite_tcp_timer_to_str(Iplite_tcp_timo_t type); IP_GLOBAL int iplite_tcp_pers_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_keep_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_conn_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_dack_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_retr_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_tiwa_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_lope_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); IP_GLOBAL int iplite_tcp_lngr_to_string(Iplite_socket *sock, char *buf, Ip_size_t buf_len); #ifdef __cplusplus } #endif #endif /* IPLITE_TCP_H */ /* **************************************************************************** * END OF FILE **************************************************************************** */