src/ssl_sock.c
static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
{
	int ret, try, done;

	done = 0;

	if (!conn->xprt_ctx)
		goto out_error;

	if (conn->flags & CO_FL_HANDSHAKE)
		/* a handshake was requested */
		return 0;

	/* send the largest possible block. For this we perform only one call
	 * to send() unless the buffer wraps and we exactly fill the first hunk,
	 * in which case we accept to do it once again.
	 */
	while (buf->o) {
		try = buf->o;

		if (global.tune.ssl_max_record && try > global.tune.ssl_max_record)
			try = global.tune.ssl_max_record;

		/* outgoing data may wrap at the end */
		if (buf->data + try > buf->p)
			try = buf->data + try - buf->p;

		ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
		if (conn->flags & CO_FL_ERROR) {
			/* CO_FL_ERROR may be set by ssl_sock_infocbk */
			goto out_error;
		}
		if (ret > 0) {
			buf->o -= ret;
			done += ret;

			if (likely(buffer_empty(buf)))
				/* optimize data alignment in the buffer */
				buf->p = buf->data;

			/* if the system buffer is full, don't insist */
			if (ret < try)
				break;
		}
		else {
			ret = SSL_get_error(conn->xprt_ctx, ret);
			if (ret == SSL_ERROR_WANT_WRITE) {
				if (SSL_renegotiate_pending(conn->xprt_ctx)) {
					/* handshake is running, and it may need to re-enable write */
					conn->flags |= CO_FL_SSL_WAIT_HS;
					__conn_sock_want_send(conn);
					break;
				}
				/* we need to poll to retry a write later */
				__conn_data_poll_send(conn);
				break;
			}
			else if (ret == SSL_ERROR_WANT_READ) {
				/* handshake is running, and it needs to enable read */
				conn->flags |= CO_FL_SSL_WAIT_HS;
				__conn_sock_want_recv(conn);
				break;
			}
			goto out_error;
		}
	}
	return done;

 out_error:
	/* Clear openssl global errors stack */
	ERR_clear_error();

	conn->flags |= CO_FL_ERROR;
	return done;
}
/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
 * <flags> may contain MSG_MORE to make the system hold on without sending
 * data too fast, but this flag is ignored at the moment.
 * Only one call to send() is performed, unless the buffer wraps, in which case
 * a second call may be performed. The connection's flags are updated with
 * whatever special event is detected (error, empty). The caller is responsible
 * for taking care of those events and avoiding the call if inappropriate. The
 * function does not call the connection's polling update function, so the caller
 * is responsible for this.
 */
Send all pending bytes from buffer  to connection 's socket.
 may contain MSG_MORE to make the system hold on without sending
data too fast, but this flag is ignored at the moment.
Only one call to send() is performed, unless the buffer wraps, in which case
a second call may be performed. The connection's flags are updated with
whatever special event is detected (error, empty). The caller is responsible
for taking care of those events and avoiding the call if inappropriate. The
function does not call the connection's polling update function, so the caller
is responsible for this.
Send all pending bytes from buffer to connection ' s socket . may contain MSG_MORE to make the system hold on without sending data too fast but this flag is ignored at the moment . Only one call to send () is performed unless the buffer wraps in which case a second call may be performed . The connection ' s flags are updated with whatever special event is detected ( error empty ) . The caller is responsible for taking care of those events and avoiding the call if inappropriate . The function does not call the connection ' s polling update function so the caller is responsible for this .
static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
{
	int ret, try, done;
	done = 0;
	if (!conn->xprt_ctx)
		goto out_error;
	if (conn->flags & CO_FL_HANDSHAKE)
		return 0;
	while (buf->o) {
		try = buf->o;
		if (global.tune.ssl_max_record && try > global.tune.ssl_max_record)
			try = global.tune.ssl_max_record;
		if (buf->data + try > buf->p)
			try = buf->data + try - buf->p;
		ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
		if (conn->flags & CO_FL_ERROR) {
			goto out_error;
		}
		if (ret > 0) {
			buf->o -= ret;
			done += ret;
			if (likely(buffer_empty(buf)))
				buf->p = buf->data;
			if (ret < try)
				break;
		}
		else {
			ret = SSL_get_error(conn->xprt_ctx, ret);
			if (ret == SSL_ERROR_WANT_WRITE) {
				if (SSL_renegotiate_pending(conn->xprt_ctx)) {
					conn->flags |= CO_FL_SSL_WAIT_HS;
					__conn_sock_want_send(conn);
					break;
				}
				__conn_data_poll_send(conn);
				break;
			}
			else if (ret == SSL_ERROR_WANT_READ) {
				conn->flags |= CO_FL_SSL_WAIT_HS;
				__conn_sock_want_recv(conn);
				break;
			}
			goto out_error;
		}
	}
	return done;
 out_error:
	ERR_clear_error();
	conn->flags |= CO_FL_ERROR;
	return done;
}
static int ssl_sock_from_buf ( struct connection * conn , struct buffer * buf , int flags ) { int ret , try , done ; done = 0 ; if ( ! conn -> xprt_ctx ) goto out_error ; if ( conn -> flags & CO_FL_HANDSHAKE ) return 0 ; while ( buf -> o ) { try = buf -> o ; if ( global . tune . ssl_max_record && try > global . tune . ssl_max_record ) try = global . tune . ssl_max_record ; if ( buf -> data + try > buf -> p ) try = buf -> data + try - buf -> p ; ret = SSL_write ( conn -> xprt_ctx , bo_ptr ( buf ) , try ) ; if ( conn -> flags & CO_FL_ERROR ) { goto out_error ; } if ( ret > 0 ) { buf -> o -= ret ; done += ret ; if ( likely ( buffer_empty ( buf ) ) ) buf -> p = buf -> data ; if ( ret < try ) break ; } else { ret = SSL_get_error ( conn -> xprt_ctx , ret ) ; if ( ret == SSL_ERROR_WANT_WRITE ) { if ( SSL_renegotiate_pending ( conn -> xprt_ctx ) ) { conn -> flags |= CO_FL_SSL_WAIT_HS ; __conn_sock_want_send ( conn ) ; break ; } __conn_data_poll_send ( conn ) ; break ; } else if ( ret == SSL_ERROR_WANT_READ ) { conn -> flags |= CO_FL_SSL_WAIT_HS ; __conn_sock_want_recv ( conn ) ; break ; } goto out_error ; } } return done ; out_error : ERR_clear_error ( ) ; conn -> flags |= CO_FL_ERROR ; return done ; }
Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Send all pending bytes from buffer <buf > to connection <conn > ' s socket .
/* a handshake was requested */ /* send the largest possible block. For this we perform only one call
	 * to send() unless the buffer wraps and we exactly fill the first hunk,
	 * in which case we accept to do it once again.
	 */ /* outgoing data may wrap at the end */ /* CO_FL_ERROR may be set by ssl_sock_infocbk */ /* optimize data alignment in the buffer */ /* if the system buffer is full, don't insist */ /* handshake is running, and it may need to re-enable write */ /* we need to poll to retry a write later */ /* handshake is running, and it needs to enable read */ /* Clear openssl global errors stack */