/*=========================================================================
 * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
 * This product is protected by U.S. and international copyright
 * and intellectual property laws. Pivotal products are covered by
 * one or more patents listed at http://www.pivotal.io/patents.
 *=========================================================================
 */
#include "TcpSslConn.hpp"

#include "../SystemProperties.hpp"
#include "../DistributedSystem.hpp"
#include "../../cryptoimpl/GFSsl.hpp"

using namespace gemfire;

GFSsl* TcpSslConn::getSSLImpl(ACE_SOCKET sock, const char * pubkeyfile,
		const char * privkeyfile) {
	const char* libName = "cryptoImpl";
	if (m_dll.open(libName, RTLD_NOW | RTLD_GLOBAL, 0) == -1) {
		char msg[1000] = { 0 };
		ACE_OS::snprintf(msg, 1000, "cannot open library: %s", libName);
		LOGERROR(msg);
		throw FileNotFoundException(msg);
	}

	gf_create_SslImpl func = (gf_create_SslImpl) m_dll.symbol(
			"gf_create_SslImpl");
	if (func == NULL) {
		char msg[1000];
		ACE_OS::snprintf(msg, 1000, "cannot find function %s in library gf_create_SslImpl","cryptoImpl");
		LOGERROR(msg);
		throw IllegalStateException(msg);
	}
	// adongre: Added for Ticket #758
	const char *pemPassword = DistributedSystem::getSystemProperties()->sslKeystorePassword();

	return (GFSsl*) func(sock, pubkeyfile, privkeyfile, pemPassword);
}


void TcpSslConn::createSocket(ACE_SOCKET sock)
{
  SystemProperties * props = DistributedSystem::getSystemProperties();
  const char * pubkeyfile = props->sslTrustStore();
  const char * privkeyfile = props->sslKeyStore();
  LOGDEBUG("Creating SSL socket stream");
  m_ssl = getSSLImpl(sock, pubkeyfile, privkeyfile);
}

void  TcpSslConn::listen( ACE_INET_Addr addr, uint32_t waitSeconds )
{
  GF_DEV_ASSERT( m_ssl != NULL );

  int32_t retVal =  m_ssl->listen(addr, waitSeconds);

  if ( retVal == -1 ) {
    char msg[256];
    int32_t lastError = ACE_OS::last_error( );
    if ( lastError == ETIME || lastError == ETIMEDOUT ) {
      /* adongre
       * Coverity - II
       * CID 29271: Calling risky function (SECURE_CODING)[VERY RISKY]. Using "sprintf" can cause a 
       * buffer overflow when done incorrectly. Because sprintf() assumes an arbitrarily long string, 
       * callers must be careful not to overflow the actual space of the destination. 
       * Use snprintf() instead, or correct precision specifiers. 
       * Fix : using ACE_OS::snprintf
       */
      //sprintf( msg, "TcpSslConn::listen Attempt to listen timed out after %d seconds.", waitSeconds );
      ACE_OS::snprintf( msg, 256, "TcpSslConn::listen Attempt to listen timed out after %d seconds.", waitSeconds );
      throw TimeoutException( msg );
    }
    //sprintf( msg, "TcpSslConn::listen failed with errno: %d: %s", lastError, ACE_OS::strerror(lastError) );
    ACE_OS::snprintf( msg, 255, "TcpSslConn::listen failed with errno: %d: %s", lastError, ACE_OS::strerror(lastError) );
    throw GemfireIOException( msg );
  }
}

void TcpSslConn::connect()
{
  GF_DEV_ASSERT( m_ssl != NULL );

  ACE_OS::signal( SIGPIPE, SIG_IGN ); // Ignore broken pipe

  //m_ssl->init();

  uint32_t waitSeconds = m_waitSeconds;

  //passing waittime as microseconds
  if(DistributedSystem::getSystemProperties()->readTimeoutUnitInMillis())
    waitSeconds = waitSeconds * 1000;
  else
    waitSeconds = waitSeconds * (1000 * 1000);

  LOGDEBUG("Connecting SSL socket stream to %s:%d waiting %d sec",
    m_addr.get_host_name(), m_addr.get_port_number(), m_waitSeconds);

  int32_t retVal = m_ssl->connect(m_addr, waitSeconds);

  if ( retVal == -1 ) {
    char msg[256];
    int32_t lastError = ACE_OS::last_error( );
    if ( lastError == ETIME || lastError == ETIMEDOUT ) {
      ACE_OS::snprintf(msg, 256, "TcpSslConn::connect Attempt to connect timed out after %d seconds.", m_waitSeconds);
      // this is only called by constructor, so we must delete m_ssl
      GF_SAFE_DELETE(m_ssl);
      throw TimeoutException( msg );
    }
    ACE_OS::snprintf(msg, 256, "TcpSslConn::connect failed with errno: %d: %s",
        lastError, ACE_OS::strerror(lastError));
    // this is only called by constructor, so we must delete m_ssl
    GF_SAFE_DELETE(m_ssl);
    throw GemfireIOException( msg );
  }
}

void TcpSslConn::close( )
{
  if ( m_ssl != NULL ) {
    m_ssl->close( );
    gf_destroy_SslImpl func = (gf_destroy_SslImpl) m_dll.symbol("gf_destroy_SslImpl");
    func((void*)m_ssl);
    m_ssl = NULL;
  }
}

int32_t TcpSslConn::socketOp( TcpConn::SockOp op, char* buff, int32_t len,
    uint32_t waitSeconds )
{
  
{
  GF_DEV_ASSERT( m_ssl != NULL );
  GF_DEV_ASSERT( buff != NULL );

#if GF_DEVEL_ASSERTS == 1
  if ( len <= 0 ) {
    LOGERROR( "TcpSslConn::socketOp called with a length of %d specified. "
        "No operation performed.", len );
    GF_DEV_ASSERT( false );
  }
#endif
  //passing wait time as micro seconds
  ACE_Time_Value waitTime( 0, waitSeconds );
  ACE_Time_Value endTime( ACE_OS::gettimeofday( ) + waitTime );
  ACE_Time_Value sleepTime( 0, 100 );
  size_t readLen = 0;
  ssize_t retVal;
  bool errnoSet = false;

  int32_t sendlen = len;
  int32_t totalsend = 0;

  while(len > 0 && waitTime > ACE_Time_Value::zero ) 
  {
    if(len > m_chunkSize)
    {
      sendlen = m_chunkSize;
      len -= m_chunkSize;
    }
    else
    {
      sendlen = len;
      len = 0;
    }
    do {
      if ( op == SOCK_READ ) {
        retVal = m_ssl->recv( buff, sendlen, &waitTime, &readLen );
      } else {
        retVal = m_ssl->send( buff, sendlen, &waitTime, &readLen );
      }
      sendlen -= static_cast<int32_t> (readLen);
      totalsend += static_cast<int32_t> (readLen);
      if( retVal < 0 ) {
        int32_t lastError = ACE_OS::last_error( );
        if ( lastError == EAGAIN ) {
          ACE_OS::sleep( sleepTime );
        } else {
          errnoSet = true;
          break;
        }
      } else if ( retVal == 0 && readLen == 0 ) {
        ACE_OS::last_error( EPIPE );
        errnoSet = true;
        break;
      }
      
      buff += readLen;
      
      waitTime = endTime - ACE_OS::gettimeofday( );      
      if( waitTime <= ACE_Time_Value::zero ) 
        break;
    } while ( sendlen > 0  );
    if(errnoSet)
      break;
  }

  if ( len > 0 && !errnoSet ) {
    ACE_OS::last_error( ETIME );
  }

  GF_DEV_ASSERT( len >= 0 );
  return totalsend;
}

}

uint16_t TcpSslConn::getPort( )
{
  GF_DEV_ASSERT( m_ssl != NULL );

  ACE_INET_Addr localAddr;
  m_ssl->getLocalAddr(*(ACE_Addr *)&localAddr);
  return localAddr.get_port_number();
}
