void Connection::PendingWriteSsl::flush() { if (!is_flushed_ && !buffers_.empty()) { SslSession* ssl_session = connection_->ssl_session_.get(); uv_bufs_.reserve(buffers_.size()); for (BufferVec::const_iterator it = buffers_.begin(), end = buffers_.end(); it != end; ++it) { uv_bufs_.push_back(uv_buf_init(const_cast<char*>(it->data()), it->size())); } rb::RingBuffer::Position prev_pos = ssl_session->outgoing().write_position(); encrypt(); FixedVector<uv_buf_t, SSL_ENCRYPTED_BUFS_COUNT> bufs; encrypted_size_ = ssl_session->outgoing().peek_multiple(prev_pos, &bufs); LOG_TRACE("Sending %u encrypted bytes", static_cast<unsigned int>(encrypted_size_)); uv_stream_t* sock_stream = copy_cast<uv_tcp_t*, uv_stream_t*>(&connection_->socket_); uv_write(&req_, sock_stream, bufs.data(), bufs.size(), PendingWriteSsl::on_write); is_flushed_ = true; } }
void Collection::encode_items_uint16(char* buf) const { for (BufferVec::const_iterator i = items_.begin(), end = items_.end(); i != end; ++i) { encode_uint16(buf, i->size()); buf += sizeof(uint16_t); memcpy(buf, i->data(), i->size()); buf += i->size(); } }
void Tuple::encode_buffers(size_t pos, Buffer* buf) const { for (BufferVec::const_iterator i = items_.begin(), end = items_.end(); i != end; ++i) { if (i->size() != 0) { pos = buf->copy(pos, i->data(), i->size()); } else { pos = buf->encode_int32(pos, -1); // null } } }
void BufferCollection::encode(int version, char* buf) const { assert(version == 1 || version == 2); char* pos = buf; for (BufferVec::const_iterator it = bufs_.begin(), end = bufs_.end(); it != end; ++it) { encode_uint16(pos, it->size()); pos += sizeof(uint16_t); memcpy(pos, it->data(), it->size()); pos += it->size(); } }
void Connection::PendingWriteSsl::encrypt() { char buf[SSL_WRITE_SIZE]; size_t copied = 0; size_t offset = 0; size_t total = 0; SslSession* ssl_session = connection_->ssl_session_.get(); BufferVec::const_iterator it = buffers_.begin(), end = buffers_.end(); LOG_TRACE("Copying %u bufs", static_cast<unsigned int>(buffers_.size())); bool is_done = (it == end); while (!is_done) { assert(it->size() > 0); size_t size = it->size(); size_t to_copy = size - offset; size_t available = SSL_WRITE_SIZE - copied; if (available < to_copy) { to_copy = available; } memcpy(buf + copied, it->data() + offset, to_copy); copied += to_copy; offset += to_copy; total += to_copy; if (offset == size) { ++it; offset = 0; } is_done = (it == end); if (is_done || copied == SSL_WRITE_SIZE) { int rc = ssl_session->encrypt(buf, copied); if (rc <= 0 && ssl_session->has_error()) { connection_->notify_error("Unable to encrypt data: " + ssl_session->error_message(), CONNECTION_ERROR_SSL); return; } copied = 0; } } LOG_TRACE("Copied %u bytes for encryption", static_cast<unsigned int>(total)); }
void Connection::PendingWrite::flush() { if (!is_flushed_ && !buffers_.empty()) { UvBufVec bufs; bufs.reserve(buffers_.size()); for (BufferVec::const_iterator it = buffers_.begin(), end = buffers_.end(); it != end; ++it) { bufs.push_back(uv_buf_init(const_cast<char*>(it->data()), it->size())); } is_flushed_ = true; uv_stream_t* sock_stream = copy_cast<uv_tcp_t*, uv_stream_t*>(&connection_->socket_); uv_write(&req_, sock_stream, bufs.data(), bufs.size(), PendingWrite::on_write); } }