1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2017 Red Hat, Inc
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.
17 #include <seastar/core/sharded.hh>
19 #include "msg/Policy.h"
20 #include "crimson/common/throttle.h"
21 #include "crimson/net/Connection.h"
22 #include "crimson/net/Socket.h"
24 namespace crimson::net
{
27 class SocketMessenger
;
28 using SocketConnectionRef
= seastar::shared_ptr
<SocketConnection
>;
30 #ifdef UNIT_TESTS_BUILT
37 * The interface class to implement Connection, called by SocketConnection.
39 class ConnectionHandler
{
41 using clock_t = seastar::lowres_system_clock
;
43 virtual ~ConnectionHandler() = default;
45 ConnectionHandler(const ConnectionHandler
&) = delete;
46 ConnectionHandler(ConnectionHandler
&&) = delete;
47 ConnectionHandler
&operator=(const ConnectionHandler
&) = delete;
48 ConnectionHandler
&operator=(ConnectionHandler
&&) = delete;
50 virtual bool is_connected() const = 0;
52 virtual seastar::future
<> send(MessageURef
) = 0;
54 virtual seastar::future
<> send_keepalive() = 0;
56 virtual clock_t::time_point
get_last_keepalive() const = 0;
58 virtual clock_t::time_point
get_last_keepalive_ack() const = 0;
60 virtual void set_last_keepalive_ack(clock_t::time_point
) = 0;
62 virtual void mark_down() = 0;
65 ConnectionHandler() = default;
68 class SocketConnection
: public Connection
{
69 const seastar::shard_id core
;
71 SocketMessenger
& messenger
;
73 std::unique_ptr
<ConnectionHandler
> io_handler
;
75 std::unique_ptr
<ProtocolV2
> protocol
;
79 entity_name_t peer_name
= {0, entity_name_t::NEW
};
81 entity_addr_t peer_addr
;
83 // which of the peer_addrs we're connecting to (as client)
84 // or should reconnect to (as peer)
85 entity_addr_t target_addr
;
87 uint64_t features
= 0;
89 ceph::net::Policy
<crimson::common::Throttle
> policy
;
91 uint64_t peer_global_id
= 0;
93 std::unique_ptr
<user_private_t
> user_private
;
95 // Connection interfaces, public to users
97 SocketConnection(SocketMessenger
& messenger
,
98 ChainedDispatchers
& dispatchers
);
100 ~SocketConnection() override
;
102 const entity_name_t
&get_peer_name() const override
{
106 const entity_addr_t
&get_peer_addr() const override
{
110 const entity_addr_t
&get_peer_socket_addr() const override
{
114 uint64_t get_features() const override
{
118 bool is_connected() const override
;
120 seastar::future
<> send(MessageURef msg
) override
;
122 seastar::future
<> send_keepalive() override
;
124 clock_t::time_point
get_last_keepalive() const override
;
126 clock_t::time_point
get_last_keepalive_ack() const override
;
128 void set_last_keepalive_ack(clock_t::time_point when
) override
;
130 void mark_down() override
;
132 bool has_user_private() const override
{
133 return user_private
!= nullptr;
136 user_private_t
&get_user_private() override
{
137 assert(has_user_private());
138 return *user_private
;
141 void set_user_private(std::unique_ptr
<user_private_t
> new_user_private
) override
{
142 assert(!has_user_private());
143 user_private
= std::move(new_user_private
);
146 void print(std::ostream
& out
) const override
;
148 // public to SocketMessenger
150 /// start a handshake from the client's perspective,
151 /// only call when SocketConnection first construct
152 void start_connect(const entity_addr_t
& peer_addr
,
153 const entity_name_t
& peer_name
);
155 /// start a handshake from the server's perspective,
156 /// only call when SocketConnection first construct
157 void start_accept(SocketRef
&& socket
,
158 const entity_addr_t
& peer_addr
);
160 seastar::future
<> close_clean_yielded();
162 seastar::socket_address
get_local_address() const;
164 SocketMessenger
&get_messenger() const {
168 ConnectionRef
get_local_shared_foreign_from_this();
171 seastar::shard_id
shard_id() const;
173 void set_peer_type(entity_type_t peer_type
) {
174 // it is not allowed to assign an unknown value when the current
176 assert(!(peer_type
== 0 &&
177 peer_name
.type() != 0));
178 // it is not allowed to assign a different known value when the
179 // current value is also known.
180 assert(!(peer_type
!= 0 &&
181 peer_name
.type() != 0 &&
182 peer_type
!= peer_name
.type()));
183 peer_name
._type
= peer_type
;
186 void set_peer_id(int64_t peer_id
) {
187 // it is not allowed to assign an unknown value when the current
189 assert(!(peer_id
== entity_name_t::NEW
&&
190 peer_name
.num() != entity_name_t::NEW
));
191 // it is not allowed to assign a different known value when the
192 // current value is also known.
193 assert(!(peer_id
!= entity_name_t::NEW
&&
194 peer_name
.num() != entity_name_t::NEW
&&
195 peer_id
!= peer_name
.num()));
196 peer_name
._num
= peer_id
;
199 void set_peer_name(entity_name_t name
) {
200 set_peer_type(name
.type());
201 set_peer_id(name
.num());
204 void set_features(uint64_t f
) {
208 #ifdef UNIT_TESTS_BUILT
209 bool is_closed_clean() const override
;
211 bool is_closed() const override
;
213 // peer wins if myaddr > peeraddr
214 bool peer_wins() const override
;
216 Interceptor
*interceptor
= nullptr;
218 // peer wins if myaddr > peeraddr
219 bool peer_wins() const;
222 friend class IOHandler
;
223 friend class ProtocolV2
;
224 friend class FrameAssemblerV2
;
227 } // namespace crimson::net
229 #if FMT_VERSION >= 90000
230 template <> struct fmt::formatter
<crimson::net::SocketConnection
> : fmt::ostream_formatter
{};