]> git.proxmox.com Git - ceph.git/blame - ceph/src/messages/MForward.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / messages / MForward.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 * Client requests often need to get forwarded from some monitor
14 * to the leader. This class encapsulates the original message
15 * along with the client's caps so the leader can do proper permissions
16 * checking.
17 */
18
19#ifndef CEPH_MFORWARD_H
20#define CEPH_MFORWARD_H
21
22#include "msg/Message.h"
23#include "mon/MonCap.h"
24#include "include/encoding.h"
25#include "include/stringify.h"
26
f67539c2 27class MForward final : public Message {
11fdf7f2 28public:
7c673cae 29 uint64_t tid;
11fdf7f2
TL
30 uint8_t client_type;
31 entity_addrvec_t client_addrs;
32 entity_addr_t client_socket_addr;
7c673cae
FG
33 MonCap client_caps;
34 uint64_t con_features;
35 EntityName entity_name;
36 PaxosServiceMessage *msg; // incoming or outgoing message
37
f67539c2
TL
38 std::string msg_desc; // for operator<< only
39
11fdf7f2
TL
40 static constexpr int HEAD_VERSION = 4;
41 static constexpr int COMPAT_VERSION = 4;
7c673cae 42
9f95a23c 43 MForward() : Message{MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION},
7c673cae 44 tid(0), con_features(0), msg(NULL) {}
7c673cae
FG
45 MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat,
46 const MonCap& caps) :
9f95a23c 47 Message{MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION},
7c673cae 48 tid(t), client_caps(caps), msg(NULL) {
11fdf7f2
TL
49 client_type = m->get_source().type();
50 client_addrs = m->get_source_addrs();
51 if (auto con = m->get_connection()) {
52 client_socket_addr = con->get_peer_socket_addr();
53 }
7c673cae
FG
54 con_features = feat;
55 msg = (PaxosServiceMessage*)m->get();
56 }
57private:
f67539c2 58 ~MForward() final {
7c673cae
FG
59 if (msg) {
60 // message was unclaimed
61 msg->put();
62 msg = NULL;
63 }
64 }
65
66public:
67 void encode_payload(uint64_t features) override {
11fdf7f2
TL
68 using ceph::encode;
69 if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
70 header.version = 3;
71 header.compat_version = 3;
72 encode(tid, payload);
73 entity_inst_t client;
74 client.name = entity_name_t(client_type, -1);
75 client.addr = client_addrs.legacy_addr();
76 encode(client, payload, features);
77 encode(client_caps, payload, features);
78 // Encode client message with intersection of target and source
79 // features. This could matter if the semantics of the encoded
80 // message are changed when reencoding with more features than the
81 // client had originally. That should never happen, but we may as
82 // well be defensive here.
83 if (con_features != features) {
84 msg->clear_payload();
85 }
86 encode_message(msg, features & con_features, payload);
87 encode(con_features, payload);
88 encode(entity_name, payload);
89 return;
90 }
91 header.version = HEAD_VERSION;
92 header.compat_version = COMPAT_VERSION;
93 encode(tid, payload);
94 encode(client_type, payload, features);
95 encode(client_addrs, payload, features);
96 encode(client_socket_addr, payload, features);
97 encode(client_caps, payload, features);
7c673cae
FG
98 // Encode client message with intersection of target and source
99 // features. This could matter if the semantics of the encoded
100 // message are changed when reencoding with more features than the
101 // client had originally. That should never happen, but we may as
102 // well be defensive here.
103 if (con_features != features) {
104 msg->clear_payload();
105 }
106 encode_message(msg, features & con_features, payload);
11fdf7f2
TL
107 encode(con_features, payload);
108 encode(entity_name, payload);
7c673cae
FG
109 }
110
111 void decode_payload() override {
f67539c2 112 using ceph::decode;
11fdf7f2
TL
113 auto p = payload.cbegin();
114 decode(tid, p);
115 if (header.version < 4) {
116 entity_inst_t client;
117 decode(client, p);
118 client_type = client.name.type();
119 client_addrs = entity_addrvec_t(client.addr);
120 client_socket_addr = client.addr;
121 } else {
122 decode(client_type, p);
123 decode(client_addrs, p);
124 decode(client_socket_addr, p);
125 }
126 decode(client_caps, p);
7c673cae 127 msg = (PaxosServiceMessage *)decode_message(NULL, 0, p);
11fdf7f2
TL
128 decode(con_features, p);
129 decode(entity_name, p);
7c673cae
FG
130 }
131
132 PaxosServiceMessage *claim_message() {
133 // let whoever is claiming the message deal with putting it.
11fdf7f2 134 ceph_assert(msg);
7c673cae
FG
135 msg_desc = stringify(*msg);
136 PaxosServiceMessage *m = msg;
137 msg = NULL;
138 return m;
139 }
140
11fdf7f2 141 std::string_view get_type_name() const override { return "forward"; }
f67539c2 142 void print(std::ostream& o) const override {
7c673cae
FG
143 o << "forward(";
144 if (msg) {
145 o << *msg;
146 } else {
147 o << msg_desc;
148 }
149 o << " caps " << client_caps
150 << " tid " << tid
151 << " con_features " << con_features << ")";
152 }
9f95a23c
TL
153private:
154 template<class T, typename... Args>
155 friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
7c673cae
FG
156};
157
158#endif