1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
9 #include <seastar/core/future.hh>
10 #include <seastar/core/gate.hh>
11 #include <seastar/core/lowres_clock.hh>
12 #include <seastar/core/shared_ptr.hh>
13 #include <seastar/core/timer.hh>
15 #include "auth/AuthRegistry.h"
16 #include "auth/KeyRing.h"
17 #include "common/ceph_context.h"
19 #include "crimson/auth/AuthClient.h"
20 #include "crimson/auth/AuthServer.h"
21 #include "crimson/common/auth_handler.h"
22 #include "crimson/common/gated.h"
23 #include "crimson/net/Dispatcher.h"
24 #include "crimson/net/Fwd.h"
26 #include "mon/MonMap.h"
28 #include "mon/MonSub.h"
30 template<typename Message
> using Ref
= boost::intrusive_ptr
<Message
>;
31 namespace crimson::net
{
37 struct AuthAuthorizeHandler
;
40 struct MMonSubscribeAck
;
41 struct MMonGetVersionReply
;
43 struct MMonCommandAck
;
47 enum class log_flushing_t
;
49 namespace crimson::mon
{
53 class Client
: public crimson::net::Dispatcher
,
54 public crimson::auth::AuthClient
,
55 public crimson::auth::AuthServer
57 EntityName entity_name
;
59 const uint32_t want_keys
;
62 bool ready_to_send
= false;
63 seastar::shared_ptr
<Connection
> active_con
;
64 std::vector
<seastar::shared_ptr
<Connection
>> pending_conns
;
65 seastar::timer
<seastar::lowres_clock
> timer
;
67 crimson::net::Messenger
& msgr
;
69 LogClient
*log_client
;
70 bool more_log_pending
= false;
71 utime_t last_send_log
;
73 seastar::future
<> send_log(log_flushing_t flush_flag
);
74 seastar::future
<> wait_for_send_log();
77 using get_version_t
= seastar::future
<std::tuple
<version_t
, version_t
>>;
79 ceph_tid_t last_version_req_id
= 0;
80 std::map
<ceph_tid_t
, typename
get_version_t::promise_type
> version_reqs
;
82 ceph_tid_t last_mon_command_id
= 0;
83 using command_result_t
=
84 seastar::future
<std::tuple
<std::int32_t, std::string
, ceph::bufferlist
>>;
85 struct mon_command_t
{
86 MURef
<MMonCommand
> req
;
87 typename
command_result_t::promise_type result
;
88 mon_command_t(MURef
<MMonCommand
> req
);
90 std::vector
<mon_command_t
> mon_commands
;
95 Client(crimson::net::Messenger
&, crimson::common::AuthHandler
&);
98 seastar::future
<> start();
99 seastar::future
<> stop();
101 void set_log_client(LogClient
*clog
) {
105 const uuid_d
& get_fsid() const {
108 get_version_t
get_version(const std::string
& map
);
109 command_result_t
run_command(std::string
&& cmd
,
111 seastar::future
<> send_message(MessageURef
);
112 bool sub_want(const std::string
& what
, version_t start
, unsigned flags
);
113 void sub_got(const std::string
& what
, version_t have
);
114 void sub_unwant(const std::string
& what
);
115 bool sub_want_increment(const std::string
& what
, version_t start
, unsigned flags
);
116 seastar::future
<> renew_subs();
117 seastar::future
<> wait_for_config();
119 void print(std::ostream
&) const;
121 // AuthServer methods
122 std::pair
<std::vector
<uint32_t>, std::vector
<uint32_t>>
123 get_supported_auth_methods(int peer_type
) final
;
124 uint32_t pick_con_mode(int peer_type
,
125 uint32_t auth_method
,
126 const std::vector
<uint32_t>& preferred_modes
) final
;
127 AuthAuthorizeHandler
* get_auth_authorize_handler(int peer_type
,
128 int auth_method
) final
;
129 int handle_auth_request(crimson::net::Connection
&conn
,
130 AuthConnectionMeta
&auth_meta
,
132 uint32_t auth_method
,
133 const ceph::bufferlist
& payload
,
134 uint64_t *p_peer_global_id
,
135 ceph::bufferlist
*reply
) final
;
137 crimson::common::CephContext cct
; // for auth_registry
138 AuthRegistry auth_registry
;
139 crimson::common::AuthHandler
& auth_handler
;
141 // AuthClient methods
142 crimson::auth::AuthClient::auth_request_t
143 get_auth_request(crimson::net::Connection
&conn
,
144 AuthConnectionMeta
&auth_meta
) final
;
146 // Handle server's request to continue the handshake
147 ceph::bufferlist
handle_auth_reply_more(crimson::net::Connection
&conn
,
148 AuthConnectionMeta
&auth_meta
,
149 const bufferlist
& bl
) final
;
151 // Handle server's indication that authentication succeeded
152 int handle_auth_done(crimson::net::Connection
&conn
,
153 AuthConnectionMeta
&auth_meta
,
156 const bufferlist
& bl
) final
;
158 // Handle server's indication that the previous auth attempt failed
159 int handle_auth_bad_method(crimson::net::Connection
&conn
,
160 AuthConnectionMeta
&auth_meta
,
161 uint32_t old_auth_method
,
163 const std::vector
<uint32_t>& allowed_methods
,
164 const std::vector
<uint32_t>& allowed_modes
) final
;
169 std::optional
<seastar::future
<>> ms_dispatch(crimson::net::ConnectionRef conn
,
170 MessageRef m
) override
;
171 void ms_handle_reset(crimson::net::ConnectionRef conn
, bool is_replace
) override
;
173 seastar::future
<> handle_monmap(crimson::net::Connection
&conn
,
175 seastar::future
<> handle_auth_reply(crimson::net::Connection
&conn
,
177 seastar::future
<> handle_subscribe_ack(Ref
<MMonSubscribeAck
> m
);
178 seastar::future
<> handle_get_version_reply(Ref
<MMonGetVersionReply
> m
);
179 seastar::future
<> handle_mon_command_ack(Ref
<MMonCommandAck
> m
);
180 seastar::future
<> handle_log_ack(Ref
<MLogAck
> m
);
181 seastar::future
<> handle_config(Ref
<MConfig
> m
);
183 seastar::future
<> on_session_opened();
185 seastar::future
<> load_keyring();
186 seastar::future
<> authenticate();
188 bool is_hunting() const;
189 // @param rank, rank of the monitor to be connected, if it is less than 0,
190 // try to connect to all monitors in monmap, until one of them
192 // @return true if a connection to monitor is established
193 seastar::future
<bool> reopen_session(int rank
);
194 std::vector
<unsigned> get_random_mons(unsigned n
) const;
195 seastar::future
<> _add_conn(unsigned rank
, uint64_t global_id
);
196 void _finish_auth(const entity_addr_t
& peer
);
197 crimson::common::Gated gate
;
199 // messages that are waiting for the active_con to be available
200 struct pending_msg_t
{
201 pending_msg_t(MessageURef m
) : msg(std::move(m
)) {}
203 seastar::promise
<> pr
;
205 std::deque
<pending_msg_t
> pending_messages
;
206 std::optional
<seastar::promise
<>> config_updated
;
209 inline std::ostream
& operator<<(std::ostream
& out
, const Client
& client
) {
214 } // namespace crimson::mon
216 #if FMT_VERSION >= 90000
217 template <> struct fmt::formatter
<crimson::mon::Client
> : fmt::ostream_formatter
{};