]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/net/Connection.h
6af12692e78bce9dd44a2cb884552437d958d702
[ceph.git] / ceph / src / crimson / net / Connection.h
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) 2017 Red Hat, Inc
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 */
14
15 #pragma once
16
17 #include <queue>
18 #include <seastar/core/future.hh>
19 #include <seastar/core/shared_ptr.hh>
20
21 #include "Fwd.h"
22
23 namespace crimson::net {
24
25 #ifdef UNIT_TESTS_BUILT
26 class Interceptor;
27 #endif
28
29 using seq_num_t = uint64_t;
30
31 class Connection : public seastar::enable_shared_from_this<Connection> {
32 entity_name_t peer_name = {0, entity_name_t::NEW};
33
34 protected:
35 entity_addr_t peer_addr;
36
37 // which of the peer_addrs we're connecting to (as client)
38 // or should reconnect to (as peer)
39 entity_addr_t target_addr;
40
41 using clock_t = seastar::lowres_system_clock;
42 clock_t::time_point last_keepalive;
43 clock_t::time_point last_keepalive_ack;
44
45 void set_peer_type(entity_type_t peer_type) {
46 // it is not allowed to assign an unknown value when the current
47 // value is known
48 assert(!(peer_type == 0 &&
49 peer_name.type() != 0));
50 // it is not allowed to assign a different known value when the
51 // current value is also known.
52 assert(!(peer_type != 0 &&
53 peer_name.type() != 0 &&
54 peer_type != peer_name.type()));
55 peer_name._type = peer_type;
56 }
57 void set_peer_id(int64_t peer_id) {
58 // it is not allowed to assign an unknown value when the current
59 // value is known
60 assert(!(peer_id == entity_name_t::NEW &&
61 peer_name.num() != entity_name_t::NEW));
62 // it is not allowed to assign a different known value when the
63 // current value is also known.
64 assert(!(peer_id != entity_name_t::NEW &&
65 peer_name.num() != entity_name_t::NEW &&
66 peer_id != peer_name.num()));
67 peer_name._num = peer_id;
68 }
69 void set_peer_name(entity_name_t name) {
70 set_peer_type(name.type());
71 set_peer_id(name.num());
72 }
73
74 public:
75 uint64_t peer_global_id = 0;
76
77 protected:
78 uint64_t features = 0;
79
80 public:
81 void set_features(uint64_t new_features) {
82 features = new_features;
83 }
84 auto get_features() const {
85 return features;
86 }
87 bool has_feature(uint64_t f) const {
88 return features & f;
89 }
90
91 public:
92 Connection() {}
93 virtual ~Connection() {}
94
95 #ifdef UNIT_TESTS_BUILT
96 Interceptor *interceptor = nullptr;
97 #endif
98
99 virtual Messenger* get_messenger() const = 0;
100 const entity_addr_t& get_peer_addr() const { return peer_addr; }
101 const entity_addrvec_t get_peer_addrs() const {
102 return entity_addrvec_t(peer_addr);
103 }
104 const auto& get_peer_socket_addr() const {
105 return target_addr;
106 }
107 const entity_name_t& get_peer_name() const { return peer_name; }
108 entity_type_t get_peer_type() const { return peer_name.type(); }
109 int64_t get_peer_id() const { return peer_name.num(); }
110
111 bool peer_is_mon() const { return peer_name.is_mon(); }
112 bool peer_is_mgr() const { return peer_name.is_mgr(); }
113 bool peer_is_mds() const { return peer_name.is_mds(); }
114 bool peer_is_osd() const { return peer_name.is_osd(); }
115 bool peer_is_client() const { return peer_name.is_client(); }
116
117 /// true if the handshake has completed and no errors have been encountered
118 virtual bool is_connected() const = 0;
119
120 #ifdef UNIT_TESTS_BUILT
121 virtual bool is_closed() const = 0;
122
123 virtual bool is_closed_clean() const = 0;
124
125 virtual bool peer_wins() const = 0;
126 #endif
127
128 /// send a message over a connection that has completed its handshake
129 virtual seastar::future<> send(MessageRef msg) = 0;
130
131 /// send a keepalive message over a connection that has completed its
132 /// handshake
133 virtual seastar::future<> keepalive() = 0;
134
135 // close the connection and cancel any any pending futures from read/send,
136 // without dispatching any reset event
137 virtual void mark_down() = 0;
138
139 virtual void print(ostream& out) const = 0;
140
141 void set_last_keepalive(clock_t::time_point when) {
142 last_keepalive = when;
143 }
144 void set_last_keepalive_ack(clock_t::time_point when) {
145 last_keepalive_ack = when;
146 }
147 auto get_last_keepalive() const { return last_keepalive; }
148 auto get_last_keepalive_ack() const { return last_keepalive_ack; }
149
150 struct user_private_t {
151 virtual ~user_private_t() = default;
152 };
153 private:
154 unique_ptr<user_private_t> user_private;
155 public:
156 bool has_user_private() const {
157 return user_private != nullptr;
158 }
159 void set_user_private(unique_ptr<user_private_t> new_user_private) {
160 user_private = std::move(new_user_private);
161 }
162 user_private_t &get_user_private() {
163 ceph_assert(user_private);
164 return *user_private;
165 }
166 };
167
168 inline ostream& operator<<(ostream& out, const Connection& conn) {
169 out << "[";
170 conn.print(out);
171 out << "]";
172 return out;
173 }
174
175 } // namespace crimson::net