in platform/posix/transport/src/openssl_posix.c [868:949]
int32_t Openssl_Send( NetworkContext_t * pNetworkContext,
const void * pBuffer,
size_t bytesToSend )
{
OpensslParams_t * pOpensslParams = NULL;
int32_t bytesSent = 0;
if( !isValidNetworkContext( pNetworkContext ) ||
( pBuffer == NULL ) ||
( bytesToSend == 0 ) )
{
LogError( ( "Parameter check failed: invalid input, pNetworkContext is invalid or pBuffer = %p, bytesToSend = %lu", pBuffer, bytesToSend ) );
bytesSent = -1;
}
else
{
struct pollfd pollFds;
int32_t pollStatus;
pOpensslParams = pNetworkContext->pParams;
/* Initialize the file descriptor. */
pollFds.events = POLLOUT;
pollFds.revents = 0;
/* Set the file descriptor for poll. */
pollFds.fd = pOpensslParams->socketDescriptor;
/* `poll` checks if the socket is ready to send data.
* Note: This is done to avoid blocking on SSL_write()
* when TCP socket is not ready to accept more data for
* network transmission (possibly due to a full TX buffer). */
pollStatus = poll( &pollFds, 1, 0 );
if( pollStatus > 0 )
{
/* SSL write of data. */
bytesSent = ( int32_t ) SSL_write( pOpensslParams->pSsl, pBuffer,
( int32_t ) bytesToSend );
if( bytesSent <= 0 )
{
LogError(
( "Failed to send data over network: SSL_write of OpenSSL failed: "
"ErrorStatus=%s.",
ERR_reason_error_string( SSL_get_error( pOpensslParams->pSsl, bytesSent ) ) ) );
/* As the SSL context is configured for blocking mode, the SSL_write()
* function does not return an SSL_ERROR_WANT_READ or
* SSL_ERROR_WANT_WRITE error code. The SSL_ERROR_WANT_READ and
* SSL_ERROR_WANT_WRITE error codes signify that the write operation can
* be retried. However, in the blocking mode, as the SSL_write()
* function does not return either of the error codes, we cannot retry
* the operation on failure, and thus, this function will never return a
* zero error code.
*/
/* The transport interface requires zero return code only when the send
* operation can be retried to achieve success. Thus, convert a zero
* error code to a negative return value as this cannot be retried. */
if( bytesSent == 0 )
{
bytesSent = -1;
}
}
}
else if( pollStatus < 0 )
{
/* An error occurred while polling. */
LogError( ( "Unable to send TLS data on network: "
"An error occurred while checking availability of TCP socket %d.",
pOpensslParams->socketDescriptor ) );
bytesSent = -1;
}
else
{
/* Socket is not available for sending data. Set return code for retrying send. */
bytesSent = 0;
}
}
return bytesSent;
}