]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/src/net/native-stack-impl.hh
import 15.2.0 Octopus source
[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
24#include <seastar/core/reactor.hh>
25#include <seastar/net/stack.hh>
26#include <iostream>
9f95a23c 27#include <seastar/net/inet_address.hh>
11fdf7f2
TL
28
29namespace seastar {
30
31namespace net {
32
33using namespace seastar;
34
35template <typename Protocol>
36class native_server_socket_impl;
37
38template <typename Protocol>
39class native_connected_socket_impl;
40
41class native_network_stack;
42
43// native_server_socket_impl
44template <typename Protocol>
9f95a23c 45class native_server_socket_impl : public api_v2::server_socket_impl {
11fdf7f2
TL
46 typename Protocol::listener _listener;
47public:
48 native_server_socket_impl(Protocol& proto, uint16_t port, listen_options opt);
9f95a23c 49 virtual future<accept_result> accept() override;
11fdf7f2 50 virtual void abort_accept() override;
9f95a23c 51 virtual socket_address local_address() const override;
11fdf7f2
TL
52};
53
54template <typename Protocol>
55native_server_socket_impl<Protocol>::native_server_socket_impl(Protocol& proto, uint16_t port, listen_options opt)
56 : _listener(proto.listen(port)) {
57}
58
59template <typename Protocol>
9f95a23c 60future<accept_result>
11fdf7f2
TL
61native_server_socket_impl<Protocol>::accept() {
62 return _listener.accept().then([] (typename Protocol::connection conn) {
9f95a23c
TL
63 // Save "conn" contents before call below function
64 // "conn" is moved in 1st argument, and used in 2nd argument
65 // It causes trouble on Arm which passes arguments from left to right
66 auto ip = conn.foreign_ip().ip;
67 auto port = conn.foreign_port();
68 return make_ready_future<accept_result>(accept_result{
11fdf7f2 69 connected_socket(std::make_unique<native_connected_socket_impl<Protocol>>(make_lw_shared(std::move(conn)))),
9f95a23c 70 make_ipv4_address(ip, port)});
11fdf7f2
TL
71 });
72}
73
74template <typename Protocol>
75void
76native_server_socket_impl<Protocol>::abort_accept() {
77 _listener.abort_accept();
78}
79
9f95a23c
TL
80template <typename Protocol>
81socket_address native_server_socket_impl<Protocol>::local_address() const {
82 return socket_address(_listener.get_tcp().inet().inet().host_address(), _listener.port());
83}
84
11fdf7f2
TL
85// native_connected_socket_impl
86template <typename Protocol>
87class native_connected_socket_impl : public connected_socket_impl {
88 lw_shared_ptr<typename Protocol::connection> _conn;
89 class native_data_source_impl;
90 class native_data_sink_impl;
91public:
92 explicit native_connected_socket_impl(lw_shared_ptr<typename Protocol::connection> conn)
93 : _conn(std::move(conn)) {}
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;
104};
105
106template <typename Protocol>
107class native_socket_impl final : public socket_impl {
108 Protocol& _proto;
109 lw_shared_ptr<typename Protocol::connection> _conn;
110public:
111 explicit native_socket_impl(Protocol& proto)
112 : _proto(proto), _conn(nullptr) { }
113
114 virtual future<connected_socket> connect(socket_address sa, socket_address local, transport proto = transport::TCP) override {
115 //TODO: implement SCTP
116 assert(proto == transport::TCP);
117
118 // FIXME: local is ignored since native stack does not support multiple IPs yet
119 assert(sa.as_posix_sockaddr().sa_family == AF_INET);
120
121 _conn = make_lw_shared<typename Protocol::connection>(_proto.connect(sa));
122 return _conn->connected().then([conn = _conn]() mutable {
123 auto csi = std::make_unique<native_connected_socket_impl<Protocol>>(std::move(conn));
124 return make_ready_future<connected_socket>(connected_socket(std::move(csi)));
125 });
126 }
127
9f95a23c
TL
128 virtual void set_reuseaddr(bool reuseaddr) override {
129 // FIXME: implement
130 std::cerr << "Reuseaddr is not supported by native stack" << std::endl;
131 }
132
133 virtual bool get_reuseaddr() const override {
134 // FIXME: implement
135 return false;
136 }
137
11fdf7f2
TL
138 virtual void shutdown() override {
139 if (_conn) {
140 _conn->shutdown_connect();
141 }
142 }
143};
144
145template <typename Protocol>
146class native_connected_socket_impl<Protocol>::native_data_source_impl final
147 : public data_source_impl {
148 typedef typename Protocol::connection connection_type;
149 lw_shared_ptr<connection_type> _conn;
150 size_t _cur_frag = 0;
151 bool _eof = false;
152 packet _buf;
153public:
154 explicit native_data_source_impl(lw_shared_ptr<connection_type> conn)
155 : _conn(std::move(conn)) {}
156 virtual future<temporary_buffer<char>> get() override {
157 if (_eof) {
158 return make_ready_future<temporary_buffer<char>>(temporary_buffer<char>(0));
159 }
160 if (_cur_frag != _buf.nr_frags()) {
161 auto& f = _buf.fragments()[_cur_frag++];
162 return make_ready_future<temporary_buffer<char>>(
163 temporary_buffer<char>(f.base, f.size,
164 make_deleter(deleter(), [p = _buf.share()] () mutable {})));
165 }
166 return _conn->wait_for_data().then([this] {
167 _buf = _conn->read();
168 _cur_frag = 0;
169 _eof = !_buf.len();
170 return get();
171 });
172 }
173 future<> close() override {
174 _conn->close_write();
175 return make_ready_future<>();
176 }
177};
178
179template <typename Protocol>
180class native_connected_socket_impl<Protocol>::native_data_sink_impl final
181 : public data_sink_impl {
182 typedef typename Protocol::connection connection_type;
183 lw_shared_ptr<connection_type> _conn;
184public:
185 explicit native_data_sink_impl(lw_shared_ptr<connection_type> conn)
186 : _conn(std::move(conn)) {}
187 using data_sink_impl::put;
188 virtual future<> put(packet p) override {
189 return _conn->send(std::move(p));
190 }
191 virtual future<> close() override {
192 _conn->close_write();
193 return make_ready_future<>();
194 }
195};
196
197template <typename Protocol>
198data_source native_connected_socket_impl<Protocol>::source() {
199 return data_source(std::make_unique<native_data_source_impl>(_conn));
200}
201
202template <typename Protocol>
203data_sink native_connected_socket_impl<Protocol>::sink() {
204 return data_sink(std::make_unique<native_data_sink_impl>(_conn));
205}
206
207template <typename Protocol>
208void
209native_connected_socket_impl<Protocol>::shutdown_input() {
210 _conn->close_read();
211}
212
213template <typename Protocol>
214void
215native_connected_socket_impl<Protocol>::shutdown_output() {
216 _conn->close_write();
217}
218
219template <typename Protocol>
220void
221native_connected_socket_impl<Protocol>::set_nodelay(bool nodelay) {
222 // FIXME: implement
223}
224
225template <typename Protocol>
226bool
227native_connected_socket_impl<Protocol>::get_nodelay() const {
228 // FIXME: implement
229 return true;
230}
231
232template <typename Protocol>
233void native_connected_socket_impl<Protocol>::set_keepalive(bool keepalive) {
234 // FIXME: implement
235 std::cerr << "Keepalive is not supported by native stack" << std::endl;
236}
237template <typename Protocol>
238bool native_connected_socket_impl<Protocol>::get_keepalive() const {
239 // FIXME: implement
240 return false;
241}
242
243template <typename Protocol>
244void native_connected_socket_impl<Protocol>::set_keepalive_parameters(const keepalive_params&) {
245 // FIXME: implement
246 std::cerr << "Keepalive parameters are not supported by native stack" << std::endl;
247}
248
249template <typename Protocol>
250keepalive_params native_connected_socket_impl<Protocol>::get_keepalive_parameters() const {
251 // FIXME: implement
252 return tcp_keepalive_params {std::chrono::seconds(0), std::chrono::seconds(0), 0};
253}
254
255}
256
257}