/* * Copyright (c) 2015 Jiri Svoboda * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @addtogroup tcp * @{ */ /** @file TCP type definitions */ #ifndef TCP_TYPE_H #define TCP_TYPE_H #include <adt/list.h> #include <async.h> #include <stdbool.h> #include <fibril.h> #include <fibril_synch.h> #include <refcount.h> #include <stddef.h> #include <stdint.h> #include <inet/addr.h> #include <inet/endpoint.h> struct tcp_conn; /** Connection state */ typedef enum { /** Listen */ st_listen, /** Syn-sent */ st_syn_sent, /** Syn-received */ st_syn_received, /** Established */ st_established, /** Fin-wait-1 */ st_fin_wait_1, /** Fin-wait-2 */ st_fin_wait_2, /** Close-wait */ st_close_wait, /** Closing */ st_closing, /** Last-ack */ st_last_ack, /** Time-wait */ st_time_wait, /** Closed */ st_closed } tcp_cstate_t; /** Error codes returned by TCP user calls (per the spec). */ typedef enum { /* OK */ TCP_EOK, /* Connection aborted due to user timeout */ TCP_EABORTED, /* Connection already exists */ TCP_EEXISTS, /* Connection closing */ TCP_ECLOSING, /* Connection does not exist */ TCP_ENOTEXIST, /* Connection illegal for this process */ TCP_EILLEGAL, /* Connection not open */ TCP_ENOTOPEN, /* Connection reset */ TCP_ERESET, /* Remote endpoint unspecified */ TCP_EUNSPEC, /* Insufficient resources */ TCP_ENORES, /* Precedence not allowed */ TCP_EINVPREC, /* Security/compartment not allowed */ TCP_EINVCOMP, TCP_EAGAIN } tcp_error_t; /** Transfer flags */ typedef enum { XF_PUSH = 0x1, XF_URGENT = 0x2 } xflags_t; /** Control message bits * * Note this is not the actual on-the-wire encoding */ typedef enum { CTL_SYN = 0x1, CTL_FIN = 0x2, CTL_RST = 0x4, CTL_ACK = 0x8 } tcp_control_t; /** Connection incoming segments queue */ typedef struct { struct tcp_conn *conn; list_t list; } tcp_iqueue_t; /** Active or passive connection */ typedef enum { ap_active, ap_passive } acpass_t; /** Flags for TCP open operation */ typedef enum { tcp_open_nonblock = 1 } tcp_open_flags_t; typedef struct tcp_conn tcp_conn_t; /** Connection state change callback function */ typedef void (*tcp_cstate_cb_t)(tcp_conn_t *, void *); /** Connection callbacks */ typedef struct { void (*cstate_change)(tcp_conn_t *, void *, tcp_cstate_t); void (*recv_data)(tcp_conn_t *, void *); } tcp_cb_t; /** Data returned by Status user call */ typedef struct { /** Connection state */ tcp_cstate_t cstate; } tcp_conn_status_t; typedef struct { /** SYN, FIN */ tcp_control_t ctrl; /** Segment sequence number */ uint32_t seq; /** Segment acknowledgement number */ uint32_t ack; /** Segment length in sequence space */ uint32_t len; /** Segment window */ uint32_t wnd; /** Segment urgent pointer */ uint32_t up; /** Segment data, may be moved when trimming segment */ void *data; /** Segment data, original pointer used to free data */ void *dfptr; } tcp_segment_t; /** Receive queue entry */ typedef struct { link_t link; inet_ep2_t epp; tcp_segment_t *seg; } tcp_rqueue_entry_t; /** Receive queue callbacks */ typedef struct { /** Segment received */ void (*seg_received)(inet_ep2_t *, tcp_segment_t *); } tcp_rqueue_cb_t; /** NCSim queue entry */ typedef struct { link_t link; usec_t delay; inet_ep2_t epp; tcp_segment_t *seg; } tcp_squeue_entry_t; /** Incoming queue entry */ typedef struct { link_t link; tcp_segment_t *seg; } tcp_iqueue_entry_t; /** Retransmission queue entry */ typedef struct { link_t link; tcp_conn_t *conn; tcp_segment_t *seg; } tcp_tqueue_entry_t; /** Retransmission queue callbacks */ typedef struct { /** Segment received */ void (*transmit_seg)(inet_ep2_t *, tcp_segment_t *); } tcp_tqueue_cb_t; /** Retransmission queue */ typedef struct { struct tcp_conn *conn; list_t list; /** Retransmission timer */ fibril_timer_t *timer; /** Callbacks */ tcp_tqueue_cb_t *cb; } tcp_tqueue_t; /** Connection */ struct tcp_conn { char *name; link_t link; /** Connection callbacks function */ tcp_cb_t *cb; /** Argument to @c cstate_cb */ void *cb_arg; /** Connection identification (local and remote endpoint) */ inet_ep2_t ident; /** Connection is in association map */ bool mapped; /** Active or passive connection */ acpass_t ap; /** Protects access to connection structure */ fibril_mutex_t lock; /** Reference count */ atomic_refcount_t refcnt; /** Connection state */ tcp_cstate_t cstate; /** True if connection was reset */ bool reset; /** True if connection was deleted by user */ bool deleted; /** Signalled when @c cstate changes */ fibril_condvar_t cstate_cv; /** Set when FIN is removed from the retransmission queue */ bool fin_is_acked; /** Queue of incoming segments */ tcp_iqueue_t incoming; /** Retransmission queue */ tcp_tqueue_t retransmit; /** Time-Wait timeout timer */ fibril_timer_t *tw_timer; /** Receive buffer */ uint8_t *rcv_buf; /** Receive buffer size */ size_t rcv_buf_size; /** Receive buffer number of bytes used */ size_t rcv_buf_used; /** Receive buffer contains FIN */ bool rcv_buf_fin; /** Receive buffer CV. Broadcast when new data is inserted */ fibril_condvar_t rcv_buf_cv; /** Send buffer */ uint8_t *snd_buf; /** Send buffer size */ size_t snd_buf_size; /** Send buffer number of bytes used */ size_t snd_buf_used; /** Send buffer contains FIN */ bool snd_buf_fin; /** Send buffer CV. Broadcast when space is made available in buffer */ fibril_condvar_t snd_buf_cv; /** Send unacknowledged */ uint32_t snd_una; /** Send next */ uint32_t snd_nxt; /** Send window */ uint32_t snd_wnd; /** Send urgent pointer */ uint32_t snd_up; /** Segment sequence number used for last window update */ uint32_t snd_wl1; /** Segment acknowledgement number used for last window update */ uint32_t snd_wl2; /** Initial send sequence number */ uint32_t iss; /** Receive next */ uint32_t rcv_nxt; /** Receive window */ uint32_t rcv_wnd; /** Receive urgent pointer */ uint32_t rcv_up; /** Initial receive sequence number */ uint32_t irs; }; /** Continuation of processing. * * When processing incoming segment, are we done or should we continue * processing it? */ typedef enum { cp_continue, cp_done } cproc_t; /** Encoded PDU */ typedef struct { /** Source address */ inet_addr_t src; /** Destination address */ inet_addr_t dest; /** Encoded header */ void *header; /** Encoded header size */ size_t header_size; /** Text */ void *text; /** Text size */ size_t text_size; } tcp_pdu_t; /** TCP client connection */ typedef struct tcp_cconn { /** Connection */ tcp_conn_t *conn; /** Connection ID for the client */ sysarg_t id; /** Client */ struct tcp_client *client; link_t lclient; } tcp_cconn_t; /** TCP client listener */ typedef struct tcp_clst { /** Local endpoint */ inet_ep_t elocal; /** Connection */ tcp_conn_t *conn; /** Listener ID for the client */ sysarg_t id; /** Client */ struct tcp_client *client; /** Link to tcp_client_t.clst */ link_t lclient; } tcp_clst_t; /** TCP client */ typedef struct tcp_client { /** Client callback session */ async_sess_t *sess; /** Client's connections */ list_t cconn; /* of tcp_cconn_t */ /** Client's listeners */ list_t clst; } tcp_client_t; /** Internal loopback type */ typedef enum { /** No loopback */ tcp_lb_none, /** Segment loopback */ tcp_lb_segment, /** PDU loopback */ tcp_lb_pdu } tcp_lb_t; #endif /** @} */