LCOV - code coverage report
Current view: top level - waltz/tlsrec - fd_tlsrec_sock.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 45 76 59.2 %
Date: 2026-09-17 04:28:31 Functions: 3 5 60.0 %

          Line data    Source code
       1             : #if FD_HAS_HOSTED
       2             : 
       3             : #include "fd_tlsrec_sock.h"
       4             : 
       5             : #include <errno.h>
       6             : #include <sys/socket.h>
       7             : 
       8             : int
       9             : fd_tlsrec_sock_flush( fd_tlsrec_sock_t * sock,
      10           3 :                       int                fd ) {
      11           6 :   while( sock->tx_off<sock->tx_sz ) {
      12           3 :     long sent = send( fd, sock->tx_buf+sock->tx_off, sock->tx_sz-sock->tx_off, MSG_NOSIGNAL|MSG_DONTWAIT );
      13           3 :     if( FD_UNLIKELY( sent<0L ) ) {
      14           0 :       if( errno==EINTR ) continue;
      15           0 :       if( errno==EAGAIN || errno==EWOULDBLOCK ) return 1;
      16           0 :       return FD_TLSREC_SOCK_ERR_SEND;
      17           0 :     }
      18           3 :     sock->tx_off += (ulong)sent;
      19           3 :   }
      20           3 :   sock->tx_off = 0UL;
      21           3 :   sock->tx_sz  = 0UL;
      22           3 :   return 0;
      23           3 : }
      24             : 
      25             : int
      26             : fd_tlsrec_sock_rx( fd_tlsrec_sock_t * sock,
      27             :                    fd_tlsrec_conn_t * conn,
      28             :                    int                fd,
      29          15 :                    ulong *            opt_rx_sz ) {
      30          15 :   if( opt_rx_sz ) *opt_rx_sz = 0UL;
      31             : 
      32          15 :   ulong tx_free = sizeof(sock->tx_buf) - sock->tx_sz;
      33          15 :   if( FD_UNLIKELY( fd_tlsrec_sock_rx_avail( sock ) || tx_free<FD_TLSREC_SOCK_TX_RESERVE ) ) return 0;
      34          12 :   if( FD_UNLIKELY( conn->rx_closed ) ) return FD_TLSREC_SOCK_ERR_EOF;
      35             : 
      36           9 :   uchar tcp_rx_buf[ FD_TLSREC_SOCK_RX_MTU ];
      37           9 :   long  tcp_rx_sz;
      38           9 :   do {
      39           9 :     tcp_rx_sz = recv( fd, tcp_rx_buf, sizeof(tcp_rx_buf), MSG_NOSIGNAL|MSG_DONTWAIT );
      40           9 :   } while( FD_UNLIKELY( tcp_rx_sz<0L && errno==EINTR ) );
      41           9 :   if( tcp_rx_sz<0L ) {
      42           0 :     if( errno==EAGAIN || errno==EWOULDBLOCK ) tcp_rx_sz = 0L;
      43           0 :     else return FD_TLSREC_SOCK_ERR_RECV;
      44           9 :   } else if( FD_UNLIKELY( !tcp_rx_sz ) ) {
      45           0 :     return FD_TLSREC_SOCK_ERR_EOF;
      46           0 :   }
      47             : 
      48           9 :   fd_tlsrec_slice_t tcp_rx[1];
      49           9 :   fd_tlsrec_slice_init( tcp_rx, tcp_rx_buf, (ulong)tcp_rx_sz );
      50           9 :   ulong tcp_tx_sz = tx_free;
      51           9 :   ulong app_rx_sz = sizeof(sock->rx_buf);
      52           9 :   int err = fd_tlsrec_conn_rx( conn, tcp_rx_sz ? tcp_rx : NULL,
      53           9 :                                sock->tx_buf+sock->tx_sz, &tcp_tx_sz,
      54           9 :                                sock->rx_buf, &app_rx_sz );
      55           9 :   sock->rx_off = 0UL;
      56           9 :   sock->rx_sz  = app_rx_sz;
      57           9 :   sock->tx_sz += tcp_tx_sz;
      58             : 
      59             :   /* Send before reporting a TLS error so an alert reaches the peer */
      60           9 :   if( tcp_tx_sz && FD_UNLIKELY( fd_tlsrec_sock_flush( sock, fd )<0 ) ) return FD_TLSREC_SOCK_ERR_SEND;
      61           9 :   if( FD_UNLIKELY( err ) ) return err;
      62           9 :   if( FD_UNLIKELY( conn->rx_closed && !app_rx_sz ) ) return FD_TLSREC_SOCK_ERR_EOF;
      63             : 
      64           3 :   if( opt_rx_sz ) *opt_rx_sz = (ulong)tcp_rx_sz;
      65           3 :   return 0;
      66           9 : }
      67             : 
      68             : int
      69             : fd_tlsrec_sock_close( fd_tlsrec_sock_t * sock,
      70             :                       fd_tlsrec_conn_t * conn,
      71           6 :                       int                fd ) {
      72           6 :   ulong tcp_tx_sz = sizeof(sock->tx_buf) - sock->tx_sz;
      73           6 :   int err = fd_tlsrec_conn_close( conn, sock->tx_buf+sock->tx_sz, &tcp_tx_sz );
      74           6 :   if( FD_UNLIKELY( err ) ) return err;
      75           3 :   sock->tx_sz += tcp_tx_sz;
      76           3 :   return fd_tlsrec_sock_flush( sock, fd );
      77           6 : }
      78             : 
      79             : int
      80             : fd_tlsrec_sock_tx( fd_tlsrec_sock_t * sock,
      81             :                    fd_tlsrec_conn_t * conn,
      82             :                    int                fd,
      83             :                    void const *       app,
      84             :                    ulong              app_sz,
      85           0 :                    ulong *            opt_consumed ) {
      86           0 :   if( opt_consumed ) *opt_consumed = 0UL;
      87           0 :   if( FD_UNLIKELY( sock->tx_sz ) ) return 0;
      88             : 
      89           0 :   fd_tlsrec_slice_t app_tx[1];
      90           0 :   fd_tlsrec_slice_init( app_tx, (uchar *)app, app_sz );
      91           0 :   ulong tcp_tx_sz = sizeof(sock->tx_buf);
      92           0 :   int err = fd_tlsrec_conn_tx( conn, sock->tx_buf, &tcp_tx_sz, app_tx );
      93           0 :   if( FD_UNLIKELY( err ) ) return err;
      94           0 :   sock->tx_off = 0UL;
      95           0 :   sock->tx_sz  = tcp_tx_sz;
      96           0 :   if( opt_consumed ) *opt_consumed = app_sz - fd_tlsrec_slice_sz( app_tx );
      97             : 
      98           0 :   if( FD_UNLIKELY( fd_tlsrec_sock_flush( sock, fd )<0 ) ) return FD_TLSREC_SOCK_ERR_SEND;
      99           0 :   return 0;
     100           0 : }
     101             : 
     102             : char const *
     103           0 : fd_tlsrec_sock_strerror( int err ) {
     104           0 :   switch( err ) {
     105           0 :   case 0:                       return "success";
     106           0 :   case FD_TLSREC_SOCK_ERR_RECV: return "recv failed";
     107           0 :   case FD_TLSREC_SOCK_ERR_SEND: return "send failed";
     108           0 :   case FD_TLSREC_SOCK_ERR_EOF:  return "peer closed connection";
     109           0 :   default:                      return err>0 ? fd_tlsrec_strerror( err ) : "unknown";
     110           0 :   }
     111           0 : }
     112             : 
     113             : #endif /* FD_HAS_HOSTED */

Generated by: LCOV version 1.14