]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/net/SocketConnection.cc
57e5c12c1aed433e89df4c3d4b7c15348b226e08
[ceph.git] / ceph / src / crimson / net / SocketConnection.cc
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 #include "SocketConnection.h"
16
17 #include "ProtocolV2.h"
18 #include "SocketMessenger.h"
19
20 #ifdef UNIT_TESTS_BUILT
21 #include "Interceptor.h"
22 #endif
23
24 using std::ostream;
25 using crimson::common::local_conf;
26
27 namespace crimson::net {
28
29 SocketConnection::SocketConnection(SocketMessenger& messenger,
30 ChainedDispatchers& dispatchers)
31 : msgr_sid{messenger.get_shard_id()}, messenger(messenger)
32 {
33 auto ret = create_handlers(dispatchers, *this);
34 io_handler = std::move(ret.io_handler);
35 protocol = std::move(ret.protocol);
36 #ifdef UNIT_TESTS_BUILT
37 if (messenger.interceptor) {
38 interceptor = messenger.interceptor;
39 interceptor->register_conn(this->get_local_shared_foreign_from_this());
40 }
41 #endif
42 }
43
44 SocketConnection::~SocketConnection() {}
45
46 bool SocketConnection::is_connected() const
47 {
48 return io_handler->is_connected();
49 }
50
51 #ifdef UNIT_TESTS_BUILT
52 bool SocketConnection::is_protocol_ready() const
53 {
54 assert(seastar::this_shard_id() == msgr_sid);
55 return protocol->is_ready();
56 }
57
58 bool SocketConnection::is_protocol_standby() const {
59 assert(seastar::this_shard_id() == msgr_sid);
60 return protocol->is_standby();
61 }
62
63 bool SocketConnection::is_protocol_closed() const
64 {
65 assert(seastar::this_shard_id() == msgr_sid);
66 return protocol->is_closed();
67 }
68
69 bool SocketConnection::is_protocol_closed_clean() const
70 {
71 assert(seastar::this_shard_id() == msgr_sid);
72 return protocol->is_closed_clean();
73 }
74
75 #endif
76 bool SocketConnection::peer_wins() const
77 {
78 assert(seastar::this_shard_id() == msgr_sid);
79 return (messenger.get_myaddr() > peer_addr || policy.server);
80 }
81
82 seastar::future<> SocketConnection::send(MessageURef _msg)
83 {
84 // may be invoked from any core
85 MessageFRef msg = seastar::make_foreign(std::move(_msg));
86 return io_handler->send(std::move(msg));
87 }
88
89 seastar::future<> SocketConnection::send_keepalive()
90 {
91 // may be invoked from any core
92 return io_handler->send_keepalive();
93 }
94
95 SocketConnection::clock_t::time_point
96 SocketConnection::get_last_keepalive() const
97 {
98 return io_handler->get_last_keepalive();
99 }
100
101 SocketConnection::clock_t::time_point
102 SocketConnection::get_last_keepalive_ack() const
103 {
104 return io_handler->get_last_keepalive_ack();
105 }
106
107 void SocketConnection::set_last_keepalive_ack(clock_t::time_point when)
108 {
109 io_handler->set_last_keepalive_ack(when);
110 }
111
112 void SocketConnection::mark_down()
113 {
114 io_handler->mark_down();
115 }
116
117 void
118 SocketConnection::start_connect(const entity_addr_t& _peer_addr,
119 const entity_name_t& _peer_name)
120 {
121 assert(seastar::this_shard_id() == msgr_sid);
122 protocol->start_connect(_peer_addr, _peer_name);
123 }
124
125 void
126 SocketConnection::start_accept(SocketFRef&& sock,
127 const entity_addr_t& _peer_addr)
128 {
129 assert(seastar::this_shard_id() == msgr_sid);
130 protocol->start_accept(std::move(sock), _peer_addr);
131 }
132
133 seastar::future<>
134 SocketConnection::close_clean_yielded()
135 {
136 assert(seastar::this_shard_id() == msgr_sid);
137 return protocol->close_clean_yielded();
138 }
139
140 seastar::socket_address SocketConnection::get_local_address() const {
141 assert(seastar::this_shard_id() == msgr_sid);
142 return socket->get_local_address();
143 }
144
145 ConnectionRef
146 SocketConnection::get_local_shared_foreign_from_this()
147 {
148 assert(seastar::this_shard_id() == msgr_sid);
149 return make_local_shared_foreign(
150 seastar::make_foreign(shared_from_this()));
151 }
152
153 SocketMessenger &
154 SocketConnection::get_messenger() const
155 {
156 assert(seastar::this_shard_id() == msgr_sid);
157 return messenger;
158 }
159
160 seastar::shard_id
161 SocketConnection::get_messenger_shard_id() const
162 {
163 return msgr_sid;
164 }
165
166 void SocketConnection::set_peer_type(entity_type_t peer_type) {
167 assert(seastar::this_shard_id() == msgr_sid);
168 // it is not allowed to assign an unknown value when the current
169 // value is known
170 assert(!(peer_type == 0 &&
171 peer_name.type() != 0));
172 // it is not allowed to assign a different known value when the
173 // current value is also known.
174 assert(!(peer_type != 0 &&
175 peer_name.type() != 0 &&
176 peer_type != peer_name.type()));
177 peer_name._type = peer_type;
178 }
179
180 void SocketConnection::set_peer_id(int64_t peer_id) {
181 assert(seastar::this_shard_id() == msgr_sid);
182 // it is not allowed to assign an unknown value when the current
183 // value is known
184 assert(!(peer_id == entity_name_t::NEW &&
185 peer_name.num() != entity_name_t::NEW));
186 // it is not allowed to assign a different known value when the
187 // current value is also known.
188 assert(!(peer_id != entity_name_t::NEW &&
189 peer_name.num() != entity_name_t::NEW &&
190 peer_id != peer_name.num()));
191 peer_name._num = peer_id;
192 }
193
194 void SocketConnection::set_features(uint64_t f) {
195 assert(seastar::this_shard_id() == msgr_sid);
196 features = f;
197 }
198
199 void SocketConnection::set_socket(Socket *s) {
200 assert(seastar::this_shard_id() == msgr_sid);
201 socket = s;
202 }
203
204 void SocketConnection::print(ostream& out) const {
205 out << (void*)this << " ";
206 messenger.print(out);
207 if (seastar::this_shard_id() != msgr_sid) {
208 out << " >> " << get_peer_name() << " " << peer_addr;
209 } else if (!socket) {
210 out << " >> " << get_peer_name() << " " << peer_addr;
211 } else if (socket->get_side() == Socket::side_t::acceptor) {
212 out << " >> " << get_peer_name() << " " << peer_addr
213 << "@" << socket->get_ephemeral_port();
214 } else { // socket->get_side() == Socket::side_t::connector
215 out << "@" << socket->get_ephemeral_port()
216 << " >> " << get_peer_name() << " " << peer_addr;
217 }
218 }
219
220 } // namespace crimson::net