Ignore:
Timestamp:
Jan 13, 2021, 12:36:17 AM (3 years ago)
Author:
alain
Message:

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/ksocket.h

    r669 r683  
    11/*
    2  * ksocket.h - kernel socket descriptor and API definition.
     2 * ksocket.h - kernel socket definition.
    33 *
    44 * Authors  Alain Greiner    (2016,2017,2018,2019,2020)
     
    4040 * existing sockets is split in as many subsets as the number of NIC channels, in order
    4141 * to parallelize the transfers. The distribution key defining the channel index
    42  * is computed from the (remote_addr/remote_port) couple: by the NIC hardware for the
    43  * RX packets; by the software for the TX packets, using a dedicated NIC driver function.
     42 * is computed from the (remote_addr/remote_port) couple (by the NIC hardware for the
     43 * RX packets; by the software for the TX packets) using a dedicated NIC driver function.
    4444 * All sockets that have the same key share the same channel, and each socket is
    4545 * therefore linked to two chdevs : NIC_TX[key] & NIC_RX[key].
     
    5252 *   to the associated TX server (mainly used to handle the TCP ACKs).
    5353 * - the kernel "crq" buffer allows to store concurrent remote client connect requests
    54  *   to a local server socket. It is allocated in socket.
     54 *   to a local server socket.
    5555 *
    5656 * The synchronisation mechanism between the client threads and the server threads
    5757 * is different for the TX and RX directions:
    5858 *
    59  * 1) TX stream
     59 * 1) TX direction (sent packets)
    6060 *
    6161 * - The internal API between the TX client thread and the NIC_TX server thread defines
    6262 *   four command types, stored in the "tx_cmd" variable of the socket descriptor:
    63  *   . SOCKET_TX_CONNECT : TCP client request to start the 3 steps connection handshake.
    64  *   . SOCKET_TX_ACCEPT  : TCP server request to accept one pending connection request.
     63 *   . SOCKET_TX_CONNECT : request to start the connection handshake (TCP client only).
     64 *   . SOCKET_TX_ACCEPT  : request to accept one connection request (TCP server only).
    6565 *   . SOCKET_TX_SEND    : local (UDP/TCP) request to send data to a remote (UDP/TCP).
    6666 *   . SOCKET_TX_CLOSE   : local TCP socket request remote TCP socket to close connection.
     
    6969 *   reset the "tx_error" field, and registers itself in the "tx_client" field.
    7070 *   Then, it unblocks the TX server thread from the BLOCKED_CLIENT condition, blocks itself
    71  *   on the BLOCKED_IO condition, and deschedules. For a SEND, the "tx_buf" kernel buffer
    72  *   is dynamicaly allocated by the client thread, that copies the payload from the user
    73  *   buffer to this kernel buffer, that is used as retransmission buffer, when required.
     71 *   on the BLOCKED_IO condition, and deschedules. For a SEND, the client thread copies
     72 *   the payload contained in the "u_buf" user buffer to the socket "tx_buf" kernel buffer
     73 *   that is used as retransmission buffer, when required.
    7474 * - A command is valid for the TX server when the socket descriptor "tx_valid" is true.
    75  *   For a SEND command, the "tx_valid" is reset by the NIC_TX server when the last byte has
    76  *   been sent, but the TX client thread is unblocked by the NIC_RX server thread only when
    77  *   the last byte has been acknowledged, or to report an error.
     75 *   For a SEND command, the "tx_valid" is reset by the NIC_TX server thread when the last
     76 *   byte has been sent, but the TX client thread is unblocked by the NIC_RX server thread
     77 *   only when the last byte has been acknowledged, or to report an error.
    7878 *   For the CONNECT, ACCEPT and CLOSE commands, the "tx_valid" is reset by the NIC_TX server
    7979 *   when the first segment of the handshake has been sent, but the TX client thread is
     
    8888 *   When "tx_valid" or "r2t_valid" are true, the TX server thread build and send an UDP
    8989 *   packet or TCP segment. A single SEND command can require a large number of TCP
    90  *   segments to move a big data buffer.
     90 *   segments to move a big data buffer, before unblocking the client thread.
    9191 *   This TX server thread blocks and deschedules on the BLOCKED_ISR condition when there
    9292 *   the NIC_RX queue is full . It is unblocked by the hardware NIC_TX_ISR.
    93  * - In order to detect and report error for multiple simultaneous TX accesses to the same
    94  *   socket, the client thread makes a double check before posting a new TX command :
     93 * - As multiple simultaneous TX accesses to the same socket are forbiden, the client
     94 *   thread makes a double check before posting a new TX command :
    9595 *   the "tx_valid" field must be false, and the "tx_client" field must be XPTR_NULL.
    9696 *   The "tx_valid" field is reset by the TX server thread, and the "tx_client"
     
    136136 * 3) R2T queue
    137137 *
    138  * To implement the TCP "3 steps handshake" protocol for connection or to send RST,
    139  * the RX server thread can directly request the associated TX server thread to send
    140  * control packets in  the TX stream, using a dedicate R2T (RX to TX) FIFO stored in
    141  * the socket descriptor. Each R2T request occupy one byte in this R2T queue.
     138 * The RX server thread can directly request the associated TX server thread to send
     139 * control packets in  the TX stream, using a dedicate R2T (RX to TX) queue embedded in
     140 * the socket descriptor, and implemented as a remote_buf_t FIFO.
     141 * It is used for TCP acknowledge and for the TCP three-steps handshake.
     142 * Each R2T request occupy exactly one single byte defining the TCP flags to be set.
    142143 *
    143144 * 4) CRQ queue
    144145 *
    145146 * The remote CONNECT requests received by a TCP socket (SYN segments) are stored in a
    146  * dedicated CRQ FIFO stored in the local socket descriptor. These requests are consumed
    147  * by the local client thread executing an ACCEPT.
    148  * Each CRQ request occupy sizeof(connect_request_t) bytes in this CRQ queue.
     147 * dedicated CRQ queue, and consumed  by the local client thread executing an ACCEPT.
     148 * This CRQ queue is embedded in the local socket descriptor,  and implemented as a
     149 * remote_buf_t FIFO. Each request occupy sizeof(connect_request_t) bytes in the queue.
    149150 * The connect_request_t structure containing the request arguments is defined below.
    150151 *
     
    171172 * This enum defines the set of command status that can be returned by the NIC_RX and
    172173 * NIC_TX server threads to the TX & RX client threads.
    173  * The success must be signaled by the null value / the various failure cases are
    174  * signaled by a non-null value.
    175174 ****************************************************************************************/
    176175typedef enum socket_cmd_sts_e
     
    217216tcp_socket_state_t;
    218217
    219 /*****************************************************************************************
     218/****************************************************************************************
    220219 * This structure defines one connection request, registered in the CRQ queue.
    221  ****************************************************************************************/
     220 ***************************************************************************************/
    222221typedef struct connect_request_s
    223222{
     
    229228connect_request_t;
    230229
    231 /*****************************************************************************************
     230/****************************************************************************************
    232231 * This structure defines the socket descriptor.
    233  ****************************************************************************************/
     232 ***************************************************************************************/
    234233typedef struct socket_s
    235234{
     
    253252    uint8_t         *  tx_buf;       /*! pointer on TX data buffer in kernel space     */
    254253    uint32_t           tx_len;       /*! number of data bytes for a SEND command       */
    255     uint32_t           tx_todo;      /*! number of bytes not yet sent                  */
    256     xlist_entry_t      tx_temp;      /*! temporary list of sockets (root in TX chdev)  */
     254    uint32_t           tx_todo;      /*! number of bytes not yet sent in tx_buf        */
     255    uint32_t           tx_ack;       /*! number of bytes acknowledged in tx_buf        */
    257256
    258257    xlist_entry_t      rx_list;      /*! all sockets attached to same NIC_RX channel   */
     
    271270    uint32_t           tx_wnd;       /*! number of acceptable bytes in TX_data stream  */
    272271    uint32_t           tx_una;       /*! first unack byte in TX_data stream            */
     272
    273273    uint32_t           rx_nxt;       /*! next expected byte in RX_data stream          */
    274274    uint32_t           rx_wnd;       /*! number of acceptable bytes in RX_data stream  */
     
    319319
    320320/****************************************************************************************
    321  * This function is called by the dev_nic_rx_handle_tcp() function, executed by the
    322  * NIC_RX[channel] server thread, to register a R2T request defined by the <flags>
     321 * This blocking function is called by the dev_nic_rx_handle_tcp() function, executed by
     322 * the NIC_RX[channel] server thread, to register a R2T request defined by the <flags>
    323323 * argument in the socket R2T queue, specified by the <queue_xp> argument.
    324324 * This function unblocks the NIC_TX[channel] server thread, identified by the <channel>
    325325 * argumentfrom the THREAD_BLOCKED_CLIENT condition.
     326 *
     327 * WARNING : It contains a waiting loop and return only when an empty slot has been
     328 * found in the R2T queue.
    326329 ****************************************************************************************
    327330 * @ queue_xp   : [in] extended pointer on the R2T qeue descriptor.
     
    330333 ***************************************************************************************/
    331334void socket_put_r2t_request( xptr_t    queue_xp,
    332                              uint32_t  flags,
     335                             uint8_t   flags,
    333336                             uint32_t  channel );
     337
     338/****************************************************************************************
     339 * This function is called by the nic_tx_server thread to extract an R2T request
     340 * (one byte) from a R2T queue, specified by the <queue_xp> argument, to the buffer
     341 * defined by the <flags> argument.
     342 *****************************************************************************************
     343 * @ queue_xp      : [in]  extended pointer on the CRQ queue descriptor.
     344 * @ flags         : [out] buffer for TCP flags to be set.
     345 * @ return 0 if success / return -1 if queue empty.
     346 ***************************************************************************************/
     347error_t socket_get_r2t_request (xptr_t    queue_xp,
     348                                uint8_t * flags );
    334349 
    335350/****************************************************************************************
     
    339354 * by the <queue_xp> argument.
    340355 ****************************************************************************************
    341  * @ queue_xp      : [in] extended pointer on the CRQ qeue descriptor.
     356 * @ queue_xp      : [in] extended pointer on the CRQ queue descriptor.
    342357 * @ remote_addr   : [in] remote socket IP address.
    343358 * @ remote_port   : [in] remote socket port.
     
    374389 ****************************************************************************************
    375390 * @ socket_xp     : [in] extended pointer on socket descriptor.
    376  $ @ string        : [in] name of calling function.
     391 * @ func_str      : [in] name of calling function.
     392 * @ string        : [in] string defining the calling context (can be NULL)
    377393 ***************************************************************************************/
    378394void socket_display( xptr_t         socket_xp,
    379                      const char   * func_str );
     395                     const char   * func_str,
     396                     const char   * string );
    380397
    381398
     
    464481 * This blocking function contains two blocking conditions because it requests services
    465482 * to both the NIC_RX server thread, and he NIC_TX server thread.
    466  * It can be split in five steps:
     483 * It is structured in five steps:
    467484 * 1) It makes several checkings on the listening socket domain, type, and state.
    468485 * 2) If the socket CRQ queue is empty, the function makes an SOCKET_RX_ACCEPT command
     
    529546 * arguments, to a connected (TCP or UDP) socket, identified by the <fdid> argument.
    530547 * The work is actually done by the NIC_TX server thread, and the synchronisation
     548 * between the client and the server threads uses the "tx_valid" set/reset flip-flop:
     549 * The client thread registers itself in the socket descriptor, registers in the queue
     550 * rooted in the NIC_TX[index] chdev, set "tx_valid", unblocks the server thread, and
     551 * finally blocks on THREAD_BLOCKED_IO, and deschedules.
     552 * When the TX server thread completes the command (all data has been sent for an UDP
     553 * socket, or acknowledged for a TCP socket), the server thread reset "rx_valid" and
     554 * unblocks the client thread.
     555 * This function can be called by a thread running in any cluster.
     556 * WARNING : This implementation does not support several concurent SEND commands
     557 * on the same socket, as only one TX thread can register in a given socket.
     558 ****************************************************************************************
     559 * @ fdid      : [in] file descriptor index identifying the socket.
     560 * @ u_buf     : [in] pointer on buffer containing packet in user space.
     561 * @ length    : [in] packet size in bytes.
     562 * @ return number of sent bytes if success / return -1 if failure.
     563 ***************************************************************************************/
     564int socket_send( uint32_t    fdid,
     565                 uint8_t   * u_buf,
     566                 uint32_t    length );
     567
     568/****************************************************************************************
     569 * This blocking function implements the recv() syscall.
     570 * It is used to receive data that has been stored by the NIC_RX server thread in the
     571 * rx_buf of a connected socket, identified by the <fdid> argument. 
     572 * The synchronisation between the client and the server threads uses the "rx_valid"
     573 * set/reset flip-flop: If "rx_valid" is set, the client simply moves the available
     574 * data from the "rx_buf" to the user buffer identified by the <u_buf> and <length>
     575 * arguments, and reset the "rx_valid" flip_flop. If "rx_valid" is not set, the client
     576 * thread register itself in the socket descriptor, registers in the clients queue rooted
     577 * in the NIC_RX[index] chdev, and finally blocks on THREAD_BLOCKED_IO, and deschedules.
     578 * The client thread is re-activated by the RX server, that set the "rx_valid" flip-flop
     579 * as soon as data is available in the "rx_buf". The number of bytes actually transfered
     580 * can be less than the user buffer size.
     581 * This  function can be called by a thread running in any cluster.
     582 * WARNING : This implementation does not support several concurent RECV
     583 * commands on the same socket, as only one RX thread can register in a given socket.
     584 ****************************************************************************************
     585 * @ fdid        : [in] file descriptor index identifying the local socket.
     586 * @ u_buf       : [in] pointer on buffer in user space.
     587 * @ length      : [in] buffer size in bytes.
     588 * @ return number of received bytes if success / return -1 if failure.
     589 ***************************************************************************************/
     590int socket_recv( uint32_t    fdid,
     591                 uint8_t   * u_buf,
     592                 uint32_t    length );
     593
     594/****************************************************************************************
     595 * This blocking function implements the sendto() syscall.
     596 * It is used to send data stored in the user buffer, identified the <u_buf> and <length>
     597 * to a remote process identified by the <remote_ip> and <remote_port> arguments,
     598 * through a local, unconnected (UDP) socket, identified by the <fdid> argument.
     599 * The work is actually done by the NIC_TX server thread, and the synchronisation
    531600 * between the client and the server threads uses the "rx_valid" set/reset flip-flop:
    532601 * The client thread registers itself in the socket descriptor, registers in the queue
     
    539608 * WARNING : This implementation does not support several concurent SEND/SENDTO commands
    540609 * on the same socket, as only one TX thread can register in a given socket.
    541  ****************************************************************************************
    542  * @ fdid      : [in] file descriptor index identifying the socket.
    543  * @ u_buf     : [in] pointer on buffer containing packet in user space.
    544  * @ length    : [in] packet size in bytes.
     610 * TODO : this function is not implemented yet.
     611 ****************************************************************************************
     612 * @ fdid        : [in] file descriptor index identifying the local socket.
     613 * @ u_buf       : [in] pointer on buffer containing packet in user space.
     614 * @ length      : [in] packet size in bytes.
     615 * @ remote_ip   : [in] remote socket IP address.
     616 * @ remote_port : [in] remote socket port address.
    545617 * @ return number of sent bytes if success / return -1 if failure.
    546618 ***************************************************************************************/
    547 int socket_send( uint32_t    fdid,
    548                  uint8_t   * u_buf,
    549                  uint32_t    length );
    550 
    551 /****************************************************************************************
    552  * This blocking function implements the recv() syscall.
     619int socket_sendto( uint32_t   fdid,
     620                   uint8_t  * u_buf,
     621                   uint32_t   length,
     622                   uint32_t   remote_ip,
     623                   uint16_t   remote_port );
     624
     625/****************************************************************************************
     626 * This blocking function implements the recvfrom() syscall.
    553627 * It is used to receive data that has been stored by the NIC_RX server thread in the
    554  * rx_buf of a connected (TCP or UDP) socket, identified by the <fdid> argument.
     628 * rx_buf of a non connected socket, identified by the <fdid> argument, from a
     629 * remote process identified by the <remote_ip> and <remote_port> arguments.
    555630 * The synchronisation between the client and the server threads uses the "rx_valid"
    556631 * set/reset flip-flop: If "rx_valid" is set, the client simply moves the available
     
    565640 * WARNING : This implementation does not support several concurent RECV/RECVFROM
    566641 * commands on the same socket, as only one RX thread can register in a given socket.
    567  ****************************************************************************************
    568  * @ fdid      : [in] file descriptor index identifying the socket.
    569  * @ u_buf     : [in] pointer on buffer in user space.
    570  * @ length    : [in] buffer size in bytes.
     642 * TODO : this function is not implemented yet.
     643 ****************************************************************************************
     644 * @ fdid        : [in] file descriptor index identifying the local socket.
     645 * @ u_buf       : [in] pointer on buffer in user space.
     646 * @ length      : [in] buffer size in bytes.
     647 * @ remote_ip   : [in] remote socket IP address.
     648 * @ remote_port : [in] remote socket port address.
    571649 * @ return number of received bytes if success / return -1 if failure.
    572650 ***************************************************************************************/
    573 int socket_recv( uint32_t    fdid,
    574                  uint8_t   * u_buf,
    575                  uint32_t    length );
     651int socket_recvfrom( uint32_t    fdid,
     652                     uint8_t   * u_buf,
     653                     uint32_t    length,
     654                     uint32_t    remote_ip,
     655                     uint16_t    remote_port );
    576656
    577657/****************************************************************************************
Note: See TracChangeset for help on using the changeset viewer.