/* * socket.h - socket descriptor and API definition. * * Authors Alain Greiner (2016,2017,2018,2019,2020) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SOCKET_H_ #define _SOCKET_H_ #include #include #include #include #include /**************************************************************************************** * This defines the three commands that can be requested by a client thread to * a TX server thread. These commands are registered in the socket descriptor. ****************************************************************************************/ typedef enum sock_cmd_e { SOCKET_TX_CONNECT = 20, /*! request 3 steps handshake (TCP socket only) */ SOCKET_TX_SEND = 21, /*! request to send data (TCP or UDP socket) */ SOCKET_TX_CLOSE = 22, /*! request 3 steps handshake (TCP socket only) */ } sock_cmd_t; /***************************************************************************************** * This structure defines a socket descriptor. In order to parallelize the transfers, * the set of all registered sockets is split in several subsets. * The number of subsets is the number of NIC channels. * The distribution key is computed from the (remote_addr/remote_port) couple. * This computation is done by the NIC hardware for RX packets, * and by the dev_nic_connect() function for the TX packets. * * A socket is attached to the NIC_TX[channel] & NIC_RX[channel] chdevs. * Each socket descriptor allows the TX and TX server threads to access various buffers: * - the user "send" buffer contains the data to be send by the TX server thread. * - the kernel "receive" buffer contains the data received by the RX server thread. * - the kernel "r2t" buffer allows the RX server thread to make direct requests * to the associated TX server (to implement the TCP 3 steps handshake). * * The synchronisation mechanism between the clients threads and the servers threads * is different for TX and RX transfers: * * 1) For a TX transfer, it can exist only one client thread for a given socket, * the transfer is always initiated by the local process, and all TX commands * (CONNECT/SEND/CLOSE) are blocking for the client thread. The user buffer is * used by TCP to handle retransmissions when required.in case of re * The client thread registers the command in the thread descriptor, registers itself * in the socket descriptor, unblocks the TX server thread from the BLOCKED_CLIENT * condition, blocks itself on the BLOCKED_IO condition, and deschedules. * When the command is completed, the TX server thread unblocks the client thread. * The TX server blocks itself on the BLOCKED_CLIENT condition, when there is no * pending commands and the R2T queue is empty. It is unblocked when a client * register a new command, or when the TX server thread register a mew request * in the R2T queue. * The tx_valid flip-flop is SET by the client thread to signal a valid command. * It is RESET by the server thread when the command is completed: For a SEND, * all bytes have been sent (UDP) or acknowledged (TCP). * * 2) For an RX transfer, it can exist only one client thread for a given socket, * but the transfer is initiated by the remote process, and the RECV command * is not really blocking: the data can arrive before the local RECV command is * executed, and the server thread does not wait to receive all requested data * to deliver data to client thread. Therefore each socket contains a receive * buffer (rx_buf) handled as a single-writer/single-reader fifo. * The client thread consumes data from the rx_buf when possible. It blocks on the * BLOCKED_IO condition and deschedules when the rx_buf is empty. * It is unblocked by the RX server thread when new data is available in the rx_buf. * The RX server blocks itself on the BLOCKED_ISR condition When the NIC_RX packets * queue is empty. It is unblocked by the hardware when new packets are available. * * Note : the socket domains and types are defined in the "shared_socket.h" file. ****************************************************************************************/ typedef enum udp_socket_state_e { UDP_STATE_UNBOUND = 0, UDP_STATE_BOUND = 1, UDP_STATE_CONNECT = 2, } udp_socket_state_t; typedef enum tcp_socket_state_e { TCP_STATE_UNBOUND = 10, TCP_STATE_BOUND = 11, TCP_STATE_LISTEN = 12, TCP_STATE_SYN_SENT = 13, TCP_STATE_SYN_RCVD = 14, TCP_STATE_ESTAB = 15, TCP_STATE_FIN_WAIT1 = 16, TCP_STATE_FIN_WAIT2 = 17, TCP_STATE_CLOSING = 18, TCP_STATE_TIME_WAIT = 19, TCP_STATE_CLOSE_WAIT = 20, TCP_STATE_LAST_ACK = 21, } tcp_socket_state_t; typedef struct socket_s { remote_busylock_t lock; /*! lock protecting socket state */ uint32_t domain; /*! domain : AF_LOCAL / AF_INET */ uint32_t type; /*! type : SOCK_DGRAM / SOCK_STREAM */ pid_t pid; /*! owner process identifier */ uint32_t state; /*! see above */ uint32_t local_addr; /*! local socket IP address */ uint32_t remote_addr; /*! remote socket IP address */ uint32_t local_port; /*! local socket port number */ uint32_t remote_port; /*! remote socket port number */ uint32_t nic_channel; /*! derived from (remote_addr,remote_port) */ xlist_entry_t tx_list; /*! sockets attached to same NIC_TX chdev */ xptr_t tx_client; /*! extended pointer on TX client thread */ sock_cmd_t tx_cmd; /*! command type (CONNECT/SEND/CLOSE) */ uint8_t * tx_buf; /*! pointer on user buffer in user space */ uint32_t tx_len; /*! number of bytes to be sent in command */ uint32_t tx_todo; /*! number of bytes not yet sent */ uint32_t tx_error; /*! signal a TX command error */ xlist_entry_t rx_list; /*! sockets attached to same NIC_RX chdev */ xptr_t rx_client; /*! extended pointer on RX client thread */ remote_buf_t rx_buf; /*! embedded receive buffer descriptor */ remote_buf_t r2tq; /*! RX_to_TX requests queue descriptor */ remote_buf_t crqq; /*! connection requests queue descriptor */ /* the following fields defines the TCB used for a TCP connection */ uint32_t tx_una; /*! first unack byte in TX_data stream */ uint32_t tx_nxt; /*! next byte to send in TX_data stream */ uint32_t tx_wnd; /*! number of acceptable bytes in TX_data stream */ uint32_t rx_nxt; /*! next expected byte in RX_data stream */ uint32_t rx_wnd; /*! number of acceptable bytes in RX_data stream */ uint32_t rx_irs; /*! initial sequence number in RX_data stream */ } socket_t; /**************************************************************************************** * This function returns a printable string for a client_to_tx_server command type. **************************************************************************************** * type : SOCKET_TX_CONNECT / SOCKET_TX_SEND / SOCKET_TX_CLOSE ***************************************************************************************/ char * socket_cmd_str( uint32_t type ); /**************************************************************************************** * This function returns a printable string for an UDP or TCP socket state. **************************************************************************************** * state : UDP_STATE_*** / TCP_STATE*** ***************************************************************************************/ char * socket_state_str( uint32_t state ); /**************************************************************************************** * This function allocates memory in the cluster defined by the argument for a * socket descriptor defined by the and aruments, for the associated * file descriptor, and for the various kernel buffers descriptors contained in the * socket descriptor : "rx_buf" (receive buffer), "r2tq" (RX to RX requests queue), and * "crqq" (connect requests queue). It initialises the socket desccriptor static fields, * (other than local_addr, local_port, remote_addr, remote_port). * It registers the file descriptor in the reference process fd_array[], set the socket * the socket state to UNBOUND, and returns the file identifier in the argument. **************************************************************************************** * @ cxy : [in] target cluster identifier. * @ domain : [in] socket protocol family (must be AF_INET). * @ type : [in] socket type (SOCK_DGRAM / SOCK_STREAM). * @ socket : [out] buffer for a local pointer on created socket. * @ fdid : [out] buffer for file identifier. * @ return 0 if success / return -1 if failure (no memory). ***************************************************************************************/ error_t socket_create( cxy_t cxy, uint32_t domain, uint32_t type, struct socket_s ** socket, uint32_t * fdid ); /**************************************************************************************** * This functions releases all memory allocated to a socket identified by the * argument. This include the file descriptor, the socket descriptor, and all buffers * referenced by the socket descriptor. **************************************************************************************** * @ fdid : [in] file descriptor index. ***************************************************************************************/ void socket_destroy( uint32_t fdid ); /**************************************************************************************** * This functions registers the socket defined by the argument into the * lists of sockets attached to the NIC_TX and NIC_TX chdevs identified by the * argument. **************************************************************************************** * @ socket_xp : [in] extended pointer on socket descriptor * @ nic_channel : [in] NIC channel index. ***************************************************************************************/ void socket_link_to_servers( xptr_t socket_xp, uint32_t nic_channel ); #endif /* _SOCKET_H_ */