LCOV - code coverage report
Current view: top level - discof/restore/utils - fd_ssresolve.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 356 0.0 %
Date: 2025-12-06 04:45:29 Functions: 0 16 0.0 %

          Line data    Source code
       1             : #include "fd_ssresolve.h"
       2             : #include "fd_ssarchive.h"
       3             : 
       4             : #include "../../../waltz/http/picohttpparser.h"
       5             : #include "../../../util/log/fd_log.h"
       6             : 
       7             : #include <unistd.h>
       8             : #include <errno.h>
       9             : #include <stdlib.h>
      10             : #include <strings.h>
      11             : 
      12             : #include <sys/socket.h>
      13             : #include <netinet/tcp.h>
      14             : #include <netinet/in.h>
      15             : 
      16             : /* TODO: consider refactoring the common http code in ssresolve and
      17             :    sshttp into a common library */
      18             : 
      19           0 : #define FD_SSRESOLVE_CONNECT             (0) /* connecting ssl */
      20           0 : #define FD_SSRESOLVE_STATE_REQ           (1) /* sending request for snapshot */
      21           0 : #define FD_SSRESOLVE_STATE_RESP          (2) /* receiving snapshot response */
      22           0 : #define FD_SSRESOLVE_STATE_SHUTTING_DOWN (3) /* shutting down ssl */
      23           0 : #define FD_SSRESOLVE_STATE_DONE          (4) /* done */
      24             : 
      25             : struct fd_ssresolve_private {
      26             :   int  state;
      27             :   long deadline;
      28             : 
      29             :   fd_ip4_port_t addr;
      30             :   int           sockfd;
      31             :   int           full;
      32             :   int           is_https;
      33             :   char const *  hostname;
      34             : 
      35             :   char  request[ 4096UL ];
      36             :   ulong request_sent;
      37             :   ulong request_len;
      38             : 
      39             :   ulong response_len;
      40             :   char  response[ USHORT_MAX ];
      41             : 
      42             : #if FD_HAS_OPENSSL
      43             :   SSL * ssl;
      44             : #endif
      45             : 
      46             :   ulong magic;
      47             : };
      48             : 
      49             : FD_FN_CONST ulong
      50           0 : fd_ssresolve_align( void ) {
      51           0 :   return FD_SSRESOLVE_ALIGN;
      52           0 : }
      53             : 
      54             : FD_FN_CONST ulong
      55           0 : fd_ssresolve_footprint( void ) {
      56           0 :   ulong l;
      57           0 :   l = FD_LAYOUT_INIT;
      58           0 :   l = FD_LAYOUT_APPEND( l, FD_SSRESOLVE_ALIGN, sizeof(fd_ssresolve_t) );
      59           0 :   return FD_LAYOUT_FINI( l, FD_SSRESOLVE_ALIGN );
      60           0 : }
      61             : 
      62             : void *
      63           0 : fd_ssresolve_new( void * shmem ) {
      64           0 :   if( FD_UNLIKELY( !shmem ) ) {
      65           0 :     FD_LOG_WARNING(( "NULL shmem" ));
      66           0 :     return NULL;
      67           0 :   }
      68             : 
      69           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_ssresolve_align() ) ) ) {
      70           0 :     FD_LOG_WARNING(( "unaligned shmem" ));
      71           0 :     return NULL;
      72           0 :   }
      73             : 
      74           0 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      75           0 :   fd_ssresolve_t * ssresolve = FD_SCRATCH_ALLOC_APPEND( l, FD_SSRESOLVE_ALIGN, sizeof(fd_ssresolve_t) );
      76             : 
      77           0 :   ssresolve->state        = FD_SSRESOLVE_STATE_REQ;
      78           0 :   ssresolve->request_sent = 0UL;
      79           0 :   ssresolve->request_len  = 0UL;
      80           0 :   ssresolve->response_len = 0UL;
      81           0 :   ssresolve->sockfd       = -1;
      82             : 
      83           0 : #if FD_HAS_OPENSSL
      84           0 :   ssresolve->ssl = NULL;
      85           0 : #endif
      86             : 
      87           0 :   FD_COMPILER_MFENCE();
      88           0 :   FD_VOLATILE( ssresolve->magic ) = FD_SSRESOLVE_MAGIC;
      89           0 :   FD_COMPILER_MFENCE();
      90             : 
      91           0 :   return (void *)ssresolve;
      92           0 : }
      93             : 
      94             : fd_ssresolve_t *
      95           0 : fd_ssresolve_join( void * _ssresolve ) {
      96           0 :   if( FD_UNLIKELY( !_ssresolve ) ) {
      97           0 :     FD_LOG_WARNING(( "NULL ssresolve" ));
      98           0 :     return NULL;
      99           0 :   }
     100             : 
     101           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)_ssresolve, fd_ssresolve_align() ) ) ) {
     102           0 :     FD_LOG_WARNING(( "misaligned ssresolve" ));
     103           0 :     return NULL;
     104           0 :   }
     105             : 
     106           0 :   fd_ssresolve_t * ssresolve = (fd_ssresolve_t *)_ssresolve;
     107             : 
     108           0 :   if( FD_UNLIKELY( ssresolve->magic!=FD_SSRESOLVE_MAGIC ) ) {
     109           0 :     FD_LOG_WARNING(( "bad magic" ));
     110           0 :     return NULL;
     111           0 :   }
     112             : 
     113           0 :   return ssresolve;
     114           0 : }
     115             : 
     116             : void
     117             : fd_ssresolve_init( fd_ssresolve_t * ssresolve,
     118             :                    fd_ip4_port_t    addr,
     119             :                    int              sockfd,
     120           0 :                    int              full ) {
     121           0 :   ssresolve->addr   = addr;
     122           0 :   ssresolve->sockfd = sockfd;
     123           0 :   ssresolve->full   = full;
     124             : 
     125           0 :   ssresolve->state        = FD_SSRESOLVE_STATE_REQ;
     126           0 :   ssresolve->request_sent = 0UL;
     127           0 :   ssresolve->request_len  = 0UL;
     128           0 :   ssresolve->response_len = 0UL;
     129           0 :   ssresolve->is_https     = 0;
     130           0 : }
     131             : 
     132             : #if FD_HAS_OPENSSL
     133             : void
     134             : fd_ssresolve_init_https( fd_ssresolve_t * ssresolve,
     135             :                          fd_ip4_port_t    addr,
     136             :                          int              sockfd,
     137             :                          int              full,
     138             :                          char const *     hostname,
     139           0 :                          SSL_CTX *        ssl_ctx ) {
     140           0 :   ssresolve->addr   = addr;
     141           0 :   ssresolve->sockfd = sockfd;
     142           0 :   ssresolve->full   = full;
     143             : 
     144           0 :   ssresolve->state        = FD_SSRESOLVE_CONNECT;
     145           0 :   ssresolve->request_sent = 0UL;
     146           0 :   ssresolve->request_len  = 0UL;
     147           0 :   ssresolve->response_len = 0UL;
     148           0 :   ssresolve->is_https     = 1;
     149           0 :   ssresolve->hostname     = hostname;
     150             : 
     151           0 :   ssresolve->ssl = SSL_new( ssl_ctx );
     152           0 :   if( FD_UNLIKELY( !ssresolve->ssl ) ) {
     153           0 :     FD_LOG_ERR(( "SSL_new failed" ));
     154           0 :   }
     155             : 
     156           0 :   static uchar const alpn_protos[] = { 8, 'h', 't', 't', 'p', '/', '1', '.', '1' };
     157           0 :   int alpn_res = SSL_set_alpn_protos( ssresolve->ssl, alpn_protos, sizeof(alpn_protos) );
     158           0 :   if( FD_UNLIKELY( alpn_res!=0 ) ) {
     159           0 :     FD_LOG_ERR(( "SSL_set_alpn_protos failed (%d)", alpn_res ));
     160           0 :   }
     161             : 
     162             :   /* set SNI */
     163           0 :   FD_TEST( hostname && hostname[ 0 ]!='\0' );
     164           0 :   int set1_host_res = SSL_set1_host( ssresolve->ssl, hostname );
     165           0 :   if( FD_UNLIKELY( !set1_host_res ) ) {
     166           0 :     FD_LOG_ERR(( "SSL_set1_host failed (%d)", set1_host_res ));
     167           0 :   }
     168           0 : }
     169             : #endif
     170             : 
     171             : static void
     172           0 : fd_ssresolve_render_req( fd_ssresolve_t * ssresolve ) {
     173           0 :   if( FD_LIKELY( ssresolve->full ) ) {
     174           0 :     if( FD_UNLIKELY( ssresolve->is_https ) ) {
     175           0 :       FD_TEST( fd_cstr_printf_check( ssresolve->request, sizeof(ssresolve->request), &ssresolve->request_len,
     176           0 :              "HEAD /snapshot.tar.bz2 HTTP/1.1\r\n"
     177           0 :              "User-Agent: Firedancer\r\n"
     178           0 :              "Accept: */*\r\n"
     179           0 :              "Accept-Encoding: identity\r\n"
     180           0 :              "Host: %s\r\n\r\n",
     181           0 :              ssresolve->hostname ) );
     182           0 :     } else {
     183           0 :       FD_TEST( fd_cstr_printf_check( ssresolve->request, sizeof(ssresolve->request), &ssresolve->request_len,
     184           0 :              "HEAD /snapshot.tar.bz2 HTTP/1.1\r\n"
     185           0 :              "User-Agent: Firedancer\r\n"
     186           0 :              "Accept: */*\r\n"
     187           0 :              "Accept-Encoding: identity\r\n"
     188           0 :              "Host: " FD_IP4_ADDR_FMT "\r\n\r\n",
     189           0 :              FD_IP4_ADDR_FMT_ARGS( ssresolve->addr.addr ) ) );
     190           0 :     }
     191           0 :   } else {
     192           0 :     if( FD_UNLIKELY( ssresolve->is_https ) ) {
     193           0 :       FD_TEST( fd_cstr_printf_check( ssresolve->request, sizeof(ssresolve->request), &ssresolve->request_len,
     194           0 :              "HEAD /incremental-snapshot.tar.bz2 HTTP/1.1\r\n"
     195           0 :              "User-Agent: Firedancer\r\n"
     196           0 :              "Accept: */*\r\n"
     197           0 :              "Accept-Encoding: identity\r\n"
     198           0 :              "Host: %s\r\n\r\n",
     199           0 :              ssresolve->hostname ) );
     200           0 :     } else {
     201           0 :       FD_TEST( fd_cstr_printf_check( ssresolve->request, sizeof(ssresolve->request), &ssresolve->request_len,
     202           0 :              "HEAD /incremental-snapshot.tar.bz2 HTTP/1.1\r\n"
     203           0 :              "User-Agent: Firedancer\r\n"
     204           0 :              "Accept: */*\r\n"
     205           0 :              "Accept-Encoding: identity\r\n"
     206           0 :              "Host: " FD_IP4_ADDR_FMT "\r\n\r\n",
     207           0 :              FD_IP4_ADDR_FMT_ARGS( ssresolve->addr.addr ) ) );
     208           0 :     }
     209           0 :   }
     210           0 : }
     211             : 
     212             : static int
     213           0 : fd_ssresolve_send_request( fd_ssresolve_t * ssresolve ) {
     214           0 :   FD_TEST( ssresolve->state==FD_SSRESOLVE_STATE_REQ );
     215             : 
     216           0 :   if( FD_UNLIKELY( !ssresolve->request_len ) ) {
     217           0 :     fd_ssresolve_render_req( ssresolve );
     218           0 :   }
     219             : 
     220           0 :   long sent = 0L;
     221           0 :   if( FD_LIKELY( ssresolve->is_https ) ) {
     222           0 : #if FD_HAS_OPENSSL
     223           0 :     int write_res = SSL_write( ssresolve->ssl, ssresolve->request+ssresolve->request_sent, (int)(ssresolve->request_len-ssresolve->request_sent) );
     224           0 :     if( FD_UNLIKELY( write_res<=0 ) ) {
     225           0 :       int ssl_err = SSL_get_error( ssresolve->ssl, write_res );
     226             : 
     227           0 :       if( FD_UNLIKELY( ssl_err!=SSL_ERROR_WANT_READ && ssl_err!=SSL_ERROR_WANT_WRITE ) ) {
     228           0 :         FD_LOG_WARNING(( "SSL_write failed (%d)", ssl_err ));
     229           0 :         return FD_SSRESOLVE_ADVANCE_ERROR;
     230           0 :       }
     231             : 
     232           0 :       return FD_SSRESOLVE_ADVANCE_AGAIN;
     233           0 :     }
     234             : 
     235           0 :     sent = (long)write_res;
     236             : #else
     237             :     FD_LOG_ERR(( "cannot use HTTPS without OpenSSL" ));
     238             : #endif
     239           0 :   } else {
     240           0 :     sent = sendto( ssresolve->sockfd, ssresolve->request+ssresolve->request_sent, ssresolve->request_len-ssresolve->request_sent, 0, NULL, 0 );
     241           0 :     if( FD_UNLIKELY( -1==sent && errno==EAGAIN ) ) return FD_SSRESOLVE_ADVANCE_AGAIN;
     242           0 :     else if( FD_UNLIKELY( -1==sent ) )             return FD_SSRESOLVE_ADVANCE_ERROR;
     243           0 :   }
     244             : 
     245           0 :   ssresolve->request_sent += (ulong)sent;
     246           0 :   if( FD_UNLIKELY( ssresolve->request_sent==ssresolve->request_len ) ) {
     247           0 :     ssresolve->state = FD_SSRESOLVE_STATE_RESP;
     248           0 :     return FD_SSRESOLVE_ADVANCE_SUCCESS;
     249           0 :   }
     250             : 
     251           0 :   return FD_SSRESOLVE_ADVANCE_AGAIN;
     252           0 : }
     253             : 
     254             : static int
     255             : fd_ssresolve_parse_redirect( fd_ssresolve_t *        ssresolve,
     256             :                              struct phr_header *     headers,
     257             :                              ulong                   header_cnt,
     258           0 :                              fd_ssresolve_result_t * result ) {
     259           0 :   ulong        location_len = 0UL;
     260           0 :   char const * location     = NULL;
     261             : 
     262           0 :   for( ulong i=0UL; i<header_cnt; i++ ) {
     263           0 :     if( FD_UNLIKELY( !strncasecmp( headers[ i ].name, "location", headers[ i ].name_len ) ) ) {
     264           0 :       if( FD_UNLIKELY( !headers [ i ].value_len || headers[ i ].value[ 0 ]!='/' ) ) {
     265           0 :         FD_LOG_WARNING(( "invalid location header `%.*s`", (int)headers[ i ].value_len, headers[ i ].value ));
     266           0 :         return FD_SSRESOLVE_ADVANCE_ERROR;
     267           0 :       }
     268             : 
     269           0 :       location_len = headers[ i ].value_len;
     270           0 :       location = headers[ i ].value;
     271           0 :       break;
     272           0 :     }
     273           0 :   }
     274             : 
     275           0 :   if( FD_UNLIKELY( location_len>=PATH_MAX-1UL ) ) return FD_SSRESOLVE_ADVANCE_ERROR;
     276             : 
     277           0 :   char snapshot_name[ PATH_MAX ];
     278           0 :   fd_memcpy( snapshot_name, location+1UL, location_len-1UL );
     279           0 :   snapshot_name[ location_len-1UL ] = '\0';
     280             : 
     281           0 :   int is_zstd;
     282           0 :   ulong full_entry_slot, incremental_entry_slot;
     283           0 :   uchar decoded_hash[ FD_HASH_FOOTPRINT ];
     284           0 :   int err = fd_ssarchive_parse_filename( snapshot_name, &full_entry_slot, &incremental_entry_slot, decoded_hash, &is_zstd );
     285             : 
     286           0 :   if( FD_UNLIKELY( err || !is_zstd ) ) {
     287           0 :     FD_LOG_WARNING(( "unrecognized snapshot file `%s` in redirect location header", snapshot_name ));
     288           0 :     return FD_SSRESOLVE_ADVANCE_ERROR;
     289           0 :   }
     290             : 
     291           0 :   if( FD_LIKELY( incremental_entry_slot==ULONG_MAX ) ) {
     292           0 :     result->slot      = full_entry_slot;
     293           0 :     result->base_slot = ULONG_MAX;
     294           0 :   } else {
     295           0 :     result->slot      = incremental_entry_slot;
     296           0 :     result->base_slot = full_entry_slot;
     297           0 :   }
     298             : 
     299           0 :   if( FD_UNLIKELY( ssresolve->is_https ) ) ssresolve->state = FD_SSRESOLVE_STATE_SHUTTING_DOWN;
     300           0 :   else                                     ssresolve->state = FD_SSRESOLVE_STATE_DONE;
     301           0 :   return FD_SSRESOLVE_ADVANCE_RESULT;
     302           0 : }
     303             : 
     304             : static int
     305             : fd_ssresolve_read_response( fd_ssresolve_t *        ssresolve,
     306           0 :                             fd_ssresolve_result_t * result ) {
     307           0 :   FD_TEST( ssresolve->state==FD_SSRESOLVE_STATE_RESP );
     308             : 
     309           0 :   long read = 0L;
     310           0 :   if( FD_LIKELY( ssresolve->is_https ) ) {
     311           0 : #if FD_HAS_OPENSSL
     312           0 :     int read_res = SSL_read( ssresolve->ssl, ssresolve->response+ssresolve->response_len, (int)(sizeof(ssresolve->response)-ssresolve->response_len) );
     313           0 :     if( FD_UNLIKELY( read_res<=0 ) ) {
     314           0 :       int ssl_err = SSL_get_error( ssresolve->ssl, read_res );
     315             : 
     316           0 :       if( FD_UNLIKELY( ssl_err!=SSL_ERROR_WANT_READ && ssl_err!=SSL_ERROR_WANT_WRITE ) ) {
     317           0 :         FD_LOG_WARNING(( "SSL_read failed (%d)", ssl_err ));
     318           0 :         return FD_SSRESOLVE_ADVANCE_ERROR;
     319           0 :       }
     320             : 
     321           0 :       return FD_SSRESOLVE_ADVANCE_AGAIN;
     322           0 :     }
     323             : 
     324           0 :     read = (long)read_res;
     325             : #else
     326             :     FD_LOG_ERR(( "cannot use HTTPS without OpenSSL" ));
     327             : #endif
     328           0 :   } else {
     329           0 :     read = recvfrom( ssresolve->sockfd, ssresolve->response+ssresolve->response_len, sizeof(ssresolve->response)-ssresolve->response_len, 0, NULL, NULL );
     330           0 :     if( FD_UNLIKELY( -1==read && errno==EAGAIN ) ) return FD_SSRESOLVE_ADVANCE_AGAIN;
     331           0 :     else if( FD_UNLIKELY( -1==read ) ) {
     332           0 :       FD_LOG_WARNING(( "recvfrom() failed (%d-%s)", errno, fd_io_strerror( errno ) ));
     333           0 :       return FD_SSRESOLVE_ADVANCE_ERROR;
     334           0 :     }
     335           0 :   }
     336             : 
     337           0 :   ssresolve->response_len += (ulong)read;
     338             : 
     339           0 :   int               minor_version;
     340           0 :   int               status;
     341           0 :   const char *      message;
     342           0 :   ulong             message_len;
     343           0 :   struct phr_header headers[ 128UL ];
     344           0 :   ulong             header_cnt = 128UL;
     345           0 :   int parsed = phr_parse_response( ssresolve->response,
     346           0 :                                     ssresolve->response_len,
     347           0 :                                     &minor_version,
     348           0 :                                     &status,
     349           0 :                                     &message,
     350           0 :                                     &message_len,
     351           0 :                                     headers,
     352           0 :                                     &header_cnt,
     353           0 :                                     ssresolve->response_len - (ulong)read );
     354           0 :   if( FD_UNLIKELY( parsed==-1 ) ) {
     355           0 :     FD_LOG_WARNING(( "malformed response body" ));
     356           0 :     return FD_SSRESOLVE_ADVANCE_ERROR;
     357           0 :   } else if( parsed==-2 ) {
     358           0 :     return FD_SSRESOLVE_ADVANCE_AGAIN;
     359           0 :   }
     360             : 
     361           0 :   int is_redirect = (status==301) | (status==302) | (status==303) | (status==304) | (status==307) | (status==308);
     362           0 :   if( FD_UNLIKELY( is_redirect ) ) {
     363           0 :     return fd_ssresolve_parse_redirect( ssresolve, headers, header_cnt, result );
     364           0 :   }
     365             : 
     366           0 :   if( FD_UNLIKELY( status!=200 ) ) {
     367           0 :     FD_LOG_WARNING(( "unexpected response status %d", status ));
     368           0 :     return FD_SSRESOLVE_ADVANCE_ERROR;
     369           0 :   }
     370             : 
     371           0 :   return FD_SSRESOLVE_ADVANCE_ERROR;
     372           0 : }
     373             : 
     374             : #if FD_HAS_OPENSSL
     375             : static int
     376           0 : ssresolve_connect_ssl( fd_ssresolve_t * ssresolve ) {
     377           0 :   FD_TEST( ssresolve->ssl );
     378           0 :   SSL_set_fd( ssresolve->ssl, ssresolve->sockfd );
     379           0 :   int ssl_err = SSL_connect( ssresolve->ssl );
     380           0 :   if( FD_UNLIKELY( ssl_err!=1 ) ) {
     381           0 :     int ssl_err_code = SSL_get_error( ssresolve->ssl, ssl_err );
     382           0 :     if( FD_UNLIKELY( ssl_err_code!=SSL_ERROR_WANT_READ && ssl_err_code!=SSL_ERROR_WANT_WRITE ) ) {
     383           0 :       FD_LOG_WARNING(( "SSL_connect failed (%d)", ssl_err_code ));
     384           0 :       SSL_free( ssresolve->ssl );
     385           0 :       ssresolve->ssl = NULL;
     386           0 :       return FD_SSRESOLVE_ADVANCE_ERROR;
     387           0 :     }
     388             :     /* in progress */
     389           0 :     return FD_SSRESOLVE_ADVANCE_AGAIN;
     390           0 :   }
     391             : 
     392           0 :   ssresolve->state = FD_SSRESOLVE_STATE_REQ;
     393           0 :   return FD_SSRESOLVE_ADVANCE_AGAIN;
     394           0 : }
     395             : 
     396             : static int
     397           0 : ssresolve_shutdown_ssl( fd_ssresolve_t * ssresolve ) {
     398           0 :   int res = SSL_shutdown( ssresolve->ssl );
     399           0 :   if( FD_LIKELY( res<=0 ) ) {
     400           0 :     int ssl_err_code = SSL_get_error( ssresolve->ssl, res );
     401           0 :     if( FD_UNLIKELY( ssl_err_code!=SSL_ERROR_WANT_READ && ssl_err_code!=SSL_ERROR_WANT_WRITE && res!=0 ) ) {
     402           0 :       FD_LOG_WARNING(( "SSL_shutdown failed (%d)", ssl_err_code ));
     403           0 :       SSL_free( ssresolve->ssl );
     404           0 :       ssresolve->ssl = NULL;
     405           0 :       return FD_SSRESOLVE_ADVANCE_ERROR;
     406           0 :     }
     407             : 
     408           0 :     return FD_SSRESOLVE_ADVANCE_AGAIN;
     409           0 :   }
     410             : 
     411           0 :   ssresolve->state = FD_SSRESOLVE_STATE_DONE;
     412           0 :   return FD_SSRESOLVE_ADVANCE_SUCCESS;
     413           0 : }
     414             : #endif
     415             : 
     416             : int
     417           0 : fd_ssresolve_advance_poll_out( fd_ssresolve_t * ssresolve ) {
     418           0 :   int res;
     419           0 :   switch( ssresolve->state ) {
     420           0 : #if FD_HAS_OPENSSL
     421           0 :     case FD_SSRESOLVE_CONNECT: {
     422           0 :       res = ssresolve_connect_ssl( ssresolve );
     423           0 :       break;
     424           0 :     }
     425           0 :     case FD_SSRESOLVE_STATE_SHUTTING_DOWN: {
     426           0 :       res = ssresolve_shutdown_ssl( ssresolve );
     427           0 :       break;
     428           0 :     }
     429           0 : #endif
     430           0 :     case FD_SSRESOLVE_STATE_REQ: {
     431           0 :       res = fd_ssresolve_send_request( ssresolve );
     432           0 :       break;
     433           0 :     }
     434           0 :     case FD_SSRESOLVE_STATE_RESP: {
     435           0 :       res = FD_SSRESOLVE_ADVANCE_AGAIN;
     436           0 :       break;
     437           0 :     }
     438           0 :     default: {
     439           0 :       FD_LOG_ERR(( "unexpected state %d", ssresolve->state ));
     440           0 :       return FD_SSRESOLVE_ADVANCE_ERROR;
     441           0 :     }
     442           0 :   }
     443           0 :   return res;
     444           0 : }
     445             : 
     446             : int
     447             : fd_ssresolve_advance_poll_in( fd_ssresolve_t *        ssresolve,
     448           0 :                               fd_ssresolve_result_t * result ) {
     449           0 :   int res;
     450           0 :   switch( ssresolve->state ) {
     451           0 : #if FD_HAS_OPENSSL
     452           0 :     case FD_SSRESOLVE_CONNECT: {
     453           0 :       res = ssresolve_connect_ssl( ssresolve );
     454           0 :       break;
     455           0 :     }
     456           0 :     case FD_SSRESOLVE_STATE_SHUTTING_DOWN: {
     457           0 :       res = ssresolve_shutdown_ssl( ssresolve );
     458           0 :       break;
     459           0 :     }
     460           0 : #endif
     461           0 :     case FD_SSRESOLVE_STATE_RESP: {
     462           0 :       res = fd_ssresolve_read_response( ssresolve, result );
     463           0 :       break;
     464           0 :     }
     465           0 :     case FD_SSRESOLVE_STATE_REQ: {
     466           0 :       res = FD_SSRESOLVE_ADVANCE_AGAIN;
     467           0 :       break;
     468           0 :     }
     469           0 :     case FD_SSRESOLVE_STATE_DONE: {
     470           0 :       res = FD_SSRESOLVE_ADVANCE_SUCCESS;
     471           0 :       break;
     472           0 :     }
     473           0 :     default: {
     474           0 :       FD_LOG_ERR(( "unexpected state %d", ssresolve->state ));
     475           0 :       return FD_SSRESOLVE_ADVANCE_ERROR;
     476           0 :     }
     477           0 :   }
     478             : 
     479           0 :   return res;
     480           0 : }
     481             : 
     482             : int
     483           0 : fd_ssresolve_is_done( fd_ssresolve_t * ssresolve ) {
     484           0 :   return ssresolve->state==FD_SSRESOLVE_STATE_DONE;
     485           0 : }
     486             : 
     487             : void
     488           0 : fd_ssresolve_cancel( fd_ssresolve_t * ssresolve ) {
     489           0 :   if( FD_LIKELY( ssresolve->sockfd!=-1 ) ) {
     490           0 :     if( FD_UNLIKELY( -1==close( ssresolve->sockfd ) ) ) FD_LOG_ERR(( "close() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     491           0 :     ssresolve->sockfd = -1;
     492           0 :   }
     493           0 : #if FD_HAS_OPENSSL
     494           0 :   if( FD_LIKELY( ssresolve->ssl ) ) {
     495           0 :     SSL_free( ssresolve->ssl );
     496             :     ssresolve->ssl = NULL;
     497           0 :   }
     498           0 : #endif
     499           0 : }

Generated by: LCOV version 1.14