Implement OSD TLS support

This commit is contained in:
Vitaliy Filippov
2026-04-27 15:24:44 +03:00
parent e42b812323
commit d0a4ac914b
15 changed files with 1267 additions and 554 deletions
+414 -241
View File
@@ -5,6 +5,342 @@
#include <limits.h>
#include "messenger.h"
#ifdef WITH_OPENSSL
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#endif
#define RDR_TLS 1
#define RDR_XTS 2
#define RDR_NO_CSUM 4
class msgr_op_reader_t
{
public:
virtual bool read(uint8_t *dst, size_t dst_len, int flags = 0) = 0;
};
class copy_op_reader_t: public msgr_op_reader_t
{
protected:
osd_messenger_t* msgr;
osd_client_t* cl;
size_t from;
uint8_t *curbuf;
size_t bufsize;
size_t done;
public:
copy_op_reader_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
msgr(msgr), cl(cl), from(cl->read_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
{}
void reset()
{
from = cl->read_op_pos;
}
bool read(uint8_t *dst, size_t dst_len, int flags = 0) override
{
if (from >= dst_len)
{
from -= dst_len;
return true;
}
if (flags & RDR_XTS)
{
msgr->op_decrypted_copy_buf(cl, curbuf, bufsize, dst, dst_len, from, done);
}
else
{
size_t n = dst_len-from;
if (n > bufsize-done)
n = bufsize-done;
if (!n)
return false;
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
{
// data may be skipped if dst == NULL but checksum is still calculated
XXH3_64bits_update(cl->read_csum_state, curbuf+done, n);
}
// Here, dst == NULL is allowed
if (dst != NULL)
memcpy(dst+from, curbuf+done, n);
done += n;
cl->read_op_pos += n;
from += n;
}
if (from < dst_len)
return false;
from = 0;
return true;
}
size_t get_done()
{
return done;
}
};
class ssl_op_reader_t: public msgr_op_reader_t
{
osd_messenger_t* msgr;
osd_client_t* cl;
size_t from;
uint8_t *curbuf;
size_t bufsize;
size_t done;
public:
ssl_op_reader_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
msgr(msgr), cl(cl), from(cl->read_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
{
}
void reset()
{
from = cl->read_op_pos;
}
void buffer_encrypted()
{
while (done < bufsize)
{
if (cl->ssl_read_record_size < sizeof(msgr_tls_record_hdr_t))
{
size_t n = bufsize-done;
if (n > sizeof(msgr_tls_record_hdr_t)-cl->ssl_read_record_size)
n = sizeof(msgr_tls_record_hdr_t)-cl->ssl_read_record_size;
memcpy(((uint8_t*)&cl->ssl_read_record) + cl->ssl_read_record_size, curbuf+done, n);
done += n;
cl->ssl_read_record_size += n;
if (done >= bufsize)
return;
}
if (cl->ssl_read_record.encrypted)
{
size_t n = cl->ssl_read_record.size;
if (n > bufsize-done)
n = bufsize-done;
// Buffer all encrypted data
// FIXME Limit the amount of buffered data
int r = BIO_write(cl->write_to_ssl, curbuf+done, n);
assert(r == n);
done += n;
cl->ssl_read_record.size -= n;
if (!cl->ssl_read_record.size)
cl->ssl_read_record_size = 0;
}
else
{
// Unencrypted data
break;
}
}
}
bool read(uint8_t *dst, size_t dst_len, int flags) override
{
if (from >= dst_len)
{
// Skip
from -= dst_len;
return true;
}
size_t n = dst_len-from;
if (!(flags & RDR_TLS) || !cl->ssl_cli)
{
if (cl->ssl_cli && (cl->ssl_read_record_size < sizeof(msgr_tls_record_hdr_t) ||
cl->ssl_read_record.size < n || cl->ssl_read_record.encrypted))
{
fprintf(stderr, "Client %ju non-TLS data is too short, disconnecting\n", cl->client_id);
cl->io_error = true;
return false;
}
if (n > bufsize-done)
n = bufsize-done;
if (flags & RDR_XTS)
{
size_t prev = done;
msgr->op_decrypted_copy_buf(cl, curbuf, bufsize, dst, dst_len, from, done);
n = 0;
cl->ssl_read_record.size -= (done-prev);
}
else
{
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
{
// data may be skipped if dst == NULL but checksum is still calculated
XXH3_64bits_update(cl->read_csum_state, curbuf+done, n);
}
// Here, dst == NULL is allowed
if (dst != NULL)
memcpy(dst+from, curbuf+done, n);
done += n;
cl->ssl_read_record.size -= n;
}
if (!cl->ssl_read_record.size)
cl->ssl_read_record_size = 0;
}
else
{
// Here, dst == NULL is not allowed
assert(dst != NULL);
buffer_encrypted();
if (!cl->ssl_handshake_done)
{
if (!msgr->ssl_do_handshake(cl))
return false;
if (cl->write_state == 0)
{
// SSL_ERROR_WANT_WRITE is absolutely non-informative with memory BIO, it basically never happens
// So we have to check memory BIO for outstanding data
char *bio_buf = NULL;
size_t bio_sz = BIO_get_mem_data(cl->read_from_ssl, &bio_buf);
if (bio_sz > 0)
{
cl->write_state = CL_WRITE_READY;
msgr->write_ready_clients.push_back(cl->client_id);
}
}
}
int ok = SSL_read_ex(cl->ssl_cli, dst+from, n, &n);
if (!ok)
{
ok = SSL_get_error(cl->ssl_cli, ok);
if (ok == SSL_ERROR_ZERO_RETURN)
{
fprintf(stderr, "Client %ju TLS disconnected\n", cl->client_id);
cl->io_error = true;
}
else if (ok != 0 && ok != SSL_ERROR_WANT_READ && ok != SSL_ERROR_WANT_WRITE)
{
fprintf(stderr, "Client %ju TLS read error: %s. Disconnecting client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
cl->io_error = true;
}
return false;
}
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
{
XXH3_64bits_update(cl->read_csum_state, dst+from, n);
}
}
cl->read_op_pos += n;
from += n;
if (from < dst_len)
{
return false;
}
from = 0;
return true;
}
size_t get_done()
{
return done;
}
};
class get_op_reader_t: public msgr_op_reader_t
{
osd_client_t* cl;
size_t from;
bool mpos;
public:
get_op_reader_t(osd_messenger_t* msgr, osd_client_t* cl):
cl(cl), from(cl->read_op_pos), mpos(false)
{
if (cl->read_op->op_type == OSD_OP_OUT &&
cl->read_op->reply.hdr.opcode == OSD_OP_READ &&
cl->read_op->reply.hdr.retval > 0)
{
// When we recvmsg directly into the operation without copying,
// we need some place for all buffers, so we allocate temporary
// buffers for all skipped parts
alloc_temp_buffers(cl->read_op);
}
}
void alloc_temp_buffers(osd_op_t *op)
{
size_t total_skip = 0;
for (int j = 0; j < op->iov.count; j++)
{
if (!op->iov.buf[j].iov_base)
{
total_skip += op->iov.buf[j].iov_len;
}
}
if (!total_skip)
{
return;
}
assert(!op->rmw_buf);
op->rmw_buf = malloc_or_die(total_skip);
total_skip = 0;
for (int j = 0; j < op->iov.count; j++)
{
if (!op->iov.buf[j].iov_base)
{
op->iov.buf[j].iov_base = (uint8_t*)op->rmw_buf + total_skip;
total_skip += op->iov.buf[j].iov_len;
}
}
}
bool read(uint8_t *dst, size_t dst_len, int flags) override
{
if (from >= dst_len)
{
// Skip
from -= dst_len;
return true;
}
if ((flags & RDR_TLS) && cl->ssl_cli)
{
// Can't inplace read TLS data
return false;
}
if (cl->recv_list.size() >= IOV_MAX)
{
return false;
}
if ((flags & RDR_XTS) && cl->read_op->enc && !mpos)
{
mpos = true;
cl->read_op_inline_decrypt_pos = cl->read_op_pos;
cl->read_op_pos = cl->read_op_inline_decrypt_in + OSD_PACKET_SIZE + cl->read_op->reply.rw.bitmap_len;
from = cl->read_op_inline_decrypt_in;
}
if (cl->ssl_cli)
{
if (cl->ssl_read_record_size < sizeof(msgr_tls_record_hdr_t))
{
return false;
}
if (cl->ssl_read_record.size < dst_len-from || cl->ssl_read_record.encrypted)
{
fprintf(stderr, "Client %ju non-TLS data is too short, disconnecting\n", cl->client_id);
cl->io_error = true;
return false;
}
cl->ssl_read_record.size -= (dst_len-from);
if (!cl->ssl_read_record.size)
cl->ssl_read_record_size = 0;
}
cl->recv_list.push_back((iovec){ dst+from, dst_len-from });
cl->recv_flags.push_back(flags);
cl->read_op_pos += dst_len-from;
from = 0;
return true;
}
};
void osd_messenger_t::read_requests()
{
for (int i = 0; i < read_ready_clients.size(); i++)
@@ -17,9 +353,17 @@ void osd_messenger_t::read_requests()
continue;
}
auto cl = cl_it->second;
if (cl->read_op && cl->read_op_size-(cl->read_op_pos-OSD_PACKET_SIZE) >= receive_buffer_size)
if (cl->read_op && cl->read_op_pos >= OSD_PACKET_SIZE && cl->read_op_size-(cl->read_op_pos-OSD_PACKET_SIZE) >= receive_buffer_size)
{
op_get_read_buffers(cl, cl->recv_list);
get_op_reader_t rdr(this, cl);
if (!op_read_from(cl, rdr))
{
if (cl->io_error)
{
stop_client(cl->client_id);
continue;
}
}
}
if (!cl->recv_list.size())
{
@@ -37,7 +381,7 @@ void osd_messenger_t::read_requests()
}
assert(!cl->read_op || cl->read_op_pos < OSD_PACKET_SIZE || cl->read_op_size >= (cl->read_op_pos-OSD_PACKET_SIZE));
cl->refs++;
if (ringloop && !use_sync_send_recv)
if (!use_sync_send_recv)
{
auto iothread = iothreads.size() ? iothreads[cl->peer_fd % iothreads.size()] : NULL;
io_uring_sqe sqe_local;
@@ -65,7 +409,7 @@ void osd_messenger_t::read_requests()
}
else
{
int result = recvmsg(cl->peer_fd, &cl->read_msg, 0);
int result = recvmsg(cl->peer_fd, &cl->read_msg, cl->recv_list.size() ? MSG_WAITALL : 0);
if (result < 0)
{
result = -errno;
@@ -125,7 +469,7 @@ out_wakeup:
while (i < cl->recv_list.size() && result >= cl->recv_list[i].iov_len)
{
if (cl->read_csum_state && cl->recv_list[i].iov_len > 0 &&
i != cl->recv_list.size()-1) // skip the checksum itself
!(cl->recv_flags[i] & RDR_NO_CSUM))
{
XXH3_64bits_update(cl->read_csum_state, cl->recv_list[i].iov_base, cl->recv_list[i].iov_len);
}
@@ -142,10 +486,10 @@ out_wakeup:
full_read = true;
}
cl->recv_list.erase(cl->recv_list.begin(), cl->recv_list.begin()+i);
if (!cl->recv_list.size())
cl->recv_flags.erase(cl->recv_flags.begin(), cl->recv_flags.begin()+i);
if (!handle_finished_op(cl))
{
if (!handle_finished_op(cl))
goto out_wakeup;
goto out_wakeup;
}
}
}
@@ -191,8 +535,8 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
cl->ping_time_remaining = 0;
cl->idle_time_remaining = osd_idle_timeout;
// Compose operation(s) from the buffer
size_t done = 0;
while (done < bufsize)
ssl_op_reader_t rdr(this, cl, curbuf, bufsize);
while (true)
{
if (!cl->read_op)
{
@@ -203,34 +547,25 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
cl->read_op_size = 0;
cl->read_op_inline_decrypt_in = 0;
cl->read_op_inline_decrypt_pos = (size_t)-1;
if (cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
{
if (!cl->read_csum_state)
cl->read_csum_state = XXH3_createState();
XXH3_64bits_reset(cl->read_csum_state);
}
rdr.reset();
}
if (cl->read_op_pos < OSD_PACKET_SIZE)
if (!cl->read_op_pos && (cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD))
{
int len = OSD_PACKET_SIZE - cl->read_op_pos;
if (len > bufsize-done)
len = bufsize-done;
memcpy(cl->read_op->req.buf + cl->read_op_pos, curbuf+done, len);
done += len;
cl->read_op_pos += len;
if (cl->read_op_pos < OSD_PACKET_SIZE)
return true;
if (!handle_hdr(cl))
if (!cl->read_csum_state)
cl->read_csum_state = XXH3_createState();
XXH3_64bits_reset(cl->read_csum_state);
}
if (!op_read_from(cl, rdr) || !handle_finished_op(cl))
{
if (cl->io_error)
{
stop_client(cl->client_id);
return false;
}
}
if (!op_copy_from(cl, curbuf, bufsize, done))
{
return false;
break;
}
}
assert(rdr.get_done() == bufsize);
return true;
}
@@ -404,281 +739,118 @@ bool osd_messenger_t::allocate_reply_buffers(osd_client_t *cl, osd_op_t *op)
return true;
}
bool osd_messenger_t::op_copy_from(osd_client_t *cl, uint8_t *src, size_t src_len, size_t & done)
bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
{
osd_op_t *op = cl->read_op;
size_t from = cl->read_op_pos-OSD_PACKET_SIZE;
auto op_read_buf = [&](uint8_t *dst, size_t dst_len, bool skip_csum = false)
bool hdr = (cl->read_op_pos < OSD_PACKET_SIZE);
if (hdr || op->op_type == OSD_OP_IN)
{
if (from < dst_len)
{
size_t n = dst_len-from;
if (n > src_len-done)
n = src_len-done;
if (cl->read_csum_state && !skip_csum)
{
// it may be skipped if !dst but checksum is still calculated
XXH3_64bits_update(cl->read_csum_state, src+done, n);
}
if (dst)
memcpy(dst+from, src+done, n);
else
assert(!this->osd_num); // NULL buffers are only used by clients
done += n;
cl->read_op_pos += n;
from += n;
if (from < dst_len)
return false;
from = 0;
}
else
from -= dst_len;
return true;
};
if (op->op_type == OSD_OP_IN)
{
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->req.sec_rw.attr_len))
return true;
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_rw.len))
return true;
}
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_stab.len))
return true;
}
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_read_bmp.len))
return true;
}
else if (op->req.hdr.opcode == OSD_OP_WRITE)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.rw.len))
return true;
}
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.show_conf.json_len))
return true;
}
}
else
{
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
{
if (op->reply.sec_rw.attr_len > 0)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len))
return true;
}
if (op->reply.hdr.retval > 0)
{
for (int i = 0; i < op->iov.count; i++)
if (!op_read_buf((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len))
return true;
}
}
else if (op->reply.hdr.opcode == OSD_OP_READ)
{
if (op->reply.rw.bitmap_len > 0)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->reply.rw.bitmap_len))
return true;
}
if (op->reply.hdr.retval > 0)
{
if (op->enc)
{
if (!op_decrypted_copy_data_from(cl, src, src_len, from, done))
return true;
}
else
{
for (int i = 0; i < op->iov.count; i++)
if (!op_read_buf((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len))
return true;
}
}
}
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
{
if (!op_read_buf((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval))
return true;
}
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
{
if (!op_read_buf((uint8_t*)op->buf, op->reply.hdr.retval))
return true;
}
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
{
if (!op_read_buf((uint8_t*)op->buf, op->reply.describe.result_bytes))
return true;
}
}
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
{
if (!op_read_buf((uint8_t*)&op->csum, 8, true))
return true;
}
return handle_finished_op(cl);
}
void osd_messenger_t::op_get_read_buffers(osd_client_t *cl, std::vector<iovec> & lst)
{
osd_op_t *op = cl->read_op;
size_t from = cl->read_op_pos-OSD_PACKET_SIZE;
size_t done = 0;
auto op_read_buf = [&](uint8_t *dst, size_t dst_len)
{
if (lst.size() >= IOV_MAX)
if (!rdr.read(op->req.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
return false;
if (from < dst_len)
if (hdr)
{
lst.push_back((iovec){ .iov_base = dst+from, .iov_len = dst_len-from });
cl->read_op_pos += dst_len-from;
done += dst_len-from;
from = 0;
if (!handle_hdr(cl))
return false;
op = cl->read_op;
if (op->op_type == OSD_OP_OUT)
goto switched_type;
}
else
from -= dst_len;
return true;
};
if (op->op_type == OSD_OP_IN)
{
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->req.sec_rw.attr_len))
return;
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_rw.len))
return;
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_TLS))
return false;
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
return false;
}
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_stab.len))
return;
if (!rdr.read((uint8_t*)op->buf, op->req.sec_stab.len, RDR_TLS))
return false;
}
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.sec_read_bmp.len))
return;
if (!rdr.read((uint8_t*)op->buf, op->req.sec_read_bmp.len, RDR_TLS))
return false;
}
else if (op->req.hdr.opcode == OSD_OP_WRITE)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.rw.len))
return;
if (!rdr.read((uint8_t*)op->buf, op->req.rw.len, 0))
return false;
}
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
{
if (!op_read_buf((uint8_t*)op->buf, op->req.show_conf.json_len))
return;
if (!rdr.read((uint8_t*)op->buf, op->req.show_conf.json_len, RDR_TLS))
return false;
}
}
else
{
if (!rdr.read(op->reply.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
return false;
switched_type:
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
{
if (op->reply.sec_rw.attr_len > 0)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len))
return;
if (!rdr.read((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, RDR_TLS))
return false;
}
if (op->reply.hdr.retval > 0)
{
for (int i = 0; i < op->iov.count; i++)
if (!op_read_buf((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len))
return;
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, 0))
return false;
}
}
else if (op->reply.hdr.opcode == OSD_OP_READ)
{
if (op->reply.rw.bitmap_len > 0)
{
if (!op_read_buf((uint8_t*)op->bitmap, op->reply.rw.bitmap_len))
return;
if (!rdr.read((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, RDR_TLS))
return false;
}
if (op->reply.hdr.retval > 0)
{
if (op->enc)
{
cl->read_op_inline_decrypt_pos = cl->read_op_pos;
cl->read_op_pos = cl->read_op_inline_decrypt_in + OSD_PACKET_SIZE + op->reply.rw.bitmap_len;
from = cl->read_op_inline_decrypt_in;
}
for (int i = 0; i < op->iov.count; i++)
{
if (!op->iov.buf[i].iov_base)
{
// When we recvmsg directly into the operation without copying,
// we need some place for all buffers, so we allocate temporary
// buffers for all skipped parts
op_alloc_temp_buffers(op, i);
}
if (!op_read_buf((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len))
return;
}
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, (op->enc ? RDR_XTS : 0)))
return false;
}
}
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
{
if (!op_read_buf((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval))
return;
if (!rdr.read((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval, RDR_TLS))
return false;
}
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
{
if (!op_read_buf((uint8_t*)op->buf, op->reply.hdr.retval))
return;
if (!rdr.read((uint8_t*)op->buf, op->reply.hdr.retval, RDR_TLS))
return false;
}
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
{
if (!op_read_buf((uint8_t*)op->buf, op->reply.describe.result_bytes))
return;
if (!rdr.read((uint8_t*)op->buf, op->reply.describe.result_bytes, RDR_TLS))
return false;
}
}
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
{
if (!op_read_buf((uint8_t*)&op->csum, 8))
return;
}
}
void osd_messenger_t::op_alloc_temp_buffers(osd_op_t *op, int i)
{
size_t total_skip = 0;
for (int j = i; j < op->iov.count; j++)
{
if (!op->iov.buf[j].iov_base)
{
total_skip += op->iov.buf[j].iov_len;
}
}
assert(total_skip);
assert(!op->rmw_buf);
op->rmw_buf = malloc_or_die(total_skip);
total_skip = 0;
for (int j = i; j < op->iov.count; j++)
{
if (!op->iov.buf[j].iov_base)
{
op->iov.buf[j].iov_base = (uint8_t*)op->rmw_buf + total_skip;
total_skip += op->iov.buf[j].iov_len;
}
if (!rdr.read((uint8_t*)&op->csum, 8, RDR_TLS|RDR_NO_CSUM))
return false;
}
assert(cl->read_op_pos == cl->read_op_size+OSD_PACKET_SIZE);
return true;
}
bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
{
if (cl->read_op_pos < cl->read_op_size+OSD_PACKET_SIZE)
{
return true;
}
osd_op_t *op = cl->read_op;
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
@@ -688,7 +860,7 @@ bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
{
fprintf(stderr, "Client %ju checksum mismatch for received data: expected %016jx, got %016jx, disconnecting client\n",
cl->client_id, op->csum, real_csum);
stop_client(cl->client_id);
cl->io_error = true;
return false;
}
}
@@ -719,6 +891,7 @@ bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
(tv_end.tv_nsec - op->tv_begin.tv_nsec)/1000
);
}
op_decrypt_free(cl);
set_immediate_ops.push_back(op);
cl->read_op = NULL;
return true;