Return TypeFunction nameArguments
hzEcodehzTcpClient::ConnectSSL(const char*,unsigned int,unsigned int,unsigned int,)

Declared in file: hzTcpClient.h
Defined in file : hzTcpClient.cpp

Function Logic:

0:START 1:!bBeenHere 2:SSL_library_init bBeenHere 3:m_nSock 4:m_Hostname==hostname&&m_nPort==nPort 5:Return E_OK 6:hzString::Clear m_pHost hzTcpClient::Close 7:m_Hostname&&m_Hostname!=hostname 8:m_Hostname m_pHost 9:gethostbyname m_pHost 10:!m_pHost 11:h_errno==TRY_AGAIN 12:Return E_DNS_RETRY 13:h_errno==HOST_NOT_FOUND 14:Return E_DNS_NOHOST 15:h_errno==NO_RECOVERY 16:Return E_DNS_FAILED 17:h_errno==NO_DATA||h_errno==NO_ADDRESS 18:Return E_DNS_NODATA 19:hzString::Clear 20:Return hzerr(E_DNS_NOHOST,Unknown Host [%s]\n,hostname) 21:m_Hostname m_nPort memset m_SvrAddr memcpy htons m_SvrAddr 22:(m_nSock=socket(AF_INET,SOCK_STREAM,0))<0 23:Return hzerr(E_INITFAIL,Could not create socket (returns %d, errno=%d),m_nSock,errno) 24:connect sys_rc 25:sys_rc<0 26:Return hzerr(E_HOSTFAIL,Could not connect to host [%s] on port %d (errno=%d),*m_Hostname,m_nPort,errno) 27:!nTimeoutR 28:nTimeoutR 29:!nTimeoutS 30:nTimeoutS 31:rc==E_OK 32:hzTcpClient::SetRecvTimeout rc 33:rc==E_OK 34:hzTcpClient::SetSendTimeout rc 35:rc!=E_OK 36:Return hzerr(rc,Could not set connection timeouts) 37:TLS_client_method sslMethod 38:!sslMethod 39:hzTcpClient::Close 40:Return hzerr(E_INITFAIL,No SSL Client Method issued) 41:SSL_CTX_new sslCtx 42:!sslCtx 43:hzTcpClient::Close 44:SSL_new m_pSSL 45:!m_pSSL 46:Return E_HOSTFAIL 47:SSL_set_fd sys_rc 48:sys_rc!=1 49:Return E_HOSTFAIL 50:SSL_set_tlsext_host_name SSL_set_connect_state SSL_connect sys_rc 51:sys_rc!=1 52:SSL_get_error ShowErrorSSL 53:Return E_HOSTFAIL 54:Return E_OK

Function body:

hzEcode hzTcpClient::ConnectSSL (const char* hostname, unsigned int nPort, unsigned int nTimeoutR, unsigned int nTimeoutS)
{
   _hzfunc("hzTcpClient::ConnectSSL") ;
   static  bool    bBeenHere = false ;
   const SSL_METHOD*   sslMethod = 0;
   SSL_CTX*            sslCtx = 0;
   int32_t     sys_rc ;
   hzEcode     rc = E_OK ;
   if (!bBeenHere)
   {
       #if OPENSSL_VERSION_NUMBER < 0x10100000L
           SSL_library_init();
       #else
           OPENSSL_init_ssl(0,NULL);
       #endif
       bBeenHere = true ;
   }
   if (m_nSock)
   {
       if (m_Hostname == hostname && m_nPort == nPort)
           return E_OK ;
       m_Hostname.Clear() ;
       m_pHost = 0;
       Close() ;
   }
   if (m_Hostname && m_Hostname != hostname)
   {
       m_Hostname = hostname ;
       m_pHost = 0;
   }
   m_pHost = gethostbyname(hostname) ;
   if (!m_pHost)
   {
       threadLog("No Host found\n") ;
       if (h_errno == TRY_AGAIN)       return E_DNS_RETRY ;
       if (h_errno == HOST_NOT_FOUND)  return E_DNS_NOHOST ;
       if (h_errno == NO_RECOVERY)     return E_DNS_FAILED ;
       if (h_errno == NO_DATA || h_errno == NO_ADDRESS)
           return E_DNS_NODATA ;
       m_Hostname.Clear() ;
       return hzerr(E_DNS_NOHOST, "Unknown Host [%s]\n", hostname) ;
   }
   m_Hostname = hostname ;
   m_nPort = nPort ;
   memset(&m_SvrAddr, 0,sizeof(m_SvrAddr)) ;
   m_SvrAddr.sin_family = AF_INET ;
   memcpy(&m_SvrAddr.sin_addr, m_pHost->h_addr, m_pHost->h_length) ;
   m_SvrAddr.sin_port = htons(nPort) ;
   if ((m_nSock = socket(AF_INET, SOCK_STREAM, 0))< 0)
       return hzerr(E_INITFAIL, "Could not create socket (returns %d, errno=%d)", m_nSock, errno) ;
   threadLog("Using socket %d\n", m_nSock) ;
   sys_rc = connect(m_nSock, (SOCKADDR*) &m_SvrAddr, sizeof(m_SvrAddr)) ;
   if (sys_rc < 0)
   {
       threadLog("Could not connect to host (returns %d)", sys_rc) ;
       return hzerr(E_HOSTFAIL, "Could not connect to host [%s] on port %d (errno=%d)", *m_Hostname, m_nPort, errno) ;
   }
   threadLog("Connected\n") ;
   if (!nTimeoutR)     nTimeoutR = 90;
   if (!nTimeoutS)     nTimeoutS = 90;
   if (rc == E_OK)     rc = SetRecvTimeout(nTimeoutR) ;
   if (rc == E_OK)     rc = SetSendTimeout(nTimeoutS) ;
   if (rc != E_OK)
       return hzerr(rc, "Could not set connection timeouts") ;
   threadLog("Socket options set\n") ;
   /*
   **  ** SSL/TLS part
   **      */
   sslMethod = TLS_client_method() ;
   if (!sslMethod)
   {
       Close() ;
       return hzerr(E_INITFAIL, "No SSL Client Method issued") ;
   }
   threadLog("Method set\n") ;
   sslCtx = SSL_CTX_new(sslMethod) ;
   if (!sslCtx)
   {
       Close() ;
       hzerr(E_INITFAIL, "No SSL Structure issued") ;
   }
   threadLog("CTX Created\n") ;
   m_pSSL = SSL_new(sslCtx) ;
   if (!m_pSSL)
   {
       threadLog("Could not allocate SSL structure\n") ;
       return E_HOSTFAIL ;
   }
   threadLog("SSL allocated\n") ;
   /*
   **  if (SSL_CTX_set_cipher_list(sslCtx, "ECDHE-RSA-AES128-GCM-SHA256") <= 0)
   **   {
   **    threadLog("Error setting the cipher list.\n");
   **    return E_HOSTFAIL ;
   **   }
   **   threadLog("Cipers Listed\n") ;
   **      */
   sys_rc = SSL_set_fd(m_pSSL, m_nSock);
   if (sys_rc != 1)
   {
       threadLog("Could not set SSL file descriptor\n") ;
       return E_HOSTFAIL ;
   }
   threadLog("SSL fd set\n") ;
   SSL_set_tlsext_host_name(m_pSSL, *m_Hostname) ;
   SSL_set_connect_state(m_pSSL) ;
   threadLog("SSL set as client\n") ;
   sys_rc = SSL_connect(m_pSSL);
   threadLog("Handshake done\n") ;
   if (sys_rc != 1)
   {
       threadLog("Could not connect: %s\n", ShowErrorSSL(SSL_get_error(m_pSSL, sys_rc))) ;
       return E_HOSTFAIL ;
   }
   threadLog("Connected Secure\n") ;
   /*
   **  Move to separate function or scrap
   **   if (bCheckCert)
   **   {
   **    if (SSL_get_peer_certificate(m_pSSL) != NULL)
   **    {
   **     if (SSL_get_verify_result(m_pSSL) == X509_V_OK)
   **      threadLog("Client verification with SSL_get_verify_result() succeeded.\n") ;
   **     else
   **      threadLog("Client verification with SSL_get_verify_result() failed.\n") ;
   **    }
   **   }
   **      */
   return E_OK ;
}