]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/src/net/native-stack-impl.hh
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / src / net / native-stack-impl.hh
CommitLineData
11fdf7f2
TL
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
20 */
21
22#pragma once
23
11fdf7f2
TL
24#include <seastar/net/stack.hh>
25#include <iostream>
9f95a23c 26#include <seastar/net/inet_address.hh>
11fdf7f2
TL
27
28namespace seastar {
29
30namespace net {
31
32using namespace seastar;
33
34template <typename Protocol>
35class native_server_socket_impl;
36
37template <typename Protocol>
38class native_connected_socket_impl;
39
40class native_network_stack;
41
42// native_server_socket_impl
43template <typename Protocol>
f67539c2 44class native_server_socket_impl : public server_socket_impl {
11fdf7f2
TL
45 typename Protocol::listener _listener;
46public:
47 native_server_socket_impl(Protocol& proto, uint16_t port, listen_options opt);
9f95a23c 48 virtual future<accept_result> accept() override;
11fdf7f2 49 virtual void abort_accept() override;
9f95a23c 50 virtual socket_address local_address() const override;
11fdf7f2
TL
51};
52
53template <typename Protocol>
54native_server_socket_impl<Protocol>::native_server_socket_impl(Protocol& proto, uint16_t port, listen_options opt)
55 : _listener(proto.listen(port)) {
56}
57
58template <typename Protocol>
9f95a23c 59future<accept_result>
11fdf7f2
TL
60native_server_socket_impl<Protocol>::accept() {
61 return _listener.accept().then([] (typename Protocol::connection conn) {
9f95a23c
TL
62 // Save "conn" contents before call below function
63 // "conn" is moved in 1st argument, and used in 2nd argument
64 // It causes trouble on Arm which passes arguments from left to right
65 auto ip = conn.foreign_ip().ip;
66 auto port = conn.foreign_port();
67 return make_ready_future<accept_result>(accept_result{
11fdf7f2 68 connected_socket(std::make_unique<native_connected_socket_impl<Protocol>>(make_lw_shared(std::move(conn)))),
9f95a23c 69 make_ipv4_address(ip, port)});
11fdf7f2
TL
70 });
71}
72
73template <typename Protocol>
74void
75native_server_socket_impl<Protocol>::abort_accept() {
76 _listener.abort_accept();
77}
78
9f95a23c
TL
79template <typename Protocol>
80socket_address native_server_socket_impl<Protocol>::local_address() const {
81 return socket_address(_listener.get_tcp().inet().inet().host_address(), _listener.port());
82}
83
11fdf7f2
TL
84// native_connected_socket_impl
85template <typename Protocol>
86class native_connected_socket_impl : public connected_socket_impl {
87 lw_shared_ptr<typename Protocol::connection> _conn;
88 class native_data_source_impl;
89 class native_data_sink_impl;
90public:
91 explicit native_connected_socket_impl(lw_shared_ptr<typename Protocol::connection> conn)
92 : _conn(std::move(conn)) {}
f67539c2 93 using connected_socket_impl::source;
11fdf7f2
TL
94 virtual data_source source() override;
95 virtual data_sink sink() override;
96 virtual void shutdown_input() override;
97 virtual void shutdown_output() override;
98 virtual void set_nodelay(bool nodelay) override;
99 virtual bool get_nodelay() const override;
100 void set_keepalive(bool keepalive) override;
101 bool get_keepalive() const override;
102 void set_keepalive_parameters(const keepalive_params&) override;
103 keepalive_params get_keepalive_parameters() const override;
f67539c2
TL
104 int get_sockopt(int level, int optname, void* data, size_t len) const override;
105 void set_sockopt(int level, int optname, const void* data, size_t len) override;
20effc67 106 socket_address local_address() const noexcept override;
1e59de90 107 virtual future<> wait_input_shutdown() override;
11fdf7f2
TL
108};
109
110template <typename Protocol>
111class native_socket_impl final : public socket_impl {
112 Protocol& _proto;
113 lw_shared_ptr<typename Protocol::connection> _conn;
114public:
115 explicit native_socket_impl(Protocol& proto)
116 : _proto(proto), _conn(nullptr) { }
117
118 virtual future<connected_socket> connect(socket_address sa, socket_address local, transport proto = transport::TCP) override {
119 //TODO: implement SCTP
120 assert(proto == transport::TCP);
121
122 // FIXME: local is ignored since native stack does not support multiple IPs yet
123 assert(sa.as_posix_sockaddr().sa_family == AF_INET);
124
125 _conn = make_lw_shared<typename Protocol::connection>(_proto.connect(sa));
126 return _conn->connected().then([conn = _conn]() mutable {
127 auto csi = std::make_unique<native_connected_socket_impl<Protocol>>(std::move(conn));
128 return make_ready_future<connected_socket>(connected_socket(std::move(csi)));
129 });
130 }
131
9f95a23c
TL
132 virtual void set_reuseaddr(bool reuseaddr) override {
133 // FIXME: implement
134 std::cerr << "Reuseaddr is not supported by native stack" << std::endl;
135 }
136
137 virtual bool get_reuseaddr() const override {
138 // FIXME: implement
139 return false;
140 }
141
11fdf7f2
TL
142 virtual void shutdown() override {
143 if (_conn) {
144 _conn->shutdown_connect();
145 }
146 }
147};
148
149template <typename Protocol>
150class native_connected_socket_impl<Protocol>::native_data_source_impl final
151 : public data_source_impl {
152 typedef typename Protocol::connection connection_type;
153 lw_shared_ptr<connection_type> _conn;
154 size_t _cur_frag = 0;
155 bool _eof = false;
156 packet _buf;
157public:
158 explicit native_data_source_impl(lw_shared_ptr<connection_type> conn)
159 : _conn(std::move(conn)) {}
160 virtual future<temporary_buffer<char>> get() override {
161 if (_eof) {
162 return make_ready_future<temporary_buffer<char>>(temporary_buffer<char>(0));
163 }
164 if (_cur_frag != _buf.nr_frags()) {
165 auto& f = _buf.fragments()[_cur_frag++];
166 return make_ready_future<temporary_buffer<char>>(
167 temporary_buffer<char>(f.base, f.size,
168 make_deleter(deleter(), [p = _buf.share()] () mutable {})));
169 }
170 return _conn->wait_for_data().then([this] {
171 _buf = _conn->read();
172 _cur_frag = 0;
173 _eof = !_buf.len();
174 return get();
175 });
176 }
177 future<> close() override {
178 _conn->close_write();
179 return make_ready_future<>();
180 }
181};
182
183template <typename Protocol>
184class native_connected_socket_impl<Protocol>::native_data_sink_impl final
185 : public data_sink_impl {
186 typedef typename Protocol::connection connection_type;
187 lw_shared_ptr<connection_type> _conn;
188public:
189 explicit native_data_sink_impl(lw_shared_ptr<connection_type> conn)
190 : _conn(std::move(conn)) {}
191 using data_sink_impl::put;
192 virtual future<> put(packet p) override {
193 return _conn->send(std::move(p));
194 }
195 virtual future<> close() override {
196 _conn->close_write();
197 return make_ready_future<>();
198 }
199};
200
201template <typename Protocol>
202data_source native_connected_socket_impl<Protocol>::source() {
203 return data_source(std::make_unique<native_data_source_impl>(_conn));
204}
205
206template <typename Protocol>
207data_sink native_connected_socket_impl<Protocol>::sink() {
208 return data_sink(std::make_unique<native_data_sink_impl>(_conn));
209}
210
211template <typename Protocol>
212void
213native_connected_socket_impl<Protocol>::shutdown_input() {
214 _conn->close_read();
215}
216
217template <typename Protocol>
218void
219native_connected_socket_impl<Protocol>::shutdown_output() {
220 _conn->close_write();
221}
222
223template <typename Protocol>
224void
225native_connected_socket_impl<Protocol>::set_nodelay(bool nodelay) {
226 // FIXME: implement
227}
228
229template <typename Protocol>
230bool
231native_connected_socket_impl<Protocol>::get_nodelay() const {
232 // FIXME: implement
233 return true;
234}
235
236template <typename Protocol>
237void native_connected_socket_impl<Protocol>::set_keepalive(bool keepalive) {
238 // FIXME: implement
239 std::cerr << "Keepalive is not supported by native stack" << std::endl;
240}
241template <typename Protocol>
242bool native_connected_socket_impl<Protocol>::get_keepalive() const {
243 // FIXME: implement
244 return false;
245}
246
247template <typename Protocol>
248void native_connected_socket_impl<Protocol>::set_keepalive_parameters(const keepalive_params&) {
249 // FIXME: implement
250 std::cerr << "Keepalive parameters are not supported by native stack" << std::endl;
251}
252
253template <typename Protocol>
254keepalive_params native_connected_socket_impl<Protocol>::get_keepalive_parameters() const {
255 // FIXME: implement
256 return tcp_keepalive_params {std::chrono::seconds(0), std::chrono::seconds(0), 0};
257}
258
f67539c2
TL
259template<typename Protocol>
260void native_connected_socket_impl<Protocol>::set_sockopt(int level, int optname, const void* data, size_t len) {
261 throw std::runtime_error("Setting custom socket options is not supported for native stack");
262}
263
264template<typename Protocol>
265int native_connected_socket_impl<Protocol>::get_sockopt(int level, int optname, void* data, size_t len) const {
266 throw std::runtime_error("Getting custom socket options is not supported for native stack");
267}
268
20effc67
TL
269template<typename Protocol>
270socket_address native_connected_socket_impl<Protocol>::local_address() const noexcept {
271 return {_conn->local_ip(), _conn->local_port()};
272}
273
1e59de90
TL
274template <typename Protocol>
275future<> native_connected_socket_impl<Protocol>::wait_input_shutdown() {
276 return _conn->wait_input_shutdown();
277}
278
11fdf7f2
TL
279}
280
281}