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

Generated by: LCOV version 1.14