From: Radoslaw Zarzynski Date: Tue, 12 Feb 2019 15:30:30 +0000 (+0100) Subject: msg/async: transmit V2 messages with new preable format. X-Git-Tag: v14.1.1~157^2~37 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a0a7d551fdbffe5431c019cd94cd549f955a9228;p=ceph.git msg/async: transmit V2 messages with new preable format. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index c5657128826..fdcdae74b6c 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -1,6 +1,8 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + #include "ProtocolV2.h" #include "AsyncMessenger.h" @@ -104,32 +106,92 @@ static void alloc_aligned_buffer(bufferlist &data, unsigned len, unsigned off) { * Protocol V2 Frame Structures **/ -static constexpr uint32_t FRAME_PREAMBLE_SIZE = 4 * sizeof(__le32); +static constexpr uint8_t CRYPTO_BLOCK_SIZE { 16 }; + +struct segment_t { + __le32 length; + __le16 alignment; +} __attribute__((packed)); + +struct preamble_main_t { + static constexpr std::size_t MAX_NUM_SEGMENTS = 2; + + __le16 crc; + __u8 tag; + __u8 num_segments; + std::array segments; +} __attribute__((packed)); +static_assert(sizeof(preamble_main_t) == CRYPTO_BLOCK_SIZE); +static_assert(std::is_standard_layout::value); + +struct preamble_extra_t { + static constexpr std::size_t MAX_NUM_SEGMENTS = 2; + std::array segments; + std::array<__u8, 4> always_padding; +} __attribute__((packed)); +static_assert(sizeof(preamble_extra_t) == CRYPTO_BLOCK_SIZE); +static_assert(std::is_standard_layout::value); + + +static constexpr uint32_t FRAME_PREAMBLE_SIZE = CRYPTO_BLOCK_SIZE; + template struct Frame { protected: ceph::bufferlist payload; ceph::bufferlist::contiguous_filler preamble_filler; - void fill_preamble(const uint32_t frame_size) { - __le32 rest_len = frame_size - FRAME_PREAMBLE_SIZE; - preamble_filler.copy_in(sizeof(rest_len), - reinterpret_cast(&rest_len)); - - __le32 tag = static_cast(T::tag); - preamble_filler.copy_in(sizeof(tag), - reinterpret_cast(&tag)); - uint32_t db = 0xbaadf00d; - preamble_filler.copy_in(sizeof(tag), - reinterpret_cast(&db)); - ceph_assert(tag != 0); + void fill_preamble( + const std::initializer_list main_segments, + const std::initializer_list extra_segments) + { + ceph_assert( + std::size(main_segments) <= preamble_main_t::MAX_NUM_SEGMENTS); + ceph_assert( + std::size(extra_segments) <= preamble_extra_t::MAX_NUM_SEGMENTS); + + // Craft the main preamble. It's always present regardless of the number + // of segments message is composed from. This doesn't apply to extra one + // as it's optional -- if there is up to 2 segments, we'll never transmit + // preamble_extra_t; + preamble_main_t main_preamble; + // TODO: we might fill/pad with pseudo-random data. + ::memset(&main_preamble, 0, sizeof(main_preamble)); + + main_preamble.num_segments = \ + std::size(main_segments) + std::size(extra_segments); + main_preamble.tag = static_cast<__u8>(T::tag); + std::copy(std::cbegin(main_segments), std::cend(main_segments), + std::begin(main_preamble.segments)); + main_preamble.crc = 0; + + ceph_assert(main_preamble.tag != 0); + + if (std::empty(extra_segments)) { + preamble_filler.copy_in(sizeof(main_preamble), + reinterpret_cast(&main_preamble)); + } else { + preamble_extra_t extra_preamble; + // TODO: we might fill/pad with pseudo-random data. + ::memset(&extra_preamble, 0, sizeof(extra_preamble)); + + std::copy(std::cbegin(extra_segments), std::cend(extra_segments), + std::begin(extra_preamble.segments)); + //main_preamble.crc = \ + // ceph::crc16(main_preamble.crc, &extra_preamble, sizeof(extra_preamble); + + preamble_filler.copy_in(sizeof(main_preamble), + reinterpret_cast(&main_preamble)); + preamble_filler.copy_in(sizeof(extra_preamble), + reinterpret_cast(&extra_preamble)); + } } public: Frame() : preamble_filler(payload.append_hole(FRAME_PREAMBLE_SIZE)) {} ceph::bufferlist &get_buffer() { - fill_preamble(payload.length()); + fill_preamble({ segment_t{ payload.length(), 1} }, {}); return payload; } @@ -300,7 +362,7 @@ struct SignedEncryptedFrame : public PayloadFrame { auto exp_size = this->payload.length() + 16; // FIXME: plainsize -> ciphersize; for AES-GCM they are equall apart // from auth tag size - this->fill_preamble(this->payload.length() + 16); + //this->fill_preamble(this->payload.length() + 16); protocol.session_stream_handlers.tx->authenticated_encrypt_update( std::move(this->payload)); @@ -465,7 +527,8 @@ struct MessageHeaderFrame const uint32_t data_len) : PayloadFrame(msghdr) { - fill_preamble(this->payload.length() + front_len + middle_len + data_len + 16); + // FIXME: plainsize -> ciphersize; for AES-GCM they are equall apart from auth tag size + //fill_preamble(this->payload.length() + front_len + middle_len + data_len + 16); } MessageHeaderFrame(ceph::bufferlist&& text) diff --git a/src/msg/async/ProtocolV2.h b/src/msg/async/ProtocolV2.h index 8589015d612..bec10174f89 100644 --- a/src/msg/async/ProtocolV2.h +++ b/src/msg/async/ProtocolV2.h @@ -47,7 +47,7 @@ private: } public: - enum class Tag : uint32_t { + enum class Tag : __u8 { HELLO = 1, AUTH_REQUEST, AUTH_BAD_METHOD,