]> git.proxmox.com Git - ceph.git/blobdiff - ceph/doc/dev/msgr2.rst
import quincy beta 17.1.0
[ceph.git] / ceph / doc / dev / msgr2.rst
index 585dc34d208cd9a10f7a8f70da33cf303e91d85f..05b6d201ed6a6c0c355256ef64bcacc58bdc17d9 100644 (file)
@@ -104,7 +104,8 @@ Each frame has a 32-byte preamble::
     __le32 segment length
     __le16 segment alignment
   } * 4
-  reserved (2 bytes)
+  __u8 flags
+  reserved (1 byte)
   __le32 preamble crc
 
 An empty frame has one empty segment.  A non-empty frame can have
@@ -114,6 +115,10 @@ empty.
 If there are less than four segments, unused (trailing) segment
 length and segment alignment fields are zeroed.
 
+### Currently supported flags
+
+  1. FRAME_EARLY_DATA_COMPRESSED (see :ref:`msgr-post-compression`)
+
 The reserved bytes are zeroed.
 
 The preamble checksum is CRC32-C.  It covers everything up to
@@ -528,6 +533,64 @@ where epilogue is::
 
 late_status has the same meaning as in msgr2.1-crc mode.
 
+Compression
+-----------
+Compression handshake is implemented using msgr2 feature-based handshaking.
+In this phase, the client will indicate the server if on-wire-compression can be used for message transmitting, 
+in addition to the list of supported compression methods. If on-wire-compression is enabled for both client and server, 
+the server will choose a compression method based on client's request and its' own preferences. 
+Once the handshake is completed, both peers have setup their compression handlers (if desired). 
+
+* TAG_COMPRESSION_REQUEST (client->server): declares compression capabilities and requirements::
+
+    bool  is_compress
+    std::vector<uint32_t> preferred_methods 
+
+  - if the client identifies that both peers support compression feature, it initiates the handshake.
+  - is_compress flag indicates whether the client's configuration is to use compression.
+  - preferred_methods is a list of compression algorithms that are supported by the client.
+
+* TAG_COMPRESSION_DONE (server->client) : determines on compression settings::
+
+    bool is_compress
+    uint32_t  method
+
+  - the server determines whether compression is possible according to its' configuration.
+  - if it is possible, it will pick its' most prioritizied compression method that is also supprorted by the client.
+  - if none exists, it will determine that session between the peers will be handled without compression.
+
+.. ditaa::
+
+           +---------+              +--------+
+           | Client  |              | Server |
+           +---------+              +--------+
+                | compression request    |
+                |----------------------->|
+                |<-----------------------|
+                |   compression done     |
+
+# msgr2.x-secure mode
+
+Combining compression with encryption introduces security implications.
+Compression will not be possible when using secure mode, unless configured specifically by an admin. 
+
+.. _msgr-post-compression:
+
+Post-compression frame format 
+-----------------------------
+Depending on the negotiated connection mode from TAG_COMPRESSION_DONE, the connection is able to accept/send compressed frames or process all frames as decompressed.
+
+# msgr2.x-force mode
+
+All subsequent frames that will be sent via the connection will be compressed if compression requirements are met (e.g, the frames size).
+
+For compressed frames, the sending peer will enable the FRAME_EARLY_DATA_COMPRESSED flag, thus allowing the accepting peer to detect it and decompress the frame.
+
+# msgr2.x-none mode
+
+FRAME_EARLY_DATA_COMPRESSED flag will be disabled in preamble.
+
+
 Message flow handshake
 ----------------------
 
@@ -838,3 +901,56 @@ _____________________________________
                 |                   |
 
 
+.. graphviz::
+   :caption: client side state machine
+
+   digraph lossy_client {
+     node [shape = doublecircle]; "start_connect" "closed";
+     node [shape = oval];
+     start_connect -> banner_connecting [label = "<connected>"];
+     subgraph hello_banner {
+       banner_connecting -> hello_connecting [label = "banner exchange"];
+       hello_connecting -> banner_connecting [label = "hello exchange"];
+       label = "hello banner exchange";
+       color = blue;
+     }
+     banner_connecting -> auth_connecting [label = "<exchange done>"];
+     auth_connecting -> auth_connecting [label = "auth reply more"];
+     auth_connecting -> auth_connecting [label = "auth bad method"];
+     auth_connecting -> auth_connecting_sign [label = "auth done"];
+     auth_connecting_sign -> session_connecting [label = "auth signature"];
+     session_connecting -> wait [label = "wait"];
+     wait -> start_connect [label = "<backoff>"];
+     session_connecting -> closed [label = "ident missing features"];
+     session_connecting -> ready [label = "server ident", tooltip = "set peer_name, peer_addr and connection features"];
+     ready -> ready [label = "keep alive"];
+   }
+
+.. graphviz::
+   :caption: server side state machine
+
+   digraph lossy_server {
+     node [shape = doublecircle]; "start_accept" "closed";
+     node [shape = oval];
+     start_accept -> banner_accepting [label = "<accepted>"];
+     subgraph hello_banner {
+       banner_accepting -> hello_accepting [label = "banner exchange"];
+       hello_accepting -> banner_accepting [label = "hello exchange"];
+       label = "hello banner exchange";
+       color = blue;
+     };
+     banner_accepting -> auth_accepting [label = "<exchange done>"];
+     auth_accepting -> auth_accepting_more [label = "auth_request => 0"];
+     auth_accepting -> auth_accepting_sign [label = "auth_request => 1"];
+     auth_accepting_more -> auth_accepting_more [label = "auth_request => 0"];
+     auth_accepting_more -> auth_accepting_sign [label = "auth_request => 1"];
+     auth_accepting_more -> standby [label = "auth_request => EBUSY"];
+     auth_accepting_more -> auth_accepting_more [label = "auth_request => *"];
+     auth_accepting -> standby [label = "auth_request => EBUSY"];
+     auth_accepting -> auth_accepting [label = "send <auth bad method>"];
+     auth_accepting_sign -> session_accepting [label = "auth signature"];
+     session_accepting -> session_accepting [label = "reconnect"];
+     session_accepting -> closed [label = "ident missing features"];
+     session_accepting -> ready [label = "client ident", tooltip = "set connection features"];
+     ready -> ready [label = "keep alive"];
+   }