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 class SocketConnection
;
29 using SocketConnectionRef
= seastar::shared_ptr
<SocketConnection
>;
31 #ifdef UNIT_TESTS_BUILT
38 * The interface class to implement Connection, called by SocketConnection.
40 * The operations must be done in get_shard_id().
42 class ConnectionHandler
{
44 using clock_t = seastar::lowres_system_clock
;
46 virtual ~ConnectionHandler() = default;
48 ConnectionHandler(const ConnectionHandler
&) = delete;
49 ConnectionHandler(ConnectionHandler
&&) = delete;
50 ConnectionHandler
&operator=(const ConnectionHandler
&) = delete;
51 ConnectionHandler
&operator=(ConnectionHandler
&&) = delete;
53 virtual seastar::shard_id
get_shard_id() const = 0;
55 virtual bool is_connected() const = 0;
57 virtual seastar::future
<> send(MessageFRef
) = 0;
59 virtual seastar::future
<> send_keepalive() = 0;
61 virtual clock_t::time_point
get_last_keepalive() const = 0;
63 virtual clock_t::time_point
get_last_keepalive_ack() const = 0;
65 virtual void set_last_keepalive_ack(clock_t::time_point
) = 0;
67 virtual void mark_down() = 0;
70 ConnectionHandler() = default;
73 class SocketConnection
: public Connection
{
75 * Connection interfaces, public to users
76 * Working in ConnectionHandler::get_shard_id()
79 SocketConnection(SocketMessenger
& messenger
,
80 ChainedDispatchers
& dispatchers
);
82 ~SocketConnection() override
;
84 const seastar::shard_id
get_shard_id() const override
{
85 return io_handler
->get_shard_id();
88 const entity_name_t
&get_peer_name() const override
{
92 const entity_addr_t
&get_peer_addr() const override
{
96 const entity_addr_t
&get_peer_socket_addr() const override
{
100 uint64_t get_features() const override
{
104 bool is_connected() const override
;
106 seastar::future
<> send(MessageURef msg
) override
;
108 seastar::future
<> send_keepalive() override
;
110 clock_t::time_point
get_last_keepalive() const override
;
112 clock_t::time_point
get_last_keepalive_ack() const override
;
114 void set_last_keepalive_ack(clock_t::time_point when
) override
;
116 void mark_down() override
;
118 bool has_user_private() const override
{
119 return user_private
!= nullptr;
122 user_private_t
&get_user_private() override
{
123 assert(has_user_private());
124 return *user_private
;
127 void set_user_private(std::unique_ptr
<user_private_t
> new_user_private
) override
{
128 assert(!has_user_private());
129 user_private
= std::move(new_user_private
);
132 void print(std::ostream
& out
) const override
;
135 * Public to SocketMessenger
136 * Working in SocketMessenger::get_shard_id();
139 /// start a handshake from the client's perspective,
140 /// only call when SocketConnection first construct
141 void start_connect(const entity_addr_t
& peer_addr
,
142 const entity_name_t
& peer_name
);
144 /// start a handshake from the server's perspective,
145 /// only call when SocketConnection first construct
146 void start_accept(SocketFRef
&& socket
,
147 const entity_addr_t
& peer_addr
);
149 seastar::future
<> close_clean_yielded();
151 seastar::socket_address
get_local_address() const;
153 seastar::shard_id
get_messenger_shard_id() const;
155 SocketMessenger
&get_messenger() const;
157 ConnectionRef
get_local_shared_foreign_from_this();
160 void set_peer_type(entity_type_t peer_type
);
162 void set_peer_id(int64_t peer_id
);
164 void set_peer_name(entity_name_t name
) {
165 set_peer_type(name
.type());
166 set_peer_id(name
.num());
169 void set_features(uint64_t f
);
171 void set_socket(Socket
*s
);
173 #ifdef UNIT_TESTS_BUILT
174 bool is_protocol_ready() const override
;
176 bool is_protocol_standby() const override
;
178 bool is_protocol_closed_clean() const override
;
180 bool is_protocol_closed() const override
;
182 // peer wins if myaddr > peeraddr
183 bool peer_wins() const override
;
185 Interceptor
*interceptor
= nullptr;
187 // peer wins if myaddr > peeraddr
188 bool peer_wins() const;
192 const seastar::shard_id msgr_sid
;
195 * Core owner is messenger core, may allow to access from the I/O core.
197 SocketMessenger
& messenger
;
199 std::unique_ptr
<ProtocolV2
> protocol
;
201 Socket
*socket
= nullptr;
203 entity_name_t peer_name
= {0, entity_name_t::NEW
};
205 entity_addr_t peer_addr
;
207 // which of the peer_addrs we're connecting to (as client)
208 // or should reconnect to (as peer)
209 entity_addr_t target_addr
;
211 uint64_t features
= 0;
213 ceph::net::Policy
<crimson::common::Throttle
> policy
;
215 uint64_t peer_global_id
= 0;
218 * Core owner is I/O core (mutable).
220 std::unique_ptr
<ConnectionHandler
> io_handler
;
223 * Core owner is up to the connection user.
225 std::unique_ptr
<user_private_t
> user_private
;
227 friend class IOHandler
;
228 friend class ProtocolV2
;
229 friend class FrameAssemblerV2
;
232 } // namespace crimson::net
234 #if FMT_VERSION >= 90000
235 template <> struct fmt::formatter
<crimson::net::SocketConnection
> : fmt::ostream_formatter
{};