]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/src/net/native-stack-impl.hh
update source to Ceph Pacific 16.2.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;
11fdf7f2
TL
106};
107
108template <typename Protocol>
109class native_socket_impl final : public socket_impl {
110 Protocol& _proto;
111 lw_shared_ptr<typename Protocol::connection> _conn;
112public:
113 explicit native_socket_impl(Protocol& proto)
114 : _proto(proto), _conn(nullptr) { }
115
116 virtual future<connected_socket> connect(socket_address sa, socket_address local, transport proto = transport::TCP) override {
117 //TODO: implement SCTP
118 assert(proto == transport::TCP);
119
120 // FIXME: local is ignored since native stack does not support multiple IPs yet
121 assert(sa.as_posix_sockaddr().sa_family == AF_INET);
122
123 _conn = make_lw_shared<typename Protocol::connection>(_proto.connect(sa));
124 return _conn->connected().then([conn = _conn]() mutable {
125 auto csi = std::make_unique<native_connected_socket_impl<Protocol>>(std::move(conn));
126 return make_ready_future<connected_socket>(connected_socket(std::move(csi)));
127 });
128 }
129
9f95a23c
TL
130 virtual void set_reuseaddr(bool reuseaddr) override {
131 // FIXME: implement
132 std::cerr << "Reuseaddr is not supported by native stack" << std::endl;
133 }
134
135 virtual bool get_reuseaddr() const override {
136 // FIXME: implement
137 return false;
138 }
139
11fdf7f2
TL
140 virtual void shutdown() override {
141 if (_conn) {
142 _conn->shutdown_connect();
143 }
144 }
145};
146
147template <typename Protocol>
148class native_connected_socket_impl<Protocol>::native_data_source_impl final
149 : public data_source_impl {
150 typedef typename Protocol::connection connection_type;
151 lw_shared_ptr<connection_type> _conn;
152 size_t _cur_frag = 0;
153 bool _eof = false;
154 packet _buf;
155public:
156 explicit native_data_source_impl(lw_shared_ptr<connection_type> conn)
157 : _conn(std::move(conn)) {}
158 virtual future<temporary_buffer<char>> get() override {
159 if (_eof) {
160 return make_ready_future<temporary_buffer<char>>(temporary_buffer<char>(0));
161 }
162 if (_cur_frag != _buf.nr_frags()) {
163 auto& f = _buf.fragments()[_cur_frag++];
164 return make_ready_future<temporary_buffer<char>>(
165 temporary_buffer<char>(f.base, f.size,
166 make_deleter(deleter(), [p = _buf.share()] () mutable {})));
167 }
168 return _conn->wait_for_data().then([this] {
169 _buf = _conn->read();
170 _cur_frag = 0;
171 _eof = !_buf.len();
172 return get();
173 });
174 }
175 future<> close() override {
176 _conn->close_write();
177 return make_ready_future<>();
178 }
179};
180
181template <typename Protocol>
182class native_connected_socket_impl<Protocol>::native_data_sink_impl final
183 : public data_sink_impl {
184 typedef typename Protocol::connection connection_type;
185 lw_shared_ptr<connection_type> _conn;
186public:
187 explicit native_data_sink_impl(lw_shared_ptr<connection_type> conn)
188 : _conn(std::move(conn)) {}
189 using data_sink_impl::put;
190 virtual future<> put(packet p) override {
191 return _conn->send(std::move(p));
192 }
193 virtual future<> close() override {
194 _conn->close_write();
195 return make_ready_future<>();
196 }
197};
198
199template <typename Protocol>
200data_source native_connected_socket_impl<Protocol>::source() {
201 return data_source(std::make_unique<native_data_source_impl>(_conn));
202}
203
204template <typename Protocol>
205data_sink native_connected_socket_impl<Protocol>::sink() {
206 return data_sink(std::make_unique<native_data_sink_impl>(_conn));
207}
208
209template <typename Protocol>
210void
211native_connected_socket_impl<Protocol>::shutdown_input() {
212 _conn->close_read();
213}
214
215template <typename Protocol>
216void
217native_connected_socket_impl<Protocol>::shutdown_output() {
218 _conn->close_write();
219}
220
221template <typename Protocol>
222void
223native_connected_socket_impl<Protocol>::set_nodelay(bool nodelay) {
224 // FIXME: implement
225}
226
227template <typename Protocol>
228bool
229native_connected_socket_impl<Protocol>::get_nodelay() const {
230 // FIXME: implement
231 return true;
232}
233
234template <typename Protocol>
235void native_connected_socket_impl<Protocol>::set_keepalive(bool keepalive) {
236 // FIXME: implement
237 std::cerr << "Keepalive is not supported by native stack" << std::endl;
238}
239template <typename Protocol>
240bool native_connected_socket_impl<Protocol>::get_keepalive() const {
241 // FIXME: implement
242 return false;
243}
244
245template <typename Protocol>
246void native_connected_socket_impl<Protocol>::set_keepalive_parameters(const keepalive_params&) {
247 // FIXME: implement
248 std::cerr << "Keepalive parameters are not supported by native stack" << std::endl;
249}
250
251template <typename Protocol>
252keepalive_params native_connected_socket_impl<Protocol>::get_keepalive_parameters() const {
253 // FIXME: implement
254 return tcp_keepalive_params {std::chrono::seconds(0), std::chrono::seconds(0), 0};
255}
256
f67539c2
TL
257template<typename Protocol>
258void native_connected_socket_impl<Protocol>::set_sockopt(int level, int optname, const void* data, size_t len) {
259 throw std::runtime_error("Setting custom socket options is not supported for native stack");
260}
261
262template<typename Protocol>
263int native_connected_socket_impl<Protocol>::get_sockopt(int level, int optname, void* data, size_t len) const {
264 throw std::runtime_error("Getting custom socket options is not supported for native stack");
265}
266
11fdf7f2
TL
267}
268
269}